在微服务架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题来连接各个微服务实例,它广播的消息会被所有在注册中心的微服务实例监听和消费,也称消息总线。
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包 而已