Consul基本使用


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


[TOC]

前言

官網(wǎng)介紹Consul是一個(gè)分布式服務(wù)網(wǎng)格(Service Mesh)解決方案...

而我目前的理解是提供了分布式系統(tǒng)中的服務(wù)發(fā)現(xiàn)和配置解決方案, 使用go實(shí)現(xiàn), 目前在github的star是15k, 遠(yuǎn)超Netflix Eureka

關(guān)于Consul的架構(gòu), 功能, 對(duì)比都可參考官網(wǎng), 建議閱讀:

目的

  • 部署啟動(dòng)consul開發(fā)環(huán)境 —— dev
  • Spring Cloud Consul 基本使用
  • consul中的服務(wù)發(fā)現(xiàn)
  • consul中的配置中心
  • consul集群部署 (下節(jié))


下載&啟動(dòng)

進(jìn)入下載地址 下載對(duì)應(yīng)的版本即可, 解壓即得到可執(zhí)行文件

這里我下載最新版1.4.4, 在Windows測(cè)試單機(jī)開發(fā)環(huán)境, 在Linux環(huán)境測(cè)試consul集群部署

進(jìn)入命令行:

  • 驗(yàn)證版本: 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)
  • 啟動(dòng): consul agent -dev

正常啟動(dòng)后, 打開 http://127.0.0.1:8500 可以看到consul提供的UI, 長(zhǎng)這個(gè)樣子

上述方式重啟不會(huì)保存數(shù)據(jù), 可以加入數(shù)據(jù)持久的參數(shù)

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

關(guān)于Consul的操作, 常用有兩種方式: CLI和UI, 后面會(huì)演示部分用法


Spring Cloud Consul

介紹: 略...

依賴

可以選擇這個(gè)all

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

上面的all包含了以下三個(gè)依賴

<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>

也可以根據(jù)實(shí)際需要選擇引入

  • consul-discovery: 服務(wù)注冊(cè)和發(fā)現(xiàn)功能
  • consul-bus: 消息總線塔逃,提供配置實(shí)時(shí)刷新,不再依賴中間件
  • consul-config: 配置中心


健康檢查

Spring Cloud Consul 默認(rèn)會(huì)自動(dòng)檢查端點(diǎn) /actuator/health

可以集成spring-boot-starter-actuator, 或者自定義這個(gè)端點(diǎn):

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

從consul ui中可以看到檢查結(jié)果

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


服務(wù)間調(diào)用

準(zhǔn)備以下兩個(gè)模塊: consul-provider(服務(wù)提供者), consul-consumer(服務(wù)消費(fèi)者)

consul-provider

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

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

3, 提供接口
測(cè)試用, 隨便寫

@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 # 默認(rèn)就是true, consumer可以不注冊(cè)的也可設(shè)為false

3, 調(diào)用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);
    }
    

測(cè)試

啟動(dòng)consul后, consul-provider啟動(dòng)兩個(gè)實(shí)例, consul-consumer啟動(dòng)一個(gè)

查看Consul UI, 確保服務(wù)注冊(cè)成功

Consul UI service

測(cè)試一下consul-comsumer中的兩個(gè)接口

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

從訪問結(jié)果可以看到consul-consumer找到了兩個(gè)服務(wù)提供者的實(shí)例, 并從中進(jìn)行負(fù)載路由到其中一個(gè)


配置中心

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

規(guī)則

先進(jìn)行一個(gè)簡(jiǎn)單的put和get

使用CLI

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

# get
$ consul kv get name
thank

Consul UI也能設(shè)置和查看

可以輸入consul kv --help, 查看其他幾個(gè)子命令的說明

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

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

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

同樣, 在Consul UI也可以這樣設(shè)置, 并以目錄的形式展現(xiàn)


Spring Cloud Consul配置實(shí)踐

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

與Spring Cloud Config不同的是, Consul中使用配置中心很簡(jiǎn)易

在動(dòng)態(tài)刷新配置時(shí), 也沒有Spring Cloud Config中那樣需要依賴消息中間件和集成Spring Cloud Bus那么麻煩

簡(jiǎn)單測(cè)試

簡(jiǎn)單測(cè)試配置屬性的讀取及動(dòng)態(tài)刷新的功能

實(shí)際情況下應(yīng)該有一個(gè)配置中心的, 這里測(cè)試為了方便, 就用consul-provider中的配置做實(shí)驗(yàn)

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

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

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

接下來啟動(dòng)consul-provider和consul-consumer, 訪問對(duì)應(yīng)的API, 即可看到我們添加的配置生效了

試著在Consul UI中修改config/consul-provider/custom.address配置項(xiàng)的value值, 驗(yàn)證動(dòng)態(tài)刷新

注意點(diǎn)

  • 第1步是為了防止啟動(dòng)無該屬性報(bào)錯(cuò), 如果第3步提前配置了該屬性, 那么第1步可以省略
  • 為了測(cè)試動(dòng)態(tài)刷新的功能, 別忘了在屬性所在bean加上@RefreshScope注釋
  • 注意優(yōu)先級(jí): 如果配置中心中的配置涉及到程序啟動(dòng), 那么要放在bootstrap.yml中, 而非application.yml, 這點(diǎn)與Spring Cloud Config一樣

可能注意到consul配置項(xiàng)中key: config/consul-provider/custom.address 兩個(gè)前綴是什么意思

  • custom.address: 對(duì)應(yīng)yaml文件中的屬性
  • consul-provider: 這個(gè)不用說了, 服務(wù)名
  • config: Spring Cloud Consul中默認(rèn)的前綴, 你可以修改它

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

測(cè)試多profile

實(shí)驗(yàn)多個(gè)profiles: default, dev, test

首先在consul中建立三個(gè)配置文件

  • default環(huán)境:
    Key: consul-provider/data
    Value:

    custom:
      env: default
      common: some common properties
    
  • dev環(huán)境
    Key: consul-provider,dev/data
    Value:

    custom:
      env: dev
    
  • test環(huán)境
    Key: consul-provider,test/data
    Value:

    custom:
      env: test
    

編寫測(cè)試接口

@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 的結(jié)果, 試著更改配置項(xiàng)的值, 驗(yàn)證動(dòng)態(tài)刷新


規(guī)則&配置總結(jié)

兩種鍵值類型

  • key/value: 默認(rèn)方式, 鍵值一一對(duì)應(yīng), 上述[簡(jiǎn)單測(cè)試]演示的就是這種
  • 值為properties或yaml: [測(cè)試多profile]演示的是這種

常用配置

列舉幾個(gè)Spring Cloud Consul配置中心相關(guān)的常用配置項(xiàng)

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

相關(guān)配置項(xiàng)參考: org.springframework.cloud.consul.config.ConsulConfigProperties

實(shí)際使用中可能需要修改, 常用的配置項(xiàng)列舉:

拿一個(gè)上面的配置對(duì)照: config/consul-provider,test/data

配置項(xiàng)(spring.cloud.consul.config.*) 含義 默認(rèn)值
default-context 指定應(yīng)用名 application
prefix folder前綴 config
profile-separator 環(huán)境分隔符 ,
format 枚舉類型, 還支持PROPERTIES, YAML, FILES KEY_VALUE
data-key 當(dāng)format是properties或yaml時(shí), 將以該值作為key去尋找對(duì)應(yīng)配置 data
watch.* 與配置刷新相關(guān)的

讀取規(guī)則
通過前面的演示, 基本也能猜出大概的規(guī)則, 例如test環(huán)境會(huì)讀取 config/consul-provider,test/data 對(duì)應(yīng)的值

有一點(diǎn)需要注意, 在上面[測(cè)試多profile]中, 示例只在config/consul-provider/data中配置了custom.common, 指定test或dev環(huán)境后, 該配置也能讀出來

從這可以看出consul-provider,xxxconsul-provider中的配置值經(jīng)過了合并, 這與Spring Cloud Config一樣

把各環(huán)境都一樣的配置寫在這個(gè)默認(rèn)會(huì)被讀取的配置中是個(gè)不錯(cuò)的選擇

關(guān)于default-context配置項(xiàng), 默認(rèn)為application, 在上面的實(shí)驗(yàn)中, 在 consul-provider 項(xiàng)目中, 沒有配置 default-context,

也能找到配置中心對(duì)應(yīng)的consul-provider,xxx配置, 這與Spring Cloud Config中{name}-{profile}.yml: 服務(wù)名-環(huán)境名的尋找規(guī)則一樣

即默認(rèn)就會(huì)去找服務(wù)名對(duì)應(yīng)的配置項(xiàng), 如果配置中心的配置與服務(wù)名不同, 也支持你將default-context設(shè)置成非服務(wù)名

如果配置中心中存在application配置, 例如config/application/data, 那么所有應(yīng)用都會(huì)加載到它中的配置, 同樣適合做一些所有應(yīng)用都公共的配置項(xiàng)

優(yōu)先級(jí)

如果某個(gè)配置項(xiàng), 例如custom.common, 存在與以下四個(gè)配置中

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

如果指定profile=dev, 三者之間的優(yōu)先級(jí)為從上至下由高到低

配置刷新原理

在配置刷新原理上, Spring Cloud Config中實(shí)現(xiàn)動(dòng)態(tài)刷新的原理是用消息隊(duì)列和bus實(shí)現(xiàn)以消息總線的方式進(jìn)行通知配置信息的變化,

完成集群上的自動(dòng)化更新和批量配置屬性刷新.

Spring Cloud Consul 采用的是客戶端定期通過watch檢測(cè)consul中配置的變化, 然后觸發(fā) Spring RefreshEvent 刷新上下文

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娇斑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡材部,警方通過查閱死者的電腦和手機(jī)毫缆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乐导,“玉大人苦丁,你說我怎么就攤上這事∥锉郏” “怎么了芬骄?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鹦聪。 經(jīng)常有香客問我账阻,道長(zhǎng),這世上最難降的妖魔是什么泽本? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任淘太,我火速辦了婚禮,結(jié)果婚禮上规丽,老公的妹妹穿的比我還像新娘蒲牧。我一直安慰自己,他們只是感情好赌莺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布冰抢。 她就那樣靜靜地躺著,像睡著了一般艘狭。 火紅的嫁衣襯著肌膚如雪挎扰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天巢音,我揣著相機(jī)與錄音遵倦,去河邊找鬼。 笑死官撼,一個(gè)胖子當(dāng)著我的面吹牛梧躺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播傲绣,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掠哥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼巩踏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起续搀,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤塞琼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后目代,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗤练,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年榛了,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煞抬。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡霜大,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出革答,到底是詐尸還是另有隱情战坤,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布残拐,位于F島的核電站途茫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏溪食。R本人自食惡果不足惜囊卜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望错沃。 院中可真熱鬧栅组,春花似錦、人聲如沸枢析。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽醒叁。三九已至司浪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間把沼,已是汗流浹背断傲。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留智政,地道東北人认罩。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像续捂,于是被迫代替她去往敵國(guó)和親垦垂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宦搬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容