SpringCloud系列之分散式配置中心極速入門與實踐

SpringCloud系列之分散式配置中心極速入門與實踐

@

1、分散式配置中心簡介

在實際的項目開發中,配置文件是使用比較多的,很多項目有測試環境(TEST)、開發環境(DEV)、規範的項目還有集成環境(UAT)、生產環境(PROD),每個環境就一個配置文件。

在這裡插入圖片描述

這個在單體應用的項目里是沒什麼問題,如果是分散式微服務項目,就會有很多的模組,比如微服務A、微服務B等等,每個工程都有一套配置文件,隨著業務增長,肯定會有很多配置,分散管理,不能實現統一的管理,所以就有了微服務的配置文件統一管理組件,比如spring cloud官方的spring cloud config、攜程的 Apollo,還有最近比較火的阿里 nacos,每款產品各有自己的特點,不過本部落格只介紹spring cloud config

作為一款分散式的配置中心,其基本的功能應該有統一的配置文件管理,至於怎麼存儲可以自行設計,客戶端可以從配置中心下拉配置數據,還有一個重要功能就是推送,有了推送功能,才能做到將數據統一發給客戶端及時更新,總不能讓客戶端自己pull,如果在客戶端很多的情況,這種肯定是不合理的,簡單畫圖表示:
在這裡插入圖片描述

2、什麼是SpringCloud Config?

ok,前面簡單介紹了分散式配置中心的基本概念,現在看看spring cloud提供的這塊分散式配置中心spring cloud config是怎麼設計?簡單歸納其特點:

  • 文件存儲:默認Git倉庫(github、gitlab等等)
  • 版本關聯:默認Git
  • 許可權控制:需要Git支援
  • 多環境(profile):配置文件指定
  • 動態更新:需要基於Springcloud config bus
  • 定時更新:需要自行拓展
  • 管理後台:默認不帶

所以有一個明顯的特點,springcloud config默認就是基於git倉庫來實現配置文件統一管理的,所以很明顯其有如下角色:

  • 配置倉庫:git倉庫
  • 配置服務端:config server,負責從git倉庫下拉配置文件到本地,然後可以統一推送給客戶端
  • 配置客戶端:各微服務業務客戶端,可以從配置服務端pull配置數據

ok,簡單畫圖表示其架構,如圖所示:
在這裡插入圖片描述

3、例子實驗環境準備

環境準備:

  • JDK 1.8
  • SpringBoot2.2.3
  • SpringCloud(Hoxton.SR7)
  • Maven 3.2+
  • 開發工具
    • IntelliJ IDEA
    • smartGit

github遠程倉庫創建,可以在github上創建一個springCloudExamples項目,然後新建一個文件夾,命名為config-repository

4、Config Server程式碼實現

創建一個SpringBoot Initialize項目,詳情可以參考我之前部落格:SpringBoot系列之快速創建項目教程

如圖:選擇config Server
在這裡插入圖片描述
也可以自行在maven引入如下配置:

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

使用註解@EnableConfigServer表示這個config服務端工程

package com.example.springcloud.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class SpringcloudConfigServerApplication {

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

}

新建bootstrap.yml配置文件,指定github倉庫的地址:

server:
  port: 8761
spring:
  application:
    name: springcloud-config-server
  cloud:
    config:
      server:
        git:
          uri: //github.com/your_github_account/springCloudExamples
          username: your_github_account
          password: your_github_password
          search-paths: config-repository

5、Config Client程式碼實現

同樣新建SpringBoot Initialize項目,快速創建
在這裡插入圖片描述
pom配置文件:

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

yaml配置,uri指定為config server的地址,profile是環境變數,可以指定為dev(開發環境),label表示分支,master是指github的主幹分支

server:
  port: 8082
spring:
  application:
    name: springcloud-config-client
  cloud:
    config:
      uri: //127.0.0.1:8761/
      profile: dev
      label: master

然後,我們要在github倉庫新建配置文件:命名規範必須是客戶端的spring. application.name加上profile
在這裡插入圖片描述
在配置文件,隨便寫點:

config.client.profile=springcloud-config-client-dev

測試:要先啟動config server,然後再啟動config client,寫個例子測試,要加上@RefreshScope實現刷新功能

@RestController
@RefreshScope
public class ConnfigClientController {

    @Value("${config.client.profile}")
    private String profile;

    @GetMapping(value = "/test")
    public String test() {
        return this.profile;
    }

}

啟動SpringBoot項目,測試:
在這裡插入圖片描述
在config server啟動過程,可以看到config server從github下拉配置文件到本地快取,具體是C盤AppData目錄
在這裡插入圖片描述

6、客戶端pull刷新實現

客戶端要實現下拉配置數據,怎麼實現?可以集成spring-boot-starter-actuator來實現:

pom配置:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

spring-boot-starter-actuator配置:include加上rehresh配置

management:
  endpoints:
    web:
    # 前綴名,默認也是actuator
      base-path: /actuator
      # 默認只開放info,health的方式訪問,加上refresh
      exposure:
        include: info,health,refresh
  endpoint:
    health:
      show-details: always
    refresh:
      enabled: true

訪問客戶端的鏈接,注意要用post方式,//localhost:8082/actuator/refresh

github配置文件沒更新的情況:
在這裡插入圖片描述
修改配置文件,commit和push到github
在這裡插入圖片描述
調用介面時候,可以看到config client從config server獲取數據:
在這裡插入圖片描述

7、消息匯流排Spring Cloud Bus

  • 什麼是匯流排?
    在微服務架構的系統中,通常會使用輕量級的消息代理來構建一個共用的消息主題,並讓系統中所有微服務實例都鏈接上來。由於該主題中產生的消息會被所有實例監聽和消費,所以稱它為消息匯流排。
  • 什麼是Spring Cloud Bus?

Spring Cloud Bus是用來將分散式系統的節點與輕量級消息系統鏈接起來的框架,它整合了Java的事件處理機制和消息中間件的功能

Spring Cloud Bus能管理和傳播分散式消息間的消息,就像一個分散式執行器,可用於廣播狀態更改、事件推送等,也可以當作微服務間的通訊通道

看了理論,貌似不理解?所以還是從前面學習說起,前面介紹說明作為一個分散式的配置中心,至少應該有推送消息的功能,所以這個配置中心的角色可以由config server充當,實現的效果是config server(配置中心)一刷新數據,客戶端都能同步更新,畫圖進行說明:
在這裡插入圖片描述

  • 1、配置中心(config server)執行bus-refresh,spring cloud bus提供的刷新介面,配置中心就從git倉庫下拉數據到本地git倉庫
  • 2、執行bus-refresh之後,將消息發給spring cloud bus(消息匯流排),消息匯流排將消息寫到消息隊列(rabbitMQ)的topic中
  • 3、只要訂閱這個消息隊列topic的都能監聽到spring cloud bus的消息(基於rabbitmq)
  • 4、監聽到之後,config client從config server pull更新配置數據

其實簡而言之,Config Client實例都監聽RabbitMQ中同一個topic,當一個服務刷新數據的時候,它會把這個資訊放入到Topic中,這樣其它監聽同一Topic的服務就能得到通知,然後去更新自身的配置,當然這個刷新操作不一定要放在config server,也可以放在某個客戶端觸發,只要將消息發送給消息匯流排就可以

8、Docker安裝部署RabbitMQ

主要介紹一下Docker版本,常用的docker鏡像操作:
在這裡插入圖片描述

查詢rabbitMQ鏡像:

management版本,不指定默認為最新版本latest

 docker search rabbitmq:management

在這裡插入圖片描述
拉取鏡像:

docker pull rabbitmq:management

查看docker鏡像列表:

docker images

Docker容器操作:
ok,上面命令執行後,鏡像就已經拉取到本地倉庫了,然後可以進行容器操作,啟動rabbitMQ

簡單版

docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management
  • -d 後台運行
  • -p 隱射埠
  • –name 指定rabbitMQ名稱

複雜版(設置賬戶密碼,hostname)

docker run -d -p 15672:15672  -p  5672:5672  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin --name rabbitmq --hostname=rabbitmqhostone  rabbitmq:management
  • -d 後台運行
  • -p 隱射埠
  • –name 指定rabbitMQ名稱
  • RABBITMQ_DEFAULT_USER 指定用戶帳號
  • RABBITMQ_DEFAULT_PASS 指定帳號密碼

執行如上命令後訪問://ip:15672/

默認帳號密碼:guest/guest
在這裡插入圖片描述
在這裡插入圖片描述
其它常用容器命令:

查看運行中的容器

# 查看所有的容器用命令docker ps -a
docker ps

啟動容器

# eg: docker start 9781cb2e64bd
docker start CONTAINERID[容器ID]

stop容器

docker stop CONTAINERID[容器ID]

刪除一個容器

 docker rm CONTAINERID[容器ID]

查看Docker容器日誌

# eg:docker logs 9781cb2e64bd
docker logs container‐name[容器名]/container‐id[容器ID]

9、Spring Cloud Bus動態刷新

有了前面的學習,接著進行程式碼例子實踐,config server pom配置:

<dependency>
  <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

yaml配置:開放bus-refresh

management:
  endpoints:
    web:
      base-path: /actuator
      exposure:
        include: info,health,refresh,bus-refresh
  endpoint:
    health:
      show-details: always
    refresh:
      enabled: true

加上rabbitmq配置

  # RabbitMQ配置
  rabbitmq:
    host: 192.168.6.155
    port: 5672
    username: guest
    password: guest
    virtual-host: /

Config Client程式碼例子改造,pom配置:

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

也要加上rabbitMQ配置,這樣才能訂閱更新:

 # RabbitMQ配置
  rabbitmq:
    host: 192.168.6.155
    port: 5672
    username: guest
    password: guest
    virtual-host: /

客戶端必須修改,refresh、enabled都要改為true,trace是進行跟蹤的,可以根據需要開啟

spring:
  cloud:
    bus:
      enabled: true
      refresh:
        enabled: true
      trace:
        enabled: true

注意點:為了實時更新,必須加上@RefreshScope

配置中心進行bus refresh
在這裡插入圖片描述
訂閱的客戶端都進行實時更新:
在這裡插入圖片描述

程式碼例子下載:github程式碼例子下載

10、官方參考手冊和其它資料