部分内容摘自 Spring Cloud 官方文档中文版
本文源码地址 https://github.com/Wyxwx/spring-cloud-bus
目录
整合 Spring Cloud Config(RabbitMQ)
消息总线简介
将分布式系统的节点与轻量级消息代理链接。用于广播状态更改(例如配置更改)或其他管理指令。一个关键的想法是,总线就像一个分布式执行器,用于扩展的 Spring Boot 应用程序,但也可以用作应用程序之间的通信通道。目前唯一的实现是使用AMQP代理作为传输,但是相同的基本功能集(还有一些取决于传输)在其他传输的路线图上。
注:目前 Spring Cloud Bus 仅支持 RabbitMQ 和 Kafka 作为中间件
Kafka 基于 ZooKeeper
RabbitMQ 是以 AMQP 协议实现的,所以可以跨平台实现
整合 RabbitMQ 基本使用
代码地址:https://github.com/Wyxwx/spring-cloud-bus
准备工作:
下载安装 Erlang(配置环境) 及 RabbitMQ
创建一个 Spring Boot 工程
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
编写配置文件 application.properties
spring.application.name=rabbitmq-hello
spring.rabbitmq.host=localhost
# web 端口:15672
# 此处端口:5672
spring.rabbitmq.port=5672
# 在 rabbitmq 管理页面创建的用户和密码
spring.rabbitmq.username=wyx
spring.rabbitmq.password=123456
server.port=8000
新建一个 RabbitConfig 类,用来配置一个简单的消息队列
注:此处的 Queue 是 org.springframework.amqp.core 下的类
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Bean
public Queue helloQueue(){
return new Queue("hello");
}
}
创建消息生产者类 Sender
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class Sender {
// 可以直接向某一个消息队列发送消息
@Autowired
private AmqpTemplate template;
public void send(){
String msg = "Hello RabbitMQ: " + new Date();
System.out.println("Sender: " + msg);
// 向一个名为 hello 的消息队列中发送消息。
this.template.convertAndSend("hello", msg);
}
}
创建消息消费者 Receiver
监听队列 hello 的消息
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(queues = "hello")
public class Receiver {
/**
* 处理接收到的消息
*/
@RabbitHandler
public void process(String msg){
System.out.println("Receiver: " + msg);
}
}
创建一个 HelloController 来执行逻辑
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private Sender sender;
@RequestMapping("/send")
public void send() {
sender.send();
}
}
运行启动类,访问 http://localhost:8000/send
可以看到控制台打印如下,即成功
整合 Spring Cloud Config(RabbitMQ)
在该工程下新建一个名为 config-server 的 Module
依赖
修改配置文件 application.properties
spring.application.name=config-server
server.port=8880
spring.cloud.config.server.git.uri=https://github.com/Wyxwx/springCloud-config
spring.cloud.config.server.git.search-paths=configRepo
spring.cloud.config.server.git.username=wyx
spring.cloud.config.server.git.password=123456
# Spring 2.x 中关于 RabbitMQ 的配置
# 将原来自动配置的端点 /bus/refresh 改为手动配置
management.endpoints.web.exposure.include=bus-refresh
修改启动类,添加 @EnableConfigServer 注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
继续再该工程下添加两个 Module,分别为 config-client、config-client2
这两个工程的内容除了配置文件的端口外,其他都相同
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
修改配置文件 bootstrap.properties
spring.application.name=my
#spring.cloud.config.profile=another
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:8880/
# config-client2 的端口改为 8889
server.port=8888
spring.rabbitmq.username=wyx
spring.rabbitmq.password=123456
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
management.endpoints.web.exposure.include=bus-refresh
新建一个 FromController
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;
// RabbitMQ 端口配置需要
@RefreshScope
@RestController
public class FromController {
@Value("${tag}")
private String tag;
@RequestMapping("/from")
public String from(){
return this.tag;
}
}
依次启动 config-server、config-client、config-client2
可以在两个客户端的日志处看到有端点 /actuator/bus-refresh 即 spring 1.5 版本中的 /bus/refresh
此时访问 http://localhost:8888/from
接下来改变 git 仓库中的配置
然后用任一客户端访问 /actuator/bus-refresh 端点
此时再次访问 http://localhost:8888/from
访问另一客户端可以发现,另一客户端的配置也已改变 http://localhost:8889/from
注:在实际运行环境中,可以在 config-server 中引入 Spring Cloud Bus,将刷新请求发送至服务端来将消息发送给各个客户端
可以在发送刷新请求时根据 destination 参数指定刷新范围
方式:/actuator/bus-refresh?destination={实例名}
实例名:${spring.cloud.client.hostname}:${spring.application.name}:${server.port}
即 实例名 = ip:服务名:端口号