spring-cloud-consul 服務注冊發現與配置


下面是 Spring Cloud 支持的服務發現軟件以及特性對比(Eureka 已停止更新,取而代之的是 Consul):

Feature euerka Consul zookeeper etcd
服務健康檢查 可配支持 服務狀態,內存,硬盤等 (弱)長連接,keepalive 連接心跳
多數據中心 支持
kv 存儲服務 支持 支持 支持
一致性 raft paxos raft
cap ap ca cp cp
使用接口(多語言能力) http(sidecar) 支持 http 和 dns 客戶端 http/grpc
watch 支持 支持 long polling/大部分增量 全量/支持long polling 支持 支持 long polling
自身監控 metrics metrics metrics
安全 acl /https acl https 支持(弱)
spring cloud 集成 已支持 已支持 已支持 已支持

 

 

 

 

 

 

 

 

 

 

 

 

 

 

什么是Consul:

  Consul是HashiCorp公司推出的開源軟件,使用GO語言編寫,提供了分布式系統的服務注冊和發現、配置等功能,這些功能中的每一個都可以根據需要單獨使用,也可以一起使用以構建全方位的服務網格。Consul不僅具有服務治理的功能,而且使用分布式一致協議RAFT算法實現,有多數據中心的高可用方案,並且很容易和Spring Cloud等微服務框架集成,使用起來非常的簡單,具有簡單、易用、可插排等特點。使用簡而言之,Consul提供了一種完整的服務網格解決方案 。

Consul具有以下的特點和功能:

  • 服務發現:Consul的客戶端可以向Consul注冊服務,例如api服務或者mysql服務,其他客戶端可以使用Consul來發現服務的提供者。Consul支持使用DNS或HTTP來注冊和發現服務。

  • 運行時健康檢查:Consul客戶端可以提供任意數量的運行狀況檢查機制,這些檢查機制可以是給定服務(“是Web服務器返回200 OK”)或本地節點(“內存利用率低於90%”)相關聯。這些信息可以用來監控群集的運行狀況,服務發現組件可以使用這些監控信息來路由流量,可以使流量遠離不健康的服務。

  • KV存儲:應用程序可以將Consul的鍵/值存儲用於任何需求,包括動態配置,功能標記,協調,領導者選舉等。它采用HTTP API使其易於使用。

  • 安全服務通信:Consul可以為服務生成和分發TLS證書,以建立相互的TLS連接。

  • 多數據中心:Consul支持多個數據中心。這意味着Consul的用戶不必擔心構建額外的抽象層以擴展到多個區域。

Consul原理:

  每個提供服務的節點都運行了Consul的代理,運行代理不需要服務發現和獲取配置的KV鍵值對,代理只負責監控檢查。代理節點可以和一個或者多個Consul server通訊。 Consul服務器是存儲和復制數據的地方。服務器本身選出了領導者。雖然Consul可以在一台服務器上運行,但建議使用3到5,以避免導致數據丟失的故障情況。建議為每個數據中心使用一組Consul服務器。

  如果你的組件需要發現服務,可以查詢任何Consul Server或任何Consul客戶端,Consul客戶端會自動將查詢轉發給Consul Server。需要發現其他服務或節點的基礎架構組件可以查詢任何Consul服務器或任何Consul代理。代理會自動將查詢轉發給服務器。每個數據中心都運行Consul服務器集群。發生跨數據中心服務發現或配置請求時,本地Consul服務器會將請求轉發到遠程數據中心並返回結果。

Consul 服務注冊發現流程:

Consul在業界最廣泛的用途就是作為服務注冊中心,同Eureka類型,consul作為服務注冊中心,它的注冊和發現過程如下圖:

  1. 當 Producer 啟動的時候,會向 Consul 發送一個 post 請求,告訴 Consul 自己的 IP 和 Port
  2. Consul 接收到 Producer 的注冊后,每隔10s(默認)會向 Producer 發送一個健康檢查的請求,檢驗Producer是否健康
  3. 當 Consumer 發送 GET 方式請求 /api/address 到 Producer 時,會先從 Consul 中拿到一個存儲服務 IP 和 Port 的臨時表,從表中拿到 Producer 的 IP 和 Port 后再發送 GET 方式請求 /api/address
  4. 該臨時表每隔10s會更新,只包含有通過了健康檢查的 Producer

