SpringCloud集成Consul註冊中心

原文連接linux

Spring Cloud 支持不少服務發現的軟件,Eureka 只是其中之一,下面是 Spring Cloud 支持的服務發現軟件以及特性對比: git

輸入圖片說明
FA26E544-309C-4D8C-9317-45F2F3C790A6.png

Consul 介紹

  • Consul 是 HashiCorp 公司推出的開源工具,用於實現分佈式系統的服務發現與配置。與其餘分佈式服務註冊與發現的方案,Consul 的方案更「一站式」,內置了服務註冊與發現框 架、分佈一致性協議實現、健康檢查、Key/Value 存儲、多數據中心方案,再也不須要依賴其餘工具(好比 ZooKeeper 等)。使用起來也較 爲簡單。Consul 使用 Go 語言編寫,所以具備自然可移植性(支持Linux、windows和Mac OS X);安裝包僅包含一個可執行文件,方便部署,與 Docker 等輕量級容器可無縫配合。

Consul 的優點:

  • 使用 Raft 算法來保證一致性, 比複雜的 Paxos 算法更直接. 相比較而言, zookeeper 採用的是 Paxos, 而 etcd 使用的則是 Raft。
  • 支持多數據中心,內外網的服務採用不一樣的端口進行監聽。 多數據中心集羣能夠避免單數據中心的單點故障,而其部署則須要考慮網絡延遲, 分片等狀況等。 zookeeper 和 etcd 均不提供多數據中心功能的支持。
  • 支持健康檢查。 etcd 不提供此功能。
  • 支持 http 和 dns 協議接口。 zookeeper 的集成較爲複雜, etcd 只支持 http 協議。
  • 官方提供 web 管理界面, etcd 無此功能。
  • 綜合比較, Consul 做爲服務註冊和配置管理的新星, 比較值得關注和研究。

特性

  • 服務發現
  • 健康檢查
  • Key/Value 存儲
  • 多數據中心

Consul 角色

  • client: 客戶端, 無狀態, 將 HTTP 和 DNS 接口請求轉發給局域網內的服務端集羣。
  • server: 服務端, 保存配置信息, 高可用集羣, 在局域網內與本地客戶端通信, 經過廣域網與其餘數據中心通信。 每一個數據中心的 server 數量推薦爲 3 個或是 5 個。

Consul 安裝

Consul 不一樣於 Eureka 須要單獨安裝,訪問Consul 官網下載 Consul 的最新版本,github

我這裏以 Windows 爲例,下載下來是一個 consul_1.2.1_windows_amd64.zip 的壓縮包,解壓是是一個 consul.exe 的執行文件。 web

輸入圖片說明
64517552831A48A88E3B1906BC501705.png

cd 到對應的目錄下,使用 cmd 啓動 Consul算法

cd D:\Common Files\consul

#cmd啓動:
consul agent -dev        # -dev表示開發模式運行,另外還有-server表示服務模式運行
複製代碼

爲了方便期間,能夠在同級目錄下建立一個 run.bat 腳原本啓動,腳本內容以下spring

consul agent -dev
複製代碼

啓動結果以下: apache

輸入圖片說明
F2A8ABD028D8428D875EE8806BDA0CF7.png

啓動成功以後訪問:http://localhost:8500,能夠看到 Consul 的管理界面 windows

輸入圖片說明
F74DE8E446464BC1A3AE58534A7AB8D8.png

這樣就意味着咱們的 Consul 服務啓動成功了。瀏覽器

Linux環境安裝

把下載的linux下的安裝包consul拷貝到linux環境裏面,使用unzip進行解壓:bash

2,配置環境變量

vi /etc/profile

export JAVA_HOME=/usr/local/jdk1.8.0_172
export MAVEN_HOME=/usr/local/apache-maven-3.5.4
export CONSUL_HOME=/usr/local/consul
 
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$CONSUL_HOME:$PATH

#上面的CONSUL_HOME就是consul的路徑,上面的配置僅供參考。
source /etc/profile #命令使配置生效

#查看安裝的consul版本
[root@CentOS124 /]# consul -v
Consul v1.2.2
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
[root@CentOS124 /]# 
複製代碼

Consul 服務端

建立一個 spring-cloud-consul-producer 項目 依賴包以下:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
複製代碼
  • spring-boot-starter-actuator 健康檢查依賴於此包。
  • spring-cloud-starter-consul-discovery Spring Cloud Consul 的支持。

配置文件內容以下

spring.application.name=spring-cloud-consul-producer
server.port=8501
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
#註冊到consul的服務名稱
spring.cloud.consul.discovery.serviceName=service-producer
複製代碼
  • Consul 的地址和端口號默認是 localhost:8500 ,若是不是這個地址能夠自行配置。
  • spring.cloud.consul.discovery.serviceName 是指註冊到 Consul 的服務名稱,後期客戶端會根據這個名稱來進行服務調用。

啓動類

@SpringBootApplication
@EnableDiscoveryClient
public class ConsulProducerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsulProducerApplication.class, args);
    }
}
複製代碼

添加了 @EnableDiscoveryClient 註解表示支持服務發現。

建立一個 Controller,推文提供 hello 的服務

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "helle consul";
    }
}
複製代碼

爲了模擬註冊均衡負載複製一份上面的項目重命名爲 spring-cloud-consul-producer-2 ,修改對應的端口爲 8502,修改 hello 方法的返回值爲:"helle consul two",修改完成後依次啓動兩個項目。

這時候咱們再次在瀏覽器訪問地址:http://localhost:8500 就會顯示出來兩個服務提供者

Consul 消費端

建立一個 spring-cloud-consul-consumer 項目,pom 文件和上面示例保持一致

配置文件內容以下

spring.application.name=spring-cloud-consul-consumer
server.port=8503
spring.cloud.consul.host=127.0.0.1
spring.cloud.consul.port=8500
#設置不須要註冊到 consul 中
spring.cloud.consul.discovery.register=false
複製代碼

客戶端能夠設置註冊到 Consul 中,也能夠不註冊到 Consul 註冊中心中,根據咱們的業務來選擇,只須要在使用服務時經過 Consul 對外提供的接口獲取服務信息便可。

啓動類

@SpringBootApplication
public class ConsulConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsulConsumerApplication.class, args);
    }
}
複製代碼

進行測試

建立一個 ServiceController ,試試若是去獲取 Consul 中的服務

@RestController
public class ServiceController {
    @Autowired
    private LoadBalancerClient loadBalancer;
    @Autowired
    private DiscoveryClient discoveryClient;
     //獲取全部服務
    @RequestMapping("/services")
    public Object services() {
        return discoveryClient.getInstances("service-producer");
    }
    //從全部服務中選擇一個服務(輪詢)
    @RequestMapping("/discover")
    public Object discover() {
     return loadBalancer.choose("service-producer").getUri().toString();
    }
}
複製代碼

Controller 中有倆個方法,一個是獲取全部服務名爲service-producer的服務信息並返回到頁面,一個是隨機從服務名爲service-producer的服務中獲取一個並返回到頁面。

添加完 ServiceController 以後咱們啓動項目,訪問地址:http://localhost:8503/services,返回jsn數據

[{"serviceId":"service-producer","host":"windows10.microdone.cn","port":8501,"secure":false,"metadata":{"secure":"false"},"uri":"http://windows10.microdone.cn:8501","scheme":null},{"serviceId":"service-producer","host":"windows10.microdone.cn","port":8502,"secure":false,"metadata":{"secure":"false"},"uri":"http://windows10.microdone.cn:8502","scheme":null}]
複製代碼

發現咱們剛纔建立的端口爲 8501 和 8502 的兩個服務端都存在

屢次訪問地址:http://localhost:8503/discover,頁面會交替返回信息:

說明 8501 和 8501 的兩個服務會交替出現,從而實現了獲取服務端地址的均衡負載。

大多數狀況下咱們但願使用均衡負載的形式去獲取服務端提供的服務,所以使用第二種方法來模擬調用服務端提供的 hello 方法。

建立 CallHelloController :

@RestController
public class CallHelloController {
    @Autowired
    private LoadBalancerClient loadBalancer;
    @RequestMapping("/call")
    public String call() {
        ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
        System.out.println("服務地址:" + serviceInstance.getUri());
        System.out.println("服務名稱:" + serviceInstance.getServiceId());
        String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
        System.out.println(callServiceResult);
        return callServiceResult;
    }
}
複製代碼

使用 RestTemplate 進行遠程調用。添加完以後重啓 spring-cloud-consul-consumer 項目。在瀏覽器中訪問地址:http://localhost:8503/call,依次返回結果以下:

helle consul

helle consul two
複製代碼

說明咱們已經成功的調用了 Consul 服務端提供的服務,而且實現了服務端的均衡負載功能

示例代碼:github.com/ityouknow/s…

相關文章
相關標籤/搜索