Spring cloud(6)-配置管理及重新整理(Config,Bus)

ohcomeyes發表於2018-10-24

Spring Cloud Config(配置管理)

分散式系統中,由於服務數量巨多,為了方便服務配置檔案統一管理,實時更新(有某些配置資訊變化有一定頻率和規律,並且希望能夠做到儘量實時(營銷類,或活動類應用系統)),所以需要分散式配置中心元件。 分散式配置統一解決方案主要目標

  1. 部署極其簡單 同一個上線包,無須改動配置,即可在多個環境中(RD/QA/PRODUCTION) 上線
  2. 部署動態化 更改配置,無需重新打包或重啟,即可實時生效
  3. 統一管理 提供web平臺,統一管理 多個環境(RD/QA/PRODUCTION)、多個產品 的所有配置
  4. 支援微服務架構

目前流行的配置管理平臺有360的QConf百度的disconf淘寶的diamond等等,相比較同類產品:

服務配置比較

Spring Cloud Config最大的優勢是Spring無縫整合, Spring應用程式的遷移成本非常低,在配置獲取的介面上是完全一致, 結合SpringBoot可使你的專案有更加統一的標準(包括依賴版本和約束規範),避免了應為整合不同開軟體源造成的依賴版本衝突。
支援任何語言的任何應用。它也能為你支援對應用開發環境、測試環境、生產環境的配置、切換、遷移。預設的配置實現通過git實現,同時非常容易的支援其他的擴充套件

訊息匯流排

Spring Cloud Config原本放在本地檔案的配置抽取出來放在中心伺服器,從而能夠提供更好的管理、釋出能力。

  • 服務端 負責將git svn中儲存的配置檔案釋出成REST介面
  • 客戶端 可以從服務端REST介面獲取配置,客戶端並不能主動感知到配置的變化,從而主動去獲取新的配置,由訊息匯流排來通知各個Spring Cloud Config的客戶端去服務端更新配置。

####服務端配置 新增依賴

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 可選,安全認證 -->
<dependency> 
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
複製程式碼

開啟服務註冊(@EnableConfigServer開啟)

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
複製程式碼

增加配置

spring:
  application:
    name: config-server
  cloud:
    config:
      label: master
      server:
        git:
          uri: https://github.com/ohcomeyes/spring-cloud.git #注意use https not use ssh
          force-pull: true
          search-paths: config
      # username: ********
      # password: ********
server:
  port: 8888 # eureka中預設讀取的埠是8888
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
 
# 需要新增上面所說的安全認證依賴 ConfigSever 預設實現的基本的 HttpBasic 的認證。
security:
  user: # user 就是使用者名稱
    password: 123
複製程式碼

eureka中需要管理配置的服務配置

新增依賴

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-client</artifactId>
</dependency>
複製程式碼

開啟服務

@EnableEurekaClient
@RestController
@SpringBootApplication
public class EurekaProviderApplication {

    @Value("${server.port}")
    String port;
    // 通過 @Value 獲取服務端的 content 值的內容
    @Value("${version}")
    String version;


    @GetMapping("/")
    public String home() {
        return "Hello home,port:"+port+"--version:"+version;
    }

    @GetMapping("/dc")
    public String home1() {
        return "hello home1 ,port:"+port+"--version:"+version;
    }

    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class,args);
    }
}
複製程式碼

新增配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: eureka-provider
  cloud:
    config:
      label: master #遠端倉庫的分支
      profile: dev # 配置檔案
      discovery:
        enabled: true # 從配置中心讀取檔案。
        service-id: config-server # 通過服務名稱去 Eureka註冊中心找服務
server:
  port: 8081
複製程式碼

注意: 倉庫的配置檔案按照{application}-{profile}.yml或者{application}-{profile}.properties格式命名,
config-client的配置檔名和配置中心的{application}名相匹配。
http請求地址和資原始檔對映如下:

  • /{application}/{profile}[/{label}] */{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

啟動所有服務後,就能發現所有服務能夠從配置中心獲取到配置資訊了

配置重新整理(單個重新整理/區域性重新整理)

上面講的是服務統一從配置中心獲取配置資訊,下面講講怎麼來重新整理 Spring Cloud Config 中使用 Refresh 要在微服務執行期間動態重新整理配置,可以通過呼叫/refresh實現,但這樣只能針對單個服務,而且要手動操作 新增依賴

<!-- actuator 健康監控 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
複製程式碼

新增配置

# 說明:
#   1.要通過actuator暴露端點,必須同時是啟用(enabled)和暴露(exposed)的
#   2.所有除了/health和/info的端點,預設都是不暴露的
#   3.所有除了/shutdown的端點,預設都是啟用的
# PS.生產環境由於安全性的問題,注意不要暴露敏感端點
# springboot 1.5.X 以上預設開通了安全認證,下面配置關閉
management: 
  security:  
    enabled: false // 指定訪問資訊不進行使用者驗證  
複製程式碼

開啟服務

//通過 @RefreshScope 開啟 SpringCloudConfig 客戶端的 refresh 重新整理範圍,
//@RefreshScope要加在宣告@Controller宣告的類上,否則refresh之後Conroller拿不到最新的值,會預設呼叫快取。
@RefreshScope 
@EnableEurekaClient
@RestController
@SpringBootApplication
public class EurekaProviderApplication {

    @Value("${server.port}")
    String port;
    // 通過 @Value 獲取服務端的 content 值的內容
    @Value("${version}")
    String version;


    @GetMapping("/")
    public String home() {
        return "Hello home,port:"+port+"--version:"+version;
    }

    @GetMapping("/dc")
    public String home1() {
        return "hello home1 ,port:"+port+"--version:"+version;
    }

    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class,args);
    }
}
複製程式碼

Spring Cloud Bus(訊息匯流排)自動重新整理

上面講到的是手動重新整理,還只能針對單個服務,下面講講怎麼通過訊息匯流排來廣播式自動重新整理,通過RabbitMQkafkaGitWebhooks來觸發配置的更新 Spring Cloud Bus
事件處理機制和訊息中介軟體訊息的傳送和接收整合起來,主要由傳送端、接收端和事件組成。針對不同的業務需求,可以設定不同的事件,傳送端傳送事件,接收端接受相應的事件,並進行相應的處理,用於實現微服務之間的通訊。本質是利用了MQ的廣播機制在分散式的系統中傳播訊息 。

預設常用rabbitmqkafka兩個binder,說到rabbitmq,先了解下訊息佇列 kafka和redis中的訊息佇列區別:

  1. redis是記憶體資料庫,只是它的list資料型別剛好可以用作訊息佇列而已
  2. kafka還提供了訊息ACK和佇列容量、消費速率等訊息相關的功能,更加完善
  3. redis 釋出訂閱除了表示不同的 topic 外,並不支援分組(之間的最大區別),比如kafka中釋出一個東西,多個訂閱者可以分組,(同一個組裡只有一個訂閱者)會收到該訊息,這樣可以用作負載均衡。
  4. 處理資料大小的級別不同

訊息佇列(MQ) 訊息佇列(Message Queue)是一種應用間的通訊方式,訊息傳送後可以立即返回,由訊息系統來確保訊息的可靠傳遞。訊息釋出者只管把訊息釋出到 MQ 中而不用管誰來取,訊息使用者只管從 MQ 中取訊息而不管是誰釋出的。這樣釋出者和使用者都不用知道對方的存在。
其它常見場景包括最終一致性、應用解耦(訂單-庫存)、廣播、錯峰流控(秒殺等)等等

MQ和RPC的區別

  • MQ 是生產者消費者模式,是面向資料的。
  • RPC 是請求響應模式,是面向動作的。

RabbitMQ RabbitMQ是實現了高階訊息佇列協議(AMQP)的開源訊息代理軟體,也稱為面向訊息的中介軟體,是一個在AMQP基礎上完整的,可複用的企業訊息系統。它可以用於大型軟體系統各個模組之間的高效通訊,支援高併發,支援可擴充套件。

  • AMQP:Advanced Message Queue,高階訊息佇列協議。它是應用層協議的一個開放標準,為面向訊息的中介軟體設計,基於此協議的客戶端與訊息中介軟體可傳遞訊息,並不受產品、開發語言等條件的限制。
    主要特徵是面向訊息、佇列、路由(包括點對點和釋出/訂閱)、可靠性、安全。

RabbitMQ 最初起源於金融系統,用於在分散式系統中儲存轉發訊息,在易用性、擴充套件性、高可用性等方面表現不俗。具體特點包括:

  • 可靠性:RabbitMQ 使用一些機制來保證可靠性,如持久化、傳輸確認、釋出確認。
  • 靈活的路由
  • 訊息叢集
  • 高可用
  • 多種協議
  • 多語言客戶端
  • 管理介面
  • 跟蹤機制
  • 外掛機制

webhooks

  • webhook:是個在特定情況下觸發的一種api. 越來越多在web上的操作被描述為事件
  • 事件是webhook的核心,當倉庫發生特定action會觸發webhook,

向服務例項請求Spring Cloud Bus的/bus/refresh介面,從而觸發匯流排上其他服務例項的/refresh/bus/refresh介面還提供了destination引數,用來定位具體要重新整理的應用程式

spring cloud bus

  1. 提交程式碼觸發post請求給bus/refresh
  2. server端接收到請求併傳送給Spring Cloud Bus
  3. Spring Cloud bus接到訊息並通知給其它客戶端
  4. 其它客戶端接收到通知,請求Server端獲取最新配置
  5. 全部客戶端均獲取到最新的配置

結語

github上有關於Spring Cloud完整的部署。
其它相關文章
Spring cloud(1)-簡介以及選擇
Spring cloud(2)-服務發現(Eureka,Consul)
Spring cloud(3)-負載均衡(Feign,Ribbon)
Spring cloud(4)-熔斷(Hystrix)
Spring cloud(5)-路由閘道器(Zuul)
Spring cloud(6)-配置管理及重新整理(Config,Bus)
最後,給個 star 吧~
個人部落格~
簡書~

相關文章