Consul基本使用


原文: Consul基本使用
date: 2019-05-13 17:01:37html


前言

官網介紹Consul是一個分佈式服務網格(Service Mesh)解決方案... java

而我目前的理解是提供了分佈式系統中的服務發現和配置解決方案, 使用go實現, 目前在github的star是15k, 遠超Netflix Eurekagit

關於Consul的架構, 功能, 對比均可參考官網, 建議閱讀:github

目的spring

  • 部署啓動consul開發環境 —— dev
  • Spring Cloud Consul 基本使用
  • consul中的服務發現
  • consul中的配置中心
  • consul集羣部署 (下節)


下載&啓動

進入下載地址 下載對應的版本便可, 解壓即獲得可執行文件shell

這裏我下載最新版1.4.4, 在Windows測試單機開發環境, 在Linux環境測試consul集羣部署bootstrap

進入命令行:bash

  • 驗證版本: consul --version
λ consul --version
Consul v1.4.4
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
  • 啓動: consul agent -dev

正常啓動後, 打開 http://127.0.0.1:8500 能夠看到consul提供的UI, 長這個樣子架構

上述方式重啓不會保存數據, 能夠加入數據持久的參數app

$ consul agent -server -bootstrap -advertise 127.0.0.1 -data-dir ./data -ui

關於Consul的操做, 經常使用有兩種方式: CLI和UI, 後面會演示部分用法


Spring Cloud Consul

介紹: 略...

依賴

能夠選擇這個all

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

上面的all包含了如下三個依賴

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

也能夠根據實際須要選擇引入

  • consul-discovery: 服務註冊和發現功能
  • consul-bus: 消息總線,提供配置實時刷新,再也不依賴中間件
  • consul-config: 配置中心


健康檢查

Spring Cloud Consul 默認會自動檢查端點 /actuator/health

能夠集成spring-boot-starter-actuator, 或者自定義這個端點:

@GetMapping("/actuator/health")
public String health() {
    return "OK";
}

從consul ui中能夠看到檢查結果

HTTP GET http://thank-pc:8801/actuator/health: 200 Output: OK


服務間調用

準備如下兩個模塊: consul-provider(服務提供者), consul-consumer(服務消費者)

consul-provider

1, 引入上述pom依賴
2, bootstrap.yml主要配置

spring:
 application:
 name: consul-provider
 cloud:
 consul:
 host: 127.0.0.1
 port: 8500

3, 提供接口
測試用, 隨便寫

@GetMapping("getHello")
public String getHello(@RequestParam String name) throws Exception {
    return String.format("[%s:%s] Hello %s", InetAddress.getLocalHost().getHostName(), this.port, name);
}

consul-comsumer

1, 引入上述pom依賴
2, bootstrap.yml主要配置

spring:
 application:
 name: consul-comsumer
 cloud:
 consul:
 host: 127.0.0.1
 port: 8500
 discovery:
 register: true # 默認就是true, consumer能夠不註冊的也可設爲false

3, 調用consul-provider中的getHello()

這裏用最經常使用的兩種方式 RestTemplate || Feign

  • RestTemplate

    @GetMapping("restTemplateInvoke")
    public ResponseEntity<String> restTemplateInvoke(@RequestParam String name) {
      String url = "http://consul-provider/getHello?name=" + name;
      String result = this.restTemplate.getForObject(url, String.class);
      return new ResponseEntity(result, HttpStatus.OK);
    }
    
  • Feign

    @FeignClient("consul-provider")
    public interface HelloClient {
        @GetMapping("getHello")
        String getHello(@RequestParam String name);
    }
    
    
    @GetMapping("feignInvoke")
    public ResponseEntity<String> feignInvoke(@RequestParam String name) {
      String result = this.helloClient.getHello(name);
      return new ResponseEntity(result, HttpStatus.OK);
    }
    

測試

啓動consul後, consul-provider啓動兩個實例, consul-consumer啓動一個

查看Consul UI, 確保服務註冊成功

Consul UI service

測試一下consul-comsumer中的兩個接口

  • GET http://localhost:8801/test/feignInvoke?name=thank
  • GET http://localhost:8801/test/restTemplateInvoke?name=thank

從訪問結果能夠看到consul-consumer找到了兩個服務提供者的實例, 並從中進行負載路由到其中一個


配置中心

從UI中可以看到, Consul也提供了配置中心的功能 —— Key/Value

規則

先進行一個簡單的put和get

使用CLI

# put
$ consul kv put name thank
Success! Data written to: name
 # get
$ consul kv get name
thank

Consul UI也能設置和查看

能夠輸入consul kv --help, 查看其餘幾個子命令的說明

爲了區分服務和profile, key支持目錄分類(key or folder), 用/來區分, 例如:

$ consul kv put config/consul-provider/custom.address 北京
 $ consul kv get /config/consul-provider/custom.address
北京

一樣, 在Consul UI也能夠這樣設置, 並以目錄的形式展示


Spring Cloud Consul配置實踐

在前面的pom依賴中可以看到其中的配置管理功能consul-config

與Spring Cloud Config不一樣的是, Consul中使用配置中心很簡易

在動態刷新配置時, 也沒有Spring Cloud Config中那樣須要依賴消息中間件和集成Spring Cloud Bus那麼麻煩

簡單測試

簡單測試配置屬性的讀取及動態刷新的功能

實際狀況下應該有一個配置中心的, 這裏測試爲了方便, 就用consul-provider中的配置作實驗

  1. 在配置文件bootstrap.yml中加入一個自定義配置

    custom:
     address: defaultAddress
    
  1. 在consul-provider中讀取該屬性

    @Value("${custom.address}")
    public String address;
    
  1. Consul UI或命令行中添加一個配置
    • key: config/consul-provider/custom.address
    • value: 北京

接下來啓動consul-provider和consul-consumer, 訪問對應的API, 便可看到咱們添加的配置生效了

試着在Consul UI中修改config/consul-provider/custom.address配置項的value值, 驗證動態刷新

注意點

  • 第1步是爲了防止啓動無該屬性報錯, 若是第3步提早配置了該屬性, 那麼第1步能夠省略
  • 爲了測試動態刷新的功能, 別忘了在屬性所在bean加上@RefreshScope註釋
  • 注意優先級: 若是配置中心中的配置涉及到程序啓動, 那麼要放在bootstrap.yml中, 而非application.yml, 這點與Spring Cloud Config同樣

可能注意到consul配置項中key: config/consul-provider/custom.address 兩個前綴是什麼意思

  • custom.address: 對應yaml文件中的屬性
  • consul-provider: 這個不用說了, 服務名
  • config: Spring Cloud Consul中默認的前綴, 你能夠修改它

具體可參考org.springframework.cloud.consul.config.ConsulConfigProperties#prefix

測試多profile

實驗多個profiles: default, dev, test

首先在consul中創建三個配置文件

  • default環境:
    Key: consul-provider/data
    Value:

    custom:
     env: default
     common: some common properties
    
  • dev環境
    Key: consul-provider,dev/data
    Value:

    custom:
     env: dev
    
  • test環境
    Key: consul-provider,test/data
    Value:

    custom:
     env: test
    

編寫測試接口

@RestController
@RequestMapping("config")
@RefreshScope
public class ConfigController {

    @Value("${custom.env}")
    private String env;

    @Value("${custom.common}")
    private String common;

    @GetMapping("getEnv")
    public String getEnv() {
        return "Environment: " + this.env + "\nCommon: " + this.common;
    }
}

bootstrap.yml 中加入以下配置:

spring:
 cloud:
 consul:
 config:
# default-context: consul-provider
 format: YAML
  profiles
 active: dev

分別指定不一樣的 spring.profiles.active, dev or test or none

觀察 curl localhost:8901/config/getEnv 的結果, 試着更改配置項的值, 驗證動態刷新


規則&配置總結

兩種鍵值類型

  • key/value: 默認方式, 鍵值一一對應, 上述[簡單測試]演示的就是這種
  • 值爲properties或yaml: [測試多profile]演示的是這種

經常使用配置

列舉幾個Spring Cloud Consul配置中心相關的經常使用配置項

在上面的示例中, 基本都使用了Spring Cloud Consul中的默認配置

相關配置項參考: org.springframework.cloud.consul.config.ConsulConfigProperties

實際使用中可能須要修改, 經常使用的配置項列舉:

拿一個上面的配置對照: config/consul-provider,test/data

配置項(spring.cloud.consul.config.*) 含義 默認值
default-context 指定應用名 application
prefix folder前綴 config
profile-separator 環境分隔符 ,
format 枚舉類型, 還支持PROPERTIES, YAML, FILES KEY_VALUE
data-key 當format是properties或yaml時, 將以該值做爲key去尋找對應配置 data
watch.* 與配置刷新相關的

讀取規則
經過前面的演示, 基本也能猜出大概的規則, 例如test環境會讀取 config/consul-provider,test/data 對應的值

有一點須要注意, 在上面[測試多profile]中, 示例只在config/consul-provider/data中配置了custom.common, 指定test或dev環境後, 該配置也能讀出來

從這能夠看出consul-provider,xxxconsul-provider中的配置值通過了合併, 這與Spring Cloud Config同樣

把各環境都同樣的配置寫在這個默認會被讀取的配置中是個不錯的選擇

關於default-context配置項, 默認爲application, 在上面的實驗中, 在 consul-provider 項目中, 沒有配置 default-context,

也能找到配置中心對應的consul-provider,xxx配置, 這與Spring Cloud Config中{name}-{profile}.yml: 服務名-環境名的尋找規則同樣

即默認就會去找服務名對應的配置項, 若是配置中心的配置與服務名不一樣, 也支持你將default-context設置成非服務名

若是配置中心中存在application配置, 例如config/application/data, 那麼全部應用都會加載到它中的配置, 一樣適合作一些全部應用都公共的配置項

優先級

若是某個配置項, 例如custom.common, 存在與如下四個配置中

  • config/{appname},dev/data
  • config/{appname}/data
  • config/application,dev/data
  • config/application/data

若是指定profile=dev, 三者之間的優先級爲從上至下由高到低

配置刷新原理

在配置刷新原理上, Spring Cloud Config中實現動態刷新的原理是用消息隊列和bus實現以消息總線的方式進行通知配置信息的變化,

完成集羣上的自動化更新和批量配置屬性刷新.

Spring Cloud Consul 採用的是客戶端按期經過watch檢測consul中配置的變化, 而後觸發 Spring RefreshEvent 刷新上下文

參考文檔

原文地址:https://www.jianshu.com/p/2e0669fed7f9
相關文章
相關標籤/搜索