springCloud -- 中級篇(2)

本系列筆記涉及到的代碼在GitHub上,地址:https://github.com/zsllsz/cloud

本文涉及知識點:

  • 服務(wù)配置中心之config;

  • 服務(wù)消息總線之bus(會用到rabbitmq);


歡迎大家關(guān)注我的公眾號 javawebkf,目前正在慢慢地將簡書文章搬到公眾號,以后簡書和公眾號文章將同步更新,且簡書上的付費文章在公眾號上將免費。


一、服務(wù)配置中心之springCloud Config

1、是什么?
springCloud學到現(xiàn)在,已經(jīng)新建了十四五個module,每個module都有yml,不方便管理,所以配置中心就應(yīng)運而生了。我們可以把微服務(wù)相同的配置抽到配置中心里面去,比如數(shù)據(jù)源的配置。假如某一天需要換數(shù)據(jù)源,只需要修改配置中心的配置即可,而不用每個微服務(wù)的yml都去改。沒錯,以前學的zookeeper也有這功能。spring config 分為服務(wù)端和客戶端兩部分,服務(wù)端也稱分布式配置中心,是一個獨立的微服務(wù)應(yīng)用;客戶端則是通過指定的配置中心來管理應(yīng)用資源以及業(yè)務(wù)相關(guān)的配置內(nèi)容,并在啟動的時候從配置中心加載配置信息。

2、能干嘛?

  • 集中管理配置文件
  • 不同環(huán)境不同配置,動態(tài)化的配置更新,分環(huán)境部署
  • 運行期間動態(tài)調(diào)整配置
  • 配置發(fā)生變化時不需要重啟即可使用新的配置
  • 將配置信息以rest接口形式暴露

3、config服務(wù)端配置與測試:

  • 首先在github上新建一個倉庫,然后新建一個config-dev.yml文件,內(nèi)容隨意,如下圖:
github倉庫
  • 新建名為cloud-config-center-3344的module;
  • pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator </artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- eureka client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
  • yml:
server:
  port: 3344
  
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri: git@github.com:zsllsz/springcloud-config.git # github倉庫地址
          search-paths:
          - springcloud-config # 搜索目錄
      label: master # 讀取的分支
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  • 主啟動:
@SpringBootApplication
@EnableConfigServer
public class ConfigMain3344 {

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

啟動后7001注冊中心,然后啟動3344,訪問http://localhost:3344/master/config-dev.yml,看看能否讀取到config-dev.yml中的內(nèi)容:

讀取配置成功

如果讀取的是master,那么http://localhost:3344/master/config-dev.yml中的master可以省略,因為默認就是讀master;如果讀其他分支,比如dev,那就在配置中寫成dev,然后訪問的url將master換成dev即可。url還可以是這樣:http://localhost:3344/config/dev/master,這里表示讀取config-dev文件,分支為master。如果用lable表示分支,application表示文件名,profiles表示環(huán)境,那么url形式有如下幾種:

  • /lable/application-profile.yml
  • /application-profile.yml(只能讀master)
  • /application/profile/lable

4、config客戶端配置與測試:

  • 修改github上的config-dev.yml,將內(nèi)容改成符合yml文件格式的內(nèi)容,比如這樣:
  • 新建名為cloud-config-client-3355的module;
  • pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator </artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- eureka client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  • bootstrap.yml:注意,以前的yml是application.yml,它是用戶級的資源配置,現(xiàn)在要新建一個bootstrap.yml,這個是系統(tǒng)級的,優(yōu)先級更高。
server:
  port: 3355
  
spring:
  application:
    name: config-client
  # config 配置
  cloud:
    config:
      label: master # 分支
      name: config # 文件名
      profile: dev # 環(huán)境
      # 以上三個組合起來就是表示讀取master上的config-dev.yml
      uri:
      - http://localhost:3344 # 配置中心地址
      
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  • 主啟動:
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(ConfigClientMain3355.class, args);
    }
}
  • controller:
@RestController
@RequestMapping("/config")
public class ConfigController {

    @Value("${config.info}")
    private String configInfo;
    
    @GetMapping("/info")
    public String getInfo() {
        return configInfo;
    }
}

我們在bootstrap.yml中配置了配置中心3344的訪問路徑,3344又會去github上找config-dev.yml,這個文件上又有config.info,所以在這個controller直接用@Value注解可以獲取。最后訪問這個controller,就可以在瀏覽器輸出config-dev.yml中config.info的信息,如下:

成功獲取配置信息

5、動態(tài)刷新問題:
加入github上的config-dev.yml內(nèi)容修改了,3344因為是直接連接github去獲取配置信息的,所以可以獲取最新信息;但是3355就必須重啟才能獲取最新內(nèi)容,這不方便。接下來配置動態(tài)刷新,即不用重啟也可以獲取最新配置:

  • 修改bootstrap.yml,加上如下配置:
# 暴露監(jiān)控端口
management:
  endpoints:
    web:
      exposure:
        include:
        - "*"
  • 在controller中加上@RefreshScope注解,如下:
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${config.info}")
    private String configInfo;
    
    @GetMapping("/info")
    public String getInfo() {
        return configInfo;
    }
}

這樣就搞定了,可以修改github上文件測試一下。經(jīng)實測訪問3355時還是沒有獲取到最新的配置內(nèi)容,其實還需要發(fā)送一個post請求刷新3355。執(zhí)行如下命令或者用postman請求都可:

curl -X POST "http://localhost:3355/actuator/refresh"


二、服務(wù)消息總線之springcloud bus

