Bus 二
pom.xml:上面三个是必须的
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.3.5.RELEASE</version> </dependency> <!--用来刷新配置--> <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> <version>1.3.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
配置:
server.port=7005 #必须和配置的服务名一致 spring.application.name=cloud-config #需要加载的配置环境 spring.cloud.config.profile=dev #拉取的分支 spring.cloud.config.label=master spring.cloud.config.discovery.enabled=true spring.cloud.config.discovery.service-id=microservice-config-server eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ #密码因为在server做了密码设置 spring.cloud.config.username=user spring.cloud.config.password=37cc5635-559b-4e6f-b633-7e932b813f73 #RabbitMQ的配置 spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.publisher-confirms=true spring.rabbitmq.virtual-host=/ #将权限关闭 访问监控端口需要权限 在后面刷新配置的时候使用 management.security.enabled=false #快速失败 优先去拉取配置 如果拉取不到直接失败 spring.cloud.config.fail-fast=true
启动类:
package com.yjp.configclient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient @SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } }
启动两个Conf-Client(除了端口号,其他的一样),修改在git上面的配置文件,通过post请求向其中一个Client发送请求http://localhost:7005/bus/refresh 然后访问两个Controller,配置都会更新
原理:
从图中就可以看的很清楚了,当我们向一个微服务发送了post请求,这个微服务就会向消息总线中发送消息,然后通过消息总线同步到别的微服务中。
指定刷新范围 customers服务名,9000端口号,可以具体的配置到一个服务上面。将customers的服务都更新
/bus/refresh?destination= customers:9000或者/bus/refresh?destination= customers:**
使用kafka只需要将RabbitMQ的jar包换为kafka的就可以了
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
不管是使用RabbitMQ还是kafka都是需要在本机先启动的。
优化:
在之前的架构中, 服务的配置更新需要通过向具体服务中的某个实例发送请求, 再触发对整个服务集群的配置更新。 虽然能实现功能, 但是这样的结果是, 我们指定的应用实例会不同千集群中的其他应用实例, 这样会增加集群内部的复杂度, 不利于将来的运维工作。 比如, 需要对服务实例进行迁移, 那么我们不得不修改Web Hook中的配置等。 所以要尽可能地让服务集群中的各个节点是对等的。
我们主要做了以下这些改动:
1.在ConfigServer中也引入SpringCloud Bus, 将配置服务端也加入到消息总线中来。
2. /bus/refresh请求不再发送到具体服务实例上, 而是发送给Config Server, 并通过destination参数来指定需要更新配置的服务或实例(都需要更新可以不加)。通过上面的改动,我们的服务实例不需要再承担触发配置更新的职责。 同时, 对于Git的触发等配置都只需要针对ConfigServer即可, 从而简化了集群上的一些维护工作。
在使用kafka的时候:
修改消息总线使用的队列或主题名称:spring.cloud.bus.destination=
设置应用是否要连接到消息总线上:spring.cloud.bus.enabled=
跟踪总线事件:
我们可以获取到Bus事件传播的的细节,可以跟踪总线事件。
设置:spring.cloud.bus.trace.enabled=true
在访问完refresh端点后,访问/trace端点就可以了。
我们可以查看 spring-cloud-starter-bus-amqp 和 spring-cloud-starter-bus-kafka的依赖,可以看到它们分别依赖了spring-cloud-starter-streamrabbit和spring-cloud-starter-stream-kafka,真正实现与这些消息代理进行交互操作的是Spring Cloud Stream。所以, 我们在本章中使用的所有Spring Cloud Bus的消息通信基础实际上都是由Spring Cloud Stream所提供的。 一定程度上, 我们可以将Spring Cloud Bus理解为是一个使用了Spring Cloud Stream构建的上层应用。由于Spring Cloud Stream为了让开发者屏蔽各个消息代理之间的差异, 将来能够方便地切换不同的消息代理而不影响业务程序, 所以在业务程序与消息代理之间定义了 一层抽象, 称为绑定器(Binder)。
我们在整合RabbitMQ和Kafka的时候就是分别引入了它们各自的绑定器实现,可以回想一下之前的实现内容, 不论使用RabbitMQ还是Kafka实现, 在程序上其实没有任何变化,变化的只是对绑定器的配置。所以,当我们要在其他消息代理上使用Spring CloudBus消息总线时, 只需要去实现 一套指定消息代理的绑定器即可。
这些都是书上面的一些总结,其实当我们使用Bus总线的时候,仅仅只是需要一个Jar而已。就可以达到我们动态刷新的效果了。也可以自己去异步实现,在微服务和service之间通过消息监听的方式获取到配置,然后在进行刷新。
努力吧,皮卡丘。