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

smileNicky發表於2020-09-09

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: https://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: http://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方式,http://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 指定賬號密碼

執行如上命令後訪問:http://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、官方參考手冊和其它資料

相關文章