Consul (CA)VS Eureka (AP):

  Eureka是一種服務發現工具。 該體系結構主要是客戶端/服務器,每個數據中心有一組Eureka服務器,通常每個可用區域一個。 通常,Eureka的客戶使用嵌入式SDK來注冊和發現服務。 對於非本地集成的客戶端,使用Ribbon等邊車通過Eureka透明地發現服務。Eureka使用盡力而為的復制提供弱一致的服務視圖。 當客戶端向服務器注冊時,該服務器將嘗試復制到其他服務器但不提供保證。 服務注冊的生存時間很短(TTL),要求客戶端對服務器進行心跳檢測。 不健康的服務或節點將停止心跳,導致它們超時並從注冊表中刪除。 發現請求可以路由到任何服務,由於盡力復制,這些服務可以提供過時或丟失的數據。 這種簡化的模型允許輕松的集群管理和高可擴展性。

  Consul提供了一系列超級功能,包括更豐富的運行狀況檢查,鍵/值存儲和多數據中心感知。 Consul需要每個數據中心中的一組服務器,以及每個客戶端上的代理,類似於使用像Ribbon這樣的邊車。 Consul代理允許大多數應用程序不知道Consul,通過配置文件執行服務注冊以及通過DNS或負載平衡器sidecars進行發現。

  Consul提供強大的一致性保證,因為服務器使用Raft協議復制狀態。 Consul支持豐富的運行狀況檢查,包括TCP,HTTP,Nagios / Sensu兼容腳本或基於的Eureka的TTL。 客戶端節點參與基於gossip的健康檢查,該檢查分發健康檢查的工作,而不像集中式心跳,這成為可擴展性挑戰。 發現請求被路由到當選的Consul領導者,這使他們默認情況下非常一致。 允許過時讀取的客戶端允許任何服務器處理其請求,從而允許像Eureka一樣的線性可伸縮性。

  Consul的強烈一致性意味着它可以用作領導者選舉和集群協調的鎖定服務。 Eureka不提供類似的保證,並且通常需要為需要執行協調或具有更強一致性需求的服務運行ZooKeeper。

  Consul提供了支持面向服務的體系結構所需的功能工具包。 這包括服務發現,還包括豐富的運行狀況檢查,鎖定,鍵/值,多數據中心聯合,事件系統和ACL。 Consul和consul-template和envconsul等工具生態系統都試圖最大限度地減少集成所需的應用程序更改,以避免需要通過SDK進行本機集成

  Eureka是更大的Netflix OSS套件的一部分,該套件期望應用程序相對同質且緊密集成。 因此,Eureka只解決了有限的一部分問題,期望其他工具如ZooKeeper可以同時使用。

  Eureka Server端采用的是P2P的復制模式,但是它不保證復制操作一定能成功,因此它提供的是一個最終一致性的服務實例視圖;Client端在Server端的注冊信息有一個帶期限的租約,一旦Server端在指定期間沒有收到Client端發送的心跳,則Server端會認定為Client端注冊的服務是不健康的,定時任務將會將其從注冊表中刪除。Consul與Eureka不同,Consul采用Raft算法,可以提供強一致性的保證,Consul的agent相當於Netflix Ribbon + Netflix Eureka Client,而且對應用來說相對透明,同時相對於Eureka這種集中式的心跳檢測機制,Consul的agent可以參與到基於goosip協議的健康檢查,分散了server端的心跳檢測壓力。除此之外,Consul為多數據中心提供了開箱即用的原生支持等。

Consul 安裝:

  下載地址:https://www.consul.io/downloads.html

  我這里以 Windows 為例,下載下來是一個 consul_1.7.2_windows_amd64.zip 的壓縮包,解壓是是一個 consul.exe 的執行文件.

  需要再環境變量 path 里配置 consul.exe 的執行文件的路徑

  然后查看版本信息:consul --version 

  consul的一些常見的執行命令如下:

命令 解釋 示例
agent 運行一個consul agent consul agent -dev
join 將agent加入到consul集群 consul join IP
members 列出consul cluster集群中的members consul members
leave 將節點移除所在集群 consul leave

 

 

 

 

 

 

 

更多命令請查看官方網站:https://www.consul.io/docs/commands/index.html

  使用 開發模式啟動:consul agent -dev  ,然后訪問 http://localhost:8500/ 

使用spring cloud consul來服務注冊與發現:

  先來看服務的提供方:

1.創建一個標准的springboot項目,添加以下依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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-actuator</artifactId>
        </dependency>
    </dependencies>

2.添加配置文件 application.properties 

spring:
  application:
    name: consul-server-hello
  cloud:
    consul:
      port: 8500 # consul代理端口
      host: localhost # consul代理ip
      enabled: true #啟用 spring cloud consul
      discovery:
        # 配置服務注冊到Consul上
        register: true # 是否開啟在 consul 中注冊服務
        health-check-path: /actuator/health   #定義 consul 健康檢查路徑
        health-check-interval: 10s # consul 健康檢查頻率
        instance-id: ${spring.application.name}:${server.port} # 配置注冊到consul 服務的id
        enabled: true #啟用 consul 服務發現
        service-name: ${spring.application.name} #設置 注冊到 consul 的服務名稱
        ip-address: localhost # 訪問服務時使用的 ip地址 (還必須設置preferIpAddress才能使用)
        prefer-ip-address: true
server:
port: 8081

3.啟動類:

@SpringBootApplication
@EnableDiscoveryClient
public class ConsulServerApp {

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

4.提供一個接口:

@RestController
public class TestController {

    @GetMapping("/hello")
    public String home() {
        return "hi ,i am from Consul:";
    }
}

5.然后啟動該服務,打開consul控制台會發現服務已經注冊上去了。

  服務消費者的搭建過程同服務提供者,在pom文件中引入的依賴同服務提供者,在配置文件application.yml配置同服務提供者,不同的點在端口為8655,服務名為consul-ribbon。

1.這里采用 ribbon 客戶端,添加以下依賴,如果使用 feign 按照之前的配置即可,導入相應依賴。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

2.提供個 rest 接口用域調用測試:

@RestController
public class RibbonController {
//需要配置該服務在condul里注冊的名字
    private static final String REST_URL_PREFIX = "http://consul-server-hello";

    @Autowired
    private RestTemplate restTemplate;


    @RequestMapping(value = "/consulHello")
    public String find() throws ExecutionException, InterruptedException {

        return restTemplate.getForObject(REST_URL_PREFIX + "/hello", String.class);
    }
}

3.主啟動類:

@SpringBootApplication
@EnableDiscoveryClient
public class ConsulRibbonApp {

    public static void main(String[] args) {
        SpringApplication.run(ConsulRibbonApp.class, args);
    }
    @Bean
    @LoadBalanced // ribbon是客戶端 的負載均衡工具
    //默認算法是輪詢算法 核心組件IRule
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

4.啟動該項目,注冊完成如下圖:

5.測試調用 http://localhost:8655/consulHello 可以看到返回信息。這樣就完成最基本的服務調用。

使用Spring Cloud Consul Config來做服務配置中心:

  Consul不僅能用來服務注冊和發現,Consul而且支持Key/Value鍵值對的存儲,可以用來做配置中心。Spring Cloud 提供了Spring Cloud Consul Config依賴去和Consul相集成,用來做配置中心。現在以案例的形式來講解如何使用Consul作為配置中心,本案例在上一個案例的consul-server-hello基礎上進行改造。首先在工程的pom文件加上consul-config的起步依賴,代碼如下:

1. pom 添加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>

2.這里需要修改配置文件了,由於application有不同的環境文件類型,比如 dev、test。我們這里先添加 boostrap.yml

spring: application: name: consul-server-hello cloud: consul: port: 8500 # consul代理端口 host: localhost # consul代理ip enabled: true #啟用 spring cloud consul discovery: # 配置服務注冊到Consul上 register: true # 是否開啟在 consul 中注冊服務 health-check-path: /actuator/health #定義 consul 健康檢查路徑 health-check-interval: 10s # consul 健康檢查頻率 instance-id: ${spring.application.name}:${server.port} # 配置注冊到consul 服務的id enabled: true #啟用 consul 服務發現 service-name: ${spring.application.name} #設置 注冊到 consul 的服務名稱 ip-address: localhost # 訪問服務時使用的 ip地址 (還必須設置preferIpAddress才能使用) prefer-ip-address: true config: enabled: true format: yaml prefix: config profile-separator: ':' data-key: data default-context: consul-server-hello

  關於spring.cloud.consul.config的配置項描述如下:

  • enabled 設置config是否啟用,默認為true
  • format 設置配置的值的格式,可以yaml和properties
  • prefix 設置配的基本目錄,比如config
  • defaultContext 設置默認的配置,被所有的應用讀取
  • profileSeparator profiles配置分隔符,默認為‘,’
  • date-key為應用配置的key名字,值為整個應用配置的字符串。

3.然后修改 application.yml 為:

spring:
  profiles:
    active: dev

4.新增 application-dev.yml

server: port: 8081

5.網頁上訪問consul的KV存儲的管理界面,即http://localhost:8500/ui/dc1/kv,創建一條記錄 ,按照我們上面的配置信息,這里需要新增為 config/consul-server-hello:dev/data

6. 修改服務端的接口:

@RestController public class TestController { @Value("${foo.bar}") String fooBar; @GetMapping("/foo") public String getFooBar() { return fooBar; } @GetMapping("/hello") public String home() { return "hi ,i am from Consul:"; } }

7.服務調用放也要新增接口:

@RestController public class RibbonController { // private static final String REST_URL_PREFIX="http://localhost:8001"; 單機版 //集群的時候 需要配置該服務在eureka里注冊的名字
    private static final String REST_URL_PREFIX = "http://consul-server-hello"; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consulHello") public String find() throws ExecutionException, InterruptedException { return restTemplate.getForObject(REST_URL_PREFIX + "/hello", String.class); } @RequestMapping(value = "/foo") public String foo() throws ExecutionException, InterruptedException { return restTemplate.getForObject(REST_URL_PREFIX + "/foo", String.class); } }

8.都啟動后訪問 http://localhost:8655/foo

動態刷新配置:

  當使用spring cloud config作為配置中心的時候,可以使用spring cloud config bus支持動態刷新配置。Spring Cloud Comsul Config默認就支持動態刷新,只需要在需要動態刷新的類上加上@RefreshScope注解即可

注意事項:

  • consul支持的KV存儲的Value值不能超過512KB
  • Consul的dev模式,所有數據都存儲在內存中,重啟Consul的時候會導致所有數據丟失,在正式的環境中,Consul的數據會持久化,數據不會丟失。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM