快捷搜索:  汽车  科技

spring cloud的client详解:SpringCloudBus使用说明详解

spring cloud的client详解:SpringCloudBus使用说明详解访问Controller接口,查看数据是否更新,分别调用serviceA和serviceB两个接口@Autowired private EnvironmentManager env ; @GetMapping("/index") public Object index() { return "akf = " env.getProperty("akf") ; }调用接口:/mgr/bus-env分别启动serviceA,serviceB,注册中心如下:RabbitMQ会自动创建一个用于消息传递的队列,该队列是排他的,只要有一个服务创建了其它的就不会创建,且是自动删除的,如果服务关闭队列会自动删除。任意调用其中一个服务的/mgr/bus-env接口,以POST的方式传递key/value数据即可。

环境:Springboot2.3.12.RELEASE Spring Cloud Hoxton.SR12 Spring Cloud Alibaba 2.2.5.RELEASE


简介

Spring Cloud Bus通过一个轻量级消息代理将分布式系统的节点连接起来。然后使用该代理来广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,总线就像一个分布式执行器,用于按比例扩展的Spring Boot应用程序。不过,它也可以用作应用程序之间的通信通道。该项目提供了对应AMQP 或 Kafka 的starter 作为传输的工具。

环境配置

新建两个工程serviceA,serviceB

<properties> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.5.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

server: port: 9100 --- spring: cloud: nacos: username: dev password: 123456 discovery: enabled: true serverAddr: localhost:8848 namespace: 7205e694-ac51-4ac1-bbe9-87c28689b88a --- spring: application: name: serviceA --- spring: RabbitMQ: host: localhost virtual-host: bus port: 5672 username: xxx password: xxx --- management: server: port: 8888 endpoint: health: show-details: always shutdown: enabled: true endpoints: web: basePath: /mgr exposure: include: '*' #暴露所有的Endpoint

serviceB的配置修改端口和spring.application.name 其它的都一样。

分别启动serviceA,serviceB,注册中心如下:

spring cloud的client详解:SpringCloudBus使用说明详解(1)

RabbitMQ会自动创建一个用于消息传递的队列,该队列是排他的,只要有一个服务创建了其它的就不会创建,且是自动删除的,如果服务关闭队列会自动删除。

spring cloud的client详解:SpringCloudBus使用说明详解(2)

Bus Env端点的应用

任意调用其中一个服务的/mgr/bus-env接口,以POST的方式传递key/value数据即可。

@Autowired private EnvironmentManager env ; @GetMapping("/index") public Object index() { return "akf = " env.getProperty("akf") ; }

调用接口:/mgr/bus-env

spring cloud的client详解:SpringCloudBus使用说明详解(3)

访问Controller接口,查看数据是否更新,分别调用serviceA和serviceB两个接口

serviceA

spring cloud的client详解:SpringCloudBus使用说明详解(4)

serviceB

spring cloud的client详解:SpringCloudBus使用说明详解(5)

实现原理:

public class BusAutoConfiguration implements ApplicationEventPublisherAware { protected static class BusEnvironmentConfiguration { // 事件监听器,专门用来处理EnvironmentChangeRemoteApplicationEvent事件 @Bean @ConditionalOnProperty(value = "spring.cloud.bus.env.enabled" matchIfMissing = true) public EnvironmentChangeListener environmentChangeListener() { return new EnvironmentChangeListener(); } @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Endpoint.class) protected static class EnvironmentBusEndpointConfiguration { @Bean @ConditionalOnAvailableEndpoint // 注册acutator端点 public EnvironmentBusEndpoint environmentBusEndpoint(ApplicationContext context BusProperties bus) { return new EnvironmentBusEndpoint(context bus.getId()); } } } } // bus-env端点定义 @Endpoint(id = "bus-env") // TODO: document public class EnvironmentBusEndpoint extends AbstractBusEndpoint { @WriteOperation public void busEnv(String name String value) { // TODO: document params Map<String String> params = Collections.singletonMap(name value); // 当调用/actuator/bus-env接口的时候会执行这里发布事件 publish(new EnvironmentChangeRemoteApplicationEvent(this getInstanceId() null params)); } } // 处理EnvironmentChangeRemoteApplicationEvent事件 public class EnvironmentChangeListener implements ApplicationListener<EnvironmentChangeRemoteApplicationEvent> { @Autowired private EnvironmentManager env; @Override public void onApplicationEvent(EnvironmentChangeRemoteApplicationEvent event) { Map<String String> values = event.getValues(); // 将数据添加到ENV中 for (Map.Entry<String String> entry : values.entrySet()) { this.env.setProperty(entry.getKey() entry.getValue()); } } }Bus Refresh 端点的应用

/actuator/busrefresh端点清除RefreshScope缓存并重新绑定@ConfigurationProperties。

在使用Nacos作为配置中心时,对于使用@ConfigurationProperties注解的类是无需手动调用/busrefresh接口进行刷新,系统会自动的刷新配置:

引入依赖:

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>

建立bootstrap.yml

spring: cloud: nacos: config: username: dev password: 123456 enabled: true serverAddr: localhost:8848 fileExtension: properties # group: HisGroup namespace: 7205e694-ac51-4ac1-bbe9-87c28689b88a timeout: 6000 shared-configs: - dataId: redis.properties group: common refresh: true

nacos新建配置

spring cloud的client详解:SpringCloudBus使用说明详解(6)

应用配置类

@Component @ConfigurationProperties(prefix="redis") public class RedisConfig { private String host ; public String getHost() { return host; } public void setHost(String host) { this.host = host; } }

接口测试

@Resource private RedisConfig redis ; @GetMapping("/redis") public Object redis() { return "redis = " redis.getHost() ; }

只要在nacos中修改了配置,这里的信息都会实时的更新。

将上面的RedisConfig修改如下:

@Component public class RedisConfig { @Value("${redis.host}") private String host ; }

去掉了@ConfigurationProperties注解

这时候在nacos中的配置,发现这个的配置信息不能够实时的更新。

接着做如下修改:

@Component @RefreshScope public class RedisConfig { @Value("${redis.host}") private String host ; }

添加了@RefreshScope注解,再次修改nacos配置,信息得到了实时的更新。

关于RefreshScope的实现原理查看《SpringCloud @RefreshScope实现原理原来这么简单?》

Bus Refresh实现原理:

public class BusRefreshAutoConfiguration { @Bean @ConditionalOnProperty(value = "spring.cloud.bus.refresh.enabled" matchIfMissing = true) @ConditionalOnBean(ContextRefresher.class) public RefreshListener refreshListener(ContextRefresher contextRefresher ServiceMatcher serviceMatcher) { return new RefreshListener(contextRefresher serviceMatcher); } @Configuration(proxyBeanMethods = false) @ConditionalOnClass(name = { "org.springframework.boot.actuate.endpoint.annotation.Endpoint" "org.springframework.cloud.context.scope.refresh.RefreshScope" }) protected static class BusRefreshEndpointConfiguration { @Bean @ConditionalOnAvailableEndpoint // 注册BusRefresh端点 public RefreshBusEndpoint refreshBusEndpoint(ApplicationContext context BusProperties bus) { return new RefreshBusEndpoint(context bus.getId()); } } } @Endpoint(id = "bus-refresh") // TODO: document new id public class RefreshBusEndpoint extends AbstractBusEndpoint { @WriteOperation // 注册刷新的事件,事件的处理是由上面的RefreshListener监听器处理 public void busRefresh() { publish(new RefreshRemoteApplicationEvent(this getInstanceId() null)); } }

在RefreshListener监听器中的核心就是调用ContextRefresher#refresh方法。

这里使用了Nacos后这个Bus就不需要了。

如果还是用于原始的Spring Cloud Config那么这个还是必须的(很久没有使用config了,应该没有变把)。

Bus ID应用

每个实例都有一个服务ID,其值可以用spring.cloud.bus.id设置,其值应该是一个以冒号分隔的标识符列表。默认值规则为:app:index:id

  • app:如果存在vcap.application.name 取该值,否则 spring.application.name
  • index:如果存在vcap.application.instance_index 取该值 否则按照下面的顺序spring.application.index local.server.port server.port。
  • id: 如果存在vcap.application.instance_id 否则生成随机值。

该spring.cloud.bus.id 有何用?

当执行:http://xxxx:port/mgr/bus-refresh 端点时会刷新所有的服务。如果执行下面接口:

http://xxxx:port/mgr/bus-refresh/serviceA:9100 那么只会刷新serviceA配置信息。其它的会被忽略。

也可以使用通配符的方式:

http://xxxx:port/mgr/bus-env/serviceA:**

完毕!!!

求个关注

Spring Cloud Sentinel 基础配置

Spring Cloud Sentinel 熔断降级

Spring Cloud Sentinel 流控限流

Spring Cloud Nacos 开启权限验证

Spring Cloud Gateway应用详解1之谓词

在Spring Cloud 中你还在使用Ribbon快来试试Load-Balancer

SpringCloud Nacos 整合feign

SpringCloud Alibaba 之 Nacos 服务

Spring Cloud Sentinel整合Feign

Spring Cloud 中断路器 Circuit Breaker的应用

spring cloud的client详解:SpringCloudBus使用说明详解(7)

spring cloud的client详解:SpringCloudBus使用说明详解(8)

spring cloud的client详解:SpringCloudBus使用说明详解(9)

spring cloud的client详解:SpringCloudBus使用说明详解(10)

猜您喜欢: