1. 程式人生 > >服務註冊發現、配置中心集一體的 Spring Cloud Consul

服務註冊發現、配置中心集一體的 Spring Cloud Consul

前面講了 Eureka 和 Spring Cloud Config,今天介紹一個全能選手 「Consul」。它是 HashiCorp 公司推出,用於提供服務發現和服務配置的工具。用 go 語言開發,具有很好的可移植性。被 Spring Cloud 納入其中,Eureka 停止新版本開發,更多的想讓開發者使用 Consul 來作為服務註冊發現使用。

Consul 提供的功能包括如下幾個:

服務發現

Consul 讓服務註冊和服務發現(通過 DNS 和 HTTP 介面)更加簡單,甚至對於外部服務(例如SaaS)註冊也一樣。

故障檢測

通過健康檢查,服務發現可以防止請求被路由到不健康的主機,並且可以使服務容易斷開(不再提供服務)。

多資料中心

Consul 不需要複雜的配置即可簡便的擴充套件到多個數據中心,查詢其它資料中心的服務或者只請求當前資料中心的服務。

鍵值儲存

靈活的鍵值儲存,提供動態配置、特徵標記、協作、leader 選舉等功能,通過長輪詢實現配置改變的即時通知。

Spring Cloud Consul 將 Consul 進行自動配置和進一步封裝。

Spring Cloud Consul 可替代已有的 Spring Cloud Eureka,也就是當做服務註冊發現框架使用。並且 Eureka 2.x 版本也已經停止開發,並且 Spring Cloud 官方也建議用 Spring Cloud Consul 來替代,當然如果已經用了 Eureka 在專案中也沒有關係,Eureka 已經足夠穩定,正常使用沒有任何問題。

Spring Cloud Consul 可替代已有的 Spring Cloud Config ,也就是當做配置中心使用。

Spring Cloud Consul 主要用作服務註冊發現,並且官方建議替代 Eureka,那麼它肯定具有 Eureka 或其他框架不具備的優勢,下面看一下對比它和其他服務發現方式做的一下對比(摘自網路):

功能點 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 採用 raft 演算法來保證資料的強一致性,如此帶來的優勢很明顯,相應的也帶來了一些犧牲:

  1. 服務註冊相比 Eureka 會稍慢一些。因為 Consul 的 raft 協議要求必須過半數的節點都寫入成功才認為註冊成功;
  2. Leader掛掉時,重新選舉期間整個 consul 不可用,以此保證了強一致性但犧牲了可用性。

Consul 的安裝和啟動

與 Eureka 不同,Consul 需要獨立安裝,可以到官網(https://www.consul.io/downloads.html)下載。具體作業系統的安裝方式不同,可參考官網。

Consul 提供了一系列的引數,用於在命令列執行。Consul 預設提供了 web UI 介面來檢視配置。通過訪問 server 的 8500 埠可以訪問到 web UI 控制檯。

開發過程中,我們可以通過命令 consul agent -dev 來啟動開發模式,啟動成功後,訪問 localhost:8500 可以看到當前 consul 的所有服務。如下圖:

更多的在生成環境的部署可自行搜尋相關介紹,這裡暫時只用 dev 模式啟動,用來介紹 Spring Cloud Consul 的使用。

實現服務提供者

1、引用 spring-cloud-consul

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-all</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-actuator</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-consul-dependencies</artifactId>
            <version>2.1.0.M2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2、設定 consul 相關配置,在 bootstrap.yml 配置檔案中,配置如下:

spring:
  cloud:
    consul:
      discovery:
        service-name: consul-provider  ## 服務提供者名稱
      host: localhost                  ## consul 所在服務地址
      port: 8500                       ## consul 埠

3、設定 server 相關配置,在 application.yml 配置檔案中,配置如下:

spring:
  application:
    name: consul-provider
server:
  port: 5000

endpoints:
  health:
    sensitive: false
  restart:
    enabled: true
  shutdown:
    enabled: true

management:
  security:
    enabled: false

4、增加一個 RestController ,寫兩個測試服務方法

@RestController
@Slf4j
public class HelloController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping(value = "test")
    public String test(){
        List<String> services = discoveryClient.getServices();
        for(String s : services){
            log.info(s);
        }
        return "hello spring cloud!";
    }

    @GetMapping(value = "nice")
    public String nice(){
        List<String> services = discoveryClient.getServices();
        for(String s : services){
            log.info("gogogo" + s);
        }
        return "nice to meet you!";
    }
}

5、Spring boot 啟動類

@SpringBootApplication
@EnableDiscoveryClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@EnableDiscoveryClient 註解標示這是一個 client 端。

啟動這個服務提供者,開啟 http://localhost:8500 可以看到這個服務

實現服務消費者

1、引用相關 maven 包,除了引用與上面服務提供者相同的包外,還引用了 openFeign

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

2、bootstrap.yml 配置,因為作為服務消費者,所以設定不註冊到 consul

spring:
  cloud:
    consul:
      discovery:
        register: false

3、application.yml 配置

spring:
  application:
    name: consul-customer
server:
  port: 5001

endpoints:
  health:
    sensitive: false
  restart:
    enabled: true
  shutdown:
    enabled: true

management:
  security:
    enabled: false

4、專案啟動類

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application {

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

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

使用 @EnableDiscoveryClient 註解表示作為服務 client 端,@EnableFeignClients 啟用 openFeign 。

5、新建一個 openFeign 服務介面

@FeignClient(value = "consul-provider")
public interface IHelloService {

    @RequestMapping(value = "/hello")
    String hello();

    @RequestMapping(value = "nice")
    String nice();
}

對應服務提供者中提供的兩個 RESTful 介面地址

6、實現一個 RestController 來訪問服務提供者開放出來的服務

@RestController
public class ConsumerController {

    @Autowired
    private LoadBalancerClient loadBalancer;

    @Autowired
    private DiscoveryClient discoveryClient;


    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IHelloService helloService;

    private final static String SERVICE_NAME = "consul-provider";


    /**
     * 使用普通的 RestTemplate 方法訪問服務
     *
     * @return
     */
    @GetMapping(value = "test")
    public Object test() {
        String result = restTemplate.getForObject("http://"+SERVICE_NAME + "/test", String.class);
        System.out.println(result);
        return result;
    }

    /**
     * 使用 openFeign 方式訪問服務
     *
     * @return
     */
    @GetMapping(value = "feign")
    public Object feign() {
        String s = helloService.nice();
        return s;
    }
    

    /**
     * 獲取所有服務例項
     *
     * @return
     */
    @GetMapping(value = "/services")
    public Object services() {
        return discoveryClient.getInstances(SERVICE_NAME);
    }

    /**
     * 從所有服務中選擇一個服務(輪詢)
     */
    @GetMapping(value = "/choose")
    public Object choose() {
        return loadBalancer.choose(SERVICE_NAME).getUri().toString();
    }
}

啟動消費者程式,然後訪問對應的 RESTful 介面,可以得到對應的結果。

實現高可用服務提供者

線上的微服務最好不要是單點形式,接下來通過配置來啟動兩個服務提供者,只要保證 service-name 相同,就表示這是同一個服務。

1、 bootstrap.yml 配置不變

spring:
  cloud:
    consul:
      discovery:
        service-name: consul-provider
      host: localhost
      port: 8500

2、application.yml 修改為如下配置

spring:
  profiles:
    active: consul-provider1
endpoints:
  health:
    sensitive: false
  restart:
    enabled: true
  shutdown:
    enabled: true

management:
  security:
    enabled: false

---
spring:
  profiles: consul-provider1
  application:
    name: consul-provider1

server:
  port: 5000

---
spring:
  profiles: consul-provider2
  application:
    name: consul-provider2

server:
  port: 5002

3、之後啟動的時候加上 vm 引數。分別加上引數:

-Dspring.profiles.active=consul-provider1

-Dspring.profiles.active=consul-provider2

分別在 5000 埠和 5002 埠啟動服務提供者 consul-provider

4、最後仍然訪問消費者的 RESTful 介面地址,可以在服務提供者後臺看到每次請求呼叫的服務例項。

用作配置中心

我們知道,Spring Cloud Config 提供了配置中心的功能,但是需要配合 git、svn 或外部儲存(例如各種資料庫),那麼既然使用了 Consul ,就可以使用 Consul 提供的配置中心功能,並且不需要額外的 git 、svn、資料庫等配合使用。

接下來,簡單介紹一下 Spring Cloud Consul 如何用作配置中心。Consul 支援 yaml 和 properties 格式的配置檔案內容,本例中以 yaml 格式為例。

1、引用相關的 maven 包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</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-actuator</artifactId>
</dependency>

2、bootstrap.yml 配置,這裡主要設定有關 config 的引數

spring:
  cloud:
    consul:
      config:
        enabled: true    # 啟用配置中心
        format: yaml     # 指定配置格式為 yaml
        data-key: mysql_config # 也就是 consul 中 key/value 中的 key
        prefix: config         # 可以理解為配置檔案所在的最外層目錄
        defaultContext: consul-config  # 可以理解為 mysql_config 的上級目錄
      discovery:
        register: false

對應到 consul 上,key/value 裡的配置如下:

3、application.yml 配置檔案內容

spring:
  application:
    name: consul-config
server:
  port: 5008

endpoints:
  health:
    sensitive: false
  restart:
    enabled: true
  shutdown:
    enabled: true

management:
  security:
    enabled: false

4、定義配置檔案實體類,指定 @ConfigurationProperties 註解,指定字首為 mysql,也就是 key/value 配置檔案中的頂層 key。

@Component
@ConfigurationProperties(prefix = "mysql")
public class MySqlComplexConfig {

    public static class UserInfo{

        private String username;

        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }

    private String host;

    private UserInfo user;


    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public UserInfo getUser() {
        return user;
    }

    public void setUser(UserInfo user) {
        this.user = user;
    }

}

5、新建一個 RestController 來獲取輸出 value 內容

@RestController
@Slf4j
public class ConfigController {

    @Autowired
    private MySqlConfig mySqlConfig;

    @Autowired
    private MySqlComplexConfig mySqlComplexConfig;


    @GetMapping(value = "mysqlhost")
    public String getMysqlHost(){
        return mySqlConfig.getHost();
    }

    @GetMapping(value = "mysqluser")
    public String getMysqlUser(){
        log.info(mySqlComplexConfig.getHost());
        MySqlComplexConfig.UserInfo userInfo = mySqlComplexConfig.getUser();
        return userInfo.toString();
    }

}

6、最後,啟動應用,訪問 RestController 中的 RESTful 介面即可看到配置檔案內容。

與 Spring Cloud Config 相比,Consul 在控制檯修改配置後,會立即更新,不用再結合 Spring Cloud Bus 之類的配合了。

原始碼地址
如果你覺得寫的還可以的話,請點個「推薦」吧

歡迎關注,不定期更新本系列和其他文章
古時的風箏 ,進入公眾號可以加入交流群

相關推薦

服務註冊發現配置中心一體Spring Cloud Consul

前面講了 Eureka 和 Spring Cloud Config,今天介紹一個全能選手 「Consul」。它是 HashiCorp 公司推出,用於提供服務發現和服務配置的工具。用 go 語言開發,具有很好的可移植性。被 Spring Cloud 納入其中,Eureka 停止新版本開發,更多的想讓開發者使用

Spring Cloud Config 分散式配置中心使用教程 Spring Cloud Config 分散式配置中心使用教程

Spring Cloud Config 分散式配置中心使用教程 一、簡介 在分散式系統中,由於服務數量巨多,為了方便服務配置檔案統一管理,實時更新,所以需要分散式配置中心元件。 在Spring Cloud中,有分散式配置中心元件spring cloud config ,它支援配置服務放在配置服務的記憶體

深入淺出高性能服務發現配置框架Nacos系列 3: 服務發現:Nacos客戶端初始化流程

tor trim 如何 try 文件的 client 註冊 rgs erro 上一章節,我們從全局了解了一下Nacos項目的模塊架構,做到了心中有數,現在,我們去逐步去挖掘裏面的代碼細節,很多人在學習開源的時候,無從下手,代碼那麽多,從哪個地方開始看呢?我們可以從一個接口開

深入淺出高性能服務發現配置框架Nacos系列 2: Nacos項目結構介紹

開始 最新 世界 微信 頻繁 throwable enter ica ice 今天,我們分析一下Nacos工程的包模塊結構,都是負責什麽功能的,從全局看一下整個工程,從整體到細節,還沒下載源碼的同學,趕緊動起來!https://github.com/alibaba/naco

深入淺出高性能服務發現配置框架Nacos系列 1: HelloWorld

產品 val 下載源碼 tmp 系列 嘗試 文件夾 home The Nacos是什麽? 引用官方的介紹,他主要提供以下幾個功能點: 動態配置服務 服務發現及管理 動態DNS服務 動態配置服務 就是通過一個系統,管理系統中的配置項,在配置項需要更新的時候,可以通過管理系

深入淺出高效能服務發現配置框架Nacos系列 1: HelloWorld

Nacos是什麼? 引用官方的介紹,他主要提供以下幾個功能點: 動態配置服務 服務發現及管理 動態DNS服務 動態配置服務 就是通過一個系統,管理系統中的配置項,在配置項需要更新的時候,可以通過管理系統去操作更新,更新完了之後,會主動推送到訂閱了這個配置的客

深入淺出高效能服務發現配置框架Nacos系列 2: Nacos專案結構介紹

今天,我們分析一下Nacos工程的包模組結構,都是負責什麼功能的,從全域性看一下整個工程,從整體到細節,還沒下載原始碼的同學,趕緊動起來!https://github.com/alibaba/nacos,這個是github程式碼地址,開始之前先start關注一下

高可用的服務註冊中心以及服務註冊發現簡單分析

現在我們的服務註冊中心以及服務提供者消費者都已經搭建完畢了,但是我們需要考慮一個問題就是 如果我們的服務註冊中心Eureka掛了怎麼辦? 高可用的服務註冊中心 服務註冊中心Eureka Server,是一個例項,當成千上萬個服務向它註冊的時候,它的負載是

spring cloud服務快速教程之(七) Spring Cloud Alibaba--nacos(一)服務註冊發現

0、前言   什麼是Spring Cloud Alibaba?   Spring Cloud Alibaba 是阿里開源的,致力於提供微服務開發的一站式解決方案。此專案包含開發分散式應用微服務的必需元件,方便開發者通過 Spring Cloud 程式設計模型輕鬆使用這些元件來開發分散式應用服務。  

服務架構:動態配置中心搭建

pre 有著 ice zed start nbsp ack pom.xml文件 之間 版權聲明:本文為博主原創文章,轉載請註明出處,歡迎交流學習! 在微服務架構中,服務之間有著錯綜復雜的依賴關系,每個服務都有自己的依賴配置,在運行期間很多配置會根據訪問流量等因

Linux DNS 服務器安裝配置和維護

web med this 包含 從右到左 主域 回復 特定 mini 每個 IP 地址都可以有一個主機名,主機名由一個或多個字符串組成,字符串之間用小數點隔開。有了主機名,就不要死記硬背每臺 IP 設備的 IP 地址,只要記住相對直觀有意義的主機名就行了。這就是 DNS 協

2018-3-26 14周1次課 NFS服務端安裝配置

NFS14.1 NFS介紹·NFS是Network File System的縮寫·NFS最早由Sun公司開發,分2,3,4三個版本,2和3由Sun起草開發,4.0開始Netapp公司參與並主導開發,最新為4.1版本·NFS數據傳輸基於RPC協議,RPC為Remote Procedure Call的簡寫。·NF

spring boot 2.0.3+spring cloud (Finchley)6配置中心Spring Cloud Config

repo 相互 class AS 默認 分布式系 配置信息 上傳 RR Spring Cloud Config 是用來為分布式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分為服務端與客戶端兩個部分。其中服務端也稱為分布式配置中心,它是一個獨立的微服務應用,用來連

詳解postfix郵箱服務器安裝配置及其工作原理(內附源碼包)

zhang 關閉防火墻 互聯 分享 接收郵件 目錄 ifconfig shutdown 數字 簡介 postfix是Wietse Venema在IBM的GPL協議之下開發的MTA(郵件傳輸代理)軟件。postfix是Wietse Venema想要為使用最廣泛的sendmai

服務註冊發現Eureka

一 Eureka相關概念 1 Peer   2 Zone   3 Region 地理區域   3 CAP理論   4 線上擴容   5     二 註冊發現 Eureka 1 搭

spring cloud 服務註冊/發現/提供/呼叫 demo

spring cloud 服務註冊/發現 Spring Cloud使用erureka server,  然後所有需要訪問配置檔案的應用都作為一個erureka client註冊上去。eureka是一個高可用的元件,它沒有後端快取,每一個例項註冊之後需要向註冊中心傳送心跳,在預設情況下erureka

C#建立Window服務圖解,安裝配置以及C#操作Windows服務

一、首先開啟VS2013,建立Windows服務專案 二、建立完成後對"Service1.cs"重新命名位"ServiceDemo";然後切換到程式碼檢視,寫個服務執行日誌。 using System; using System.Collections.Generic; usi

Nginx服務基本概念配置詳解和反向代理

                         &nb

spring cloud(五配置中心

在分散式系統中,由於服務數量巨多,為了方便服務配置檔案統一管理,實時更新,所以需要分散式配置中心元件。在Spring Cloud中,有分散式配置中心元件spring cloud config ,它支援配置服務放在配置服務的記憶體中(即本地),也支援放在遠端Git倉庫中。 一、設定一個配置中心(e