在微服務架構中,通常會使用輕量級的消息代理來構建一個共用的消息主題來連接各個微服務實例,它廣播的消息會被所有在注冊中心的微服務實例監聽和消費,也稱消息總線。
SpringCloud中也有對應的解決方案,SpringCloud Bus 將分布式的節點用輕量的消息代理連接起來,可以很容易搭建消息總線,配合SpringCloud config 實現微服務應用配置信息的動態更新。
消息總線其實通過消息中間主題模式,他使用廣播消息的機制被所有在注冊中心微服務實例進行監聽和消費。以廣播形式將消息推送給所有注冊中心服務列表
消息代理屬於中間件。設計代理的目的就是為了能夠從應用程序中傳入消息,並執行一些特別的操作。開源產品很多如ActiveMQ、Kafka、RabbitMQ、RocketMQ等
目前springCloud僅支持RabbitMQ和Kafka。本文采用RabbitMQ實現這一功能。
圖示:
通過客戶端去通知每個服務 更新配置文件
升級 通過消息總線的方式:
消息總線框架底層是MQ實現的,引入相應的jar包,底層框架實現好了,每個服務里面引入了相應的jar包后,自動創建隊列 綁定交換機等等
配置文件的應用場景就很符合。
環境搭建:
每個服務對於分布式配置中心來說是 client端
配置文件環境 dev test pre prd
配置文件命名規范 client服務名稱(注冊中心名稱)-版本.yml
創建好這個文件
互聯網項目場景中的配置文件 不是存放在本底的 是存放在遠程服務器
寫在本地 需要重啟服務器 !!
下面開始搭建分布式配置中心 SpringCloude 組件 Config
1、配置文件存放在git 或者 svn
2、搭建分布式配置中心服務
3、客戶端讀取分布式配置中心服務
configServer端:
配置文件:
pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.toov5</groupId> <artifactId>SpringCloud-eureka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <!-- 管理依賴 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.M7</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--SpringCloud eureka-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- hystrix斷路器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> <!-- 注意: 這里必須要添加, 否者各種依賴有問題 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
yml:
###服務注冊到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
application:
####注冊中心應用名稱
name: config-server
cloud:
config:
server:
git:
###git環境地址
uri: https://gitee.com/toov5/distributed_configuration_file.git
####搜索目錄
search-paths:
- Test
####讀取分支
label: master
####端口號
server:
port: 8888
啟動:
package com.toov5.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient @EnableConfigServer public class AppServerConfig { public static void main(String[] args) { SpringApplication.run(AppServerConfig.class, args); } }
啟動Eureka后啟動 configServer
訪問地址: http://127.0.0.1:8888//appConfig-dev.yml
Client端:
pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.toov5</groupId> <artifactId>SpringCloud_config_client</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <!-- SpringBoot整合Web組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</artifactId> <version>2.0.2.RELEASE</version> </dependency> <!-- SpringBoot整合eureka客戶端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.0.2.RELEASE</version> </dependency> </dependencies> <!-- 注意: 這里必須要添加, 否者各種依賴有問題 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
Controller:
package com.toov5.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @Value("${userAge}") //配置中心的 我們這個字段在本地沒有配置 private String userAge; @RequestMapping("/getUserAge") public String getUerAge() { return userAge; } }
啟動類:
package com.toov5.controller; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class AppClientConfig { public static void main(String[] args) { SpringApplication.run(AppClientConfig.class, args); } }
yml:
對應命名規范去配置!
spring: application: ####注冊中心應用名稱 對應命名規范去配置 appConfig-dev.yml name: appConfig cloud: config: ####讀取后綴 profile: dev #對應命名規范去配置 ####讀取config-server注冊地址 discovery: service-id: config-server ##服務的名字 enabled: true ##### eureka服務注冊地址 eureka: client: service-url: defaultZone: http://localhost:8100/eureka server: port: 8882
訪問結果:
如果此時 修改了配置文件,刷新出來的還是不變的!緩存到當前的jvm中了 重啟client端就OK了 可以做定時刷新
升級: 不重啟服務器自動刷新
1.手動通知刷新單個jvm值
2. 消息總線通知整個微服務刷新
1. 通過監控中心
手動actuator端點刷新數據
引入mavn 到client
<!-- actuator監控中心 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
yml
開啟監控服務
management:
endpoints:
web:
exposure:
include: "*"
此時的yml:
spring:
application:
####注冊中心應用名稱 對應命名規范去配置 appConfig-dev.yml
name: appConfig
cloud:
config:
####讀取后綴
profile: dev #對應命名規范去配置
####讀取config-server注冊地址
discovery:
service-id: config-server ##服務的名字
enabled: true
##### eureka服務注冊地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
server:
port: 8882
#開啟所有服務端點權限
management:
endpoints:
web:
exposure:
include: "*"
然后Controller 加上 刷新的注解 @RefreshScope
package com.toov5.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class IndexController { @Value("${userAge}") //配置中心的 我們這個字段在本地沒有配置 private String userAge; @RequestMapping("/getUserAge") public String getUerAge() { return userAge; } }
對應的值 不用重啟就可以刷新了
啟動后:修改git的文件值
發送post請求:
http://127.0.0.1:8882/actuator/refresh
有個缺點,如果configClient做個集群
如要去刷新每個 服務的值! postman 搞一遍
升級:這樣就需要消息總線了!
SpringCloud整合rabbitmq 和 kafka
本文采用的是rabbitmq去作為案例講解:
rabbitmq 的加交換機有四種: fanout direct topic head
在這個體系中 微服務有多少個 就會在MQ中創建多少個隊列,當手動刷新一個服務時候,會通過rabbitmq 去把消息同時發給交換機,然后通過交換機發送給其他的微服務 。
環境的搭建:
引入maven: bus的核心jar包
client和servler端都需要引入
<!--核心jar包 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <!-- actuator監控中心 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
如果報錯添加:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-bus-parent</artifactId> <version>2.0.0.RC2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
客戶端需要yml開啟bus刷新:client端
###開啟bus刷新 management: endpoints: web: exposure: include: bus-refresh
同時需要配置mq的連接信息:
此時的client端yml:
spring:
rabbitmq:
####連接地址
host: 192.168.91.6
####端口號
port: 5672
####賬號
username: admin
####密碼
password: admin
### 地址 主機獨立的virtualhost
virtual-host: /admin_toov5
application:
####注冊中心應用名稱 對應命名規范去配置 appConfig-dev.yml
name: appConfig
cloud:
config:
####讀取后綴
profile: dev #對應命名規范去配置
####讀取config-server注冊地址
discovery:
service-id: config-server ##服務的名字
enabled: true
##### eureka服務注冊地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
server:
port: 8882
###開啟bus刷新
management:
endpoints:
web:
exposure:
include: bus-refresh
server:
###服務注冊到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
rabbitmq:
####連接地址
host: 192.168.91.6
####端口號
port: 5672
####賬號
username: admin
####密碼
password: admin
### 地址 主機獨立的virtualhost
virtual-host: /admin_toov5
application:
####注冊中心應用名稱
name: config-server
cloud:
config:
server:
git:
###git環境地址
uri: https://gitee.com/toov5/distributed_configuration_file.git
####搜索目錄
search-paths:
- Test
####讀取分支
label: master
####端口號
server:
port: 8888
###開啟bus刷新
management:
endpoints:
web:
exposure:
include: bus-refresh
底層會幫助創建 mq隊列 主題 兩個client 一個 server
訪問一個接口 8882 的,其他的服務8883也會跟着改了!
http://127.0.0.1:8882/actuator/bus-refresh
就是玩了個 yml+jar包 而已