上面的config還有點麻煩的就是每次修改了github上的配置文件,想要客戶端也能立即讀取到最新的,需要發(fā)送一個post請求去刷新,總歸還是不方便。springcloud bus就是對springcloud config的增強,配合config使用,可以實現(xiàn)完全自動刷新,不需要再發(fā)post請求。

1、是什么?
搭配消息中間件使用,可以實現(xiàn)全局廣播通知。支持的消息中間件有RabbitMQ和Kafka。這個消息總線就像一個微信公眾號,一個個的微服務(wù)應(yīng)用就是訂閱了這個公眾號的人。微信公眾號發(fā)了推文,每個訂閱了的人都可以收到消息。這個springcloud bus就是這個公眾號,它會讓所有的服務(wù)都連接上來,配置文件有變化它會通知所有的服務(wù)。

2、RabbitMQ安裝與配置:

  • 由于RabbitMQ是Erlang語言開發(fā)的,所以要安裝Erlang,在centos上依次執(zhí)行以下命令即可安裝erlang:
yum install -y epel-release

wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm

rpm -Uvh erlang-solutions-1.0-1.noarch.rpm

yum install -y erlang

erl -version
# 導入密鑰
rpm --import https://www.rabbitmq.com/rabbitmq-release-signing-key.asc
# 安裝
yum install rabbitmq-server-3.8.3-1.el7.noarch.rpm
# 啟動
systemctl start rabbitmq-server
# 開啟圖形界面
rabbitmq-plugins enable rabbitmq_management

訪問ip:15672,即可訪問圖形界面。默認用戶名和密碼都為guest,但是這個只允許用localhost訪問,所以可以通過以下步驟新建用戶:

# 新建admin用戶,密碼也為admin
rabbitmqctl add_user admin admin
# 設(shè)置權(quán)限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 將admin設(shè)置為管理員用戶
rabbitmqctl set_user_tags admin administrator
# 重啟rabbitmq
systemctl restart rabbitmq-server

再次訪問ip:15672,用admin就可以登陸進去了。


rabbitmq啟動成功

3、springcloud bus的使用:

  • 新建名為cloud-config-client-3366的module;
  • pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator </artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- eureka client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  • bootstrap.yml:
server:
  port: 3366
  
spring:
  application:
    name: config-client
  # config 配置
  cloud:
    config:
      label: master # 分支
      name: config # 文件名
      profile: dev # 環(huán)境
      # 以上三個組合起來就是表示讀取master上的config-dev.yml
      uri:
      - http://localhost:3344 # 配置中心地址
      
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  
# 暴露監(jiān)控端點    
management:
  endpoints:
    web:
      exposure:
        include:
        - "*"
  • 主啟動類:
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3366 {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(ConfigClientMain3366.class, args);
    }
}
  • controller:
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/info")
    public String getInfo() {
        return configInfo;
    }
}

上面還沒用到bus。bus的通知思想有兩種,一種是廣播通知一個客戶端,進而通知到所有的客戶端;另一種是bus廣播通知服務(wù)端,服務(wù)端再通知所有的客戶端。一般情況使用第二種方式,即通知服務(wù)端,通知這個帶頭大哥即可。

下面開始使用springcloud bus

  • 修改3344的pom,新增如下依賴:
<!-- rabbitmq的支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  • 修改3344的yml,添加rabbitmq和bus相關(guān)配置,如下:
  # mq相關(guān)配置
  rabbitmq:
    host: 192.168.0.106
    port: 5672
    username: admin
    password: admin
# bus配置
management:
  endpoints:
    web:
      exposure:
        include:
        - 'bus-refresh'
  • 修改3355的pom,添加如下依賴:
<!-- rabbitmq的支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  • 修改3355的yml,添加如下配置:
  # mq相關(guān)配置
  rabbitmq:
    host: 192.168.0.106
    port: 5672
    username: admin
    password: admin
  • 3366和3355做一樣的修改。
  • 依次啟動7001,3344,3355,3366
  • 3344、3355和3366先訪問一次配置文件
  • 然后修改github上config-dev.yml的內(nèi)容
  • 3344此時可以訪問到修改后的內(nèi)容,因為它是帶頭大哥,直連github的,但是3355和3366此時還沒有獲取到最新的,因為RabbitMQ還沒進行廣播通知;
  • 執(zhí)行如下命令:
curl -X POST http://localhost:3344/actuator/bus-refresh
  • 刷新了帶頭大哥3344,叫它去通知3355和3366,再次去訪問3355和3366,發(fā)現(xiàn)也能獲取到最新的配置了。這就是bus和rabbitmq的功勞。如下圖,在rabbitmq上有一個topic叫springCloudBus,3344、3355和3366都訂閱了這個topic。當github上的配置發(fā)生改變時,我們就發(fā)一個post請求去通知3344,然后所有訂閱了該topic的服務(wù)都會收到通知去更新配置。
rabbitmq

4、定點通知:
上面演示的是通知所有訂閱了該topic的服務(wù),即3355和3366都通知到了。如果我想只通知3355,又當如何?發(fā)送post請求的時候指定發(fā)給誰就行了,公式就是:

curl -X POST http://localhost:3344/actuator/bus-refresh/客戶端的服務(wù)名:服務(wù)端口

服務(wù)名就是config客戶端的微服務(wù)名字,即3344和3355的spring.application.name,比如只通知3355,那么執(zhí)行如下命令即可:

curl -X POST http://localhost:3344/actuator/bus-refresh/config-client:3355
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容