天天看點

服務注冊和發現-consulconsul

consul

consul的理論概念自行百度一下,此處不再叙述

1. consul的搭建

此處我們使用

docker

來搭建consul的叢集,至于docker不是很熟練的同學,自行惡補一下

1.1 docker拉取consul

拉取的指令很簡單

docker pull consul
           

預設下載下傳最新的consul鏡像檔案,下載下傳完成好之後我們開始啟動一個節點,作為叢集的一個節點,這裡我們搭建三個節點,最終組裝成一個叢集,因我這裡隻有一台機器,是以我們部署在一台機器上,分别采用三個端口,這樣就是三個節點,實際使用過程中,一般都是三台機器來搭建三個節點。

1.2 搭建第一個節點

執行的指令為:

docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul:1.2.2 agent -server -bootstrap-expect 2 -ui -bind=0.0.0.0 -client=0.0.0.0
           

至于裡面所使用的指令下面簡單介紹一下

–net=host docker參數, 使得docker容器越過了net namespace的隔離,免去手動指定端口映射的步驟
-server consul支援以server或client的模式運作, server是服務發現子產品的核心, client主要用于轉發請求
-advertise 将本機私有IP傳遞到consul
-retry-join 指定要加入的consul節點位址,失敗後會重試, 可多次指定不同的位址
-client 指定consul綁定在哪個client位址上,這個位址可提供HTTP、DNS、RPC等服務,預設是>127.0.0.1
-bind 綁定伺服器的ip位址;該位址用來在叢集内部的通訊,叢集内的所有節點到位址必須是可達的,>預設是0.0.0.0
allow_stale 設定為true則表明可從consul叢集的任一server節點擷取dns資訊, false則表明每次請求都會>經過consul的server leader
-bootstrap-expect 資料中心中預期的伺服器數。指定後,Consul将等待指定數量的伺服器可用,然後>啟動群集。允許自動選舉leader,但不能與傳統-bootstrap标志一起使用, 需要在server模式下運作。
-data-dir 資料存放的位置,用于持久化儲存叢集狀态
-node 群集中此節點的名稱,這在群集中必須是唯一的,預設情況下是節點的主機名。
-config-dir 指定配置檔案,當這個目錄下有 .json 結尾的檔案就會被加載,詳細可參考https://www.consul.io/docs/agent/options.html#configuration_files
-enable-script-checks 檢查服務是否處于活動狀态,類似開啟心跳
-datacenter 資料中心名稱
-ui 開啟ui界面
-join 指定ip, 加入到已有的叢集中
           

1.3 檢視第一個節點的位址

執行如下的指令我們來檢視第一個節點的位址,這個很重要,因為我們要給節點二和節點三綁定到節點一上。

docker inspect --format ‘{{ .NetworkSettings.IPAddress }}‘ consul1
           

1.4 搭建第二個節點

執行指令:

docker run --name consul3 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
           

1.5 搭建第三個節點

執行指令:

docker run --name consul3 -d -p 8502:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
           

搭建完成之後,我們檢視docker容器運作的情況,檢視運作狀态

服務注冊和發現-consulconsul

我們可以看到我們建立的consul叢集已經在運作中,我這裡是将防火牆關閉了,我們你是啟動的防火牆,要是通路我們需要做個防火牆開放端口,開放端口之後,并且重新開機防火牆。完了才可以執行下面的操作。

1.6 檢視叢集

通過浏覽器通路192.168.1.100:8500之後,如果能看到下面的界面,說明我們的叢集搭建完成了

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳

服務注冊和發現-consulconsul

繼續通路節點2 節點2我們的端口是8501

服務注冊和發現-consulconsul

通路節點3 端口是8502

服務注冊和發現-consulconsul

至此我們consul的叢集算是搭建完畢了。那我們如何使用它呢?

2. 調用consul

2.1 建立一個服務提供者

建立一個項目名稱叫consul-provider,引入如下圖所示的

服務注冊和發現-consulconsul

2.2 修改服務提供者配置檔案

我們在建立的服務提供者的配置檔案中加入如下配置:

spring.application.name=consul-provider
server.port=3000
spring.cloud.consul.host=192.168.1.100
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.service-name=consul-provider
           
注意:

spring.cloud.consul.host

中配置的是我們consul的位址,

spring.cloud.consul.port

中配置的是我們consul的端口,此處我們隻配置三個節點中的任意一個,我們我們建立的三個節點,本身是帶有複制功能,是以随便配置一個,其他兩個都能擷取到這個服務提供者。這裡和zk的用法不太一樣。

2.3 服務提供者業務

為了示範我們給服務提供者叢集部署,測試一下負載均衡。

我們建立一個controller,内容如下:

服務注冊和發現-consulconsul

完了我們開啟注冊服務,在啟動類上加上注解

@EnableDiscoveryClient

服務注冊和發現-consulconsul

完成以上配置之後,我們需要打包,完了叢集部署。

2.4 叢集部署服務提供者

右擊服務提供者的target,選擇open in terminal

服務注冊和發現-consulconsul

之後執行指令

java -jar consul-provider-0.0.1-SNAPSHOT.jar --server.port=3001
           

再次右擊服務提供者的target,選擇open in terminal,執行指令

java -jar consul-provider-0.0.1-SNAPSHOT.jar --server.port=3002
           
服務注冊和發現-consulconsul

我們通路consul,檢視服務注冊情況。

我們先通路節點1,檢視運作情況。

服務注冊和發現-consulconsul

再通路節點2

服務注冊和發現-consulconsul

最後通路節點3

服務注冊和發現-consulconsul

我們可以看出來 我們注冊的時候配置檔案的位址隻寫了一個節點的位址,但是我們同樣可以看到節點2和節點3的運作情況,完全和節點1一樣。

2.5 建立服務消費者

和建立服務提供者是一樣的。引入這三個jar包

服務注冊和發現-consulconsul

2.6 修改服務消費者的配置檔案

這裡修改的配置檔案和服務提供者的一樣,如下圖所示:

spring.application.name=consul-consumer
server.port=3100
spring.cloud.consul.host=192.168.1.100
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.service-name=consul-consumer
           

2.7 修改服務消費者的啟動類

因為我們這裡需要調用服務提供者,是以我們需要建立一個

restTemplate

@SpringBootApplication
@EnableDiscoveryClient 
public class ConsulConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsulConsumerApplication.class, args);
    }

    @Bean
//    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

}
           
注意:這裡的restTemplate可以采用輪詢,也可以不用再這裡設定輪詢,我們再具體代碼調用的地方再設定

2.8 服務消費者的業務編寫

建立一個controller,編寫一個簡單的參數接受并傳回的方法。

@RestController
public class ConsulConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("/consulconsumer")
    public String hello(){
        ServiceInstance choose = loadBalancerClient.choose("consul-provider");
        URI uri = choose.getUri();
        String forObject = restTemplate.getForObject(uri + "/consulprovider?name={1}", String.class,"muyan");
        return forObject;
    }
}
           

上面就是就是再controller中采用的輪詢方式,如果我們在啟動類的RestTemplate中加上@LoadBalanced,那麼此處的代碼應該是:

@RestController
public class ConsulConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @GetMapping("/consulconsumer")
    public String hello(){
//        ServiceInstance choose = loadBalancerClient.choose("consul-provider");
//        URI uri = choose.getUri();
        String forObject = restTemplate.getForObject("http://consul-provider/consulprovider?name={1}", String.class, "mumu");
//        String forObject = restTemplate.getForObject(uri + "/consulprovider?name={1}", String.class,"muyan");
        return forObject;
    }
}
           
切記,千萬不要在啟動類上加上了@LoadBalanced注解之後,再在controller中采用LoadBalancerClient的choose方式來調用遠端服務,因為serverid必須是我們通路的服務名稱 ,當我們直接輸入ip的時候擷取的server是null,就會抛出異常。

2.9 測試

啟動服務消費者。我們通過浏覽器來調用consulconsumer方法。

服務注冊和發現-consulconsul

可以看到調用的3001端口的服務提供者,我們再重新整理

服務注冊和發現-consulconsul

我們可以看到出現的調用時3002的端口服務提供者。