SpringCloudStream
框架学习笔记(2020.10.10)
前言: (官网)
CloudStream
是什么? 为什么需要学习使用? 能做什么? 能解决什么问题?官网翻译:
Spring Cloud Stream是一个框架,用于构建与共享消息传递系统连接的高度可扩展的事件驱动型微服务。
该框架提供了一个灵活的编程模型,该模型建立在已经建立并熟悉的Spring习惯用法和最佳实践的基础上,包括对持久性pub / sub语义,使用者组和有状态分区的支持。
网上看到的一句话理解:
屏蔽底层消息中间件的差异,降低切换成本,统一消息的编程模型
目前仅支持:
RabbitMQ
、Apache Kafka
Spring Cloud Stream的核心构建块是: ()
- Destination Binders:负责与外部消息传递系统集成的组件。
- Destination Bindings:外部消息传递系统和应用程序之间提供的消息的生成者和消费者(由目标绑定程序创建)之间的桥梁。
- Message:生产者和消费者使用的规范数据结构,用于与目标绑定程序(以及通过外部消息传递系统进行的其他应用程序)进行通信。
Stream
就是通过Binder
绑定器作为中间层实现了应用程序与中间件的隔离:流程变成了, 生产者输出消息到绑定层, 由绑定层在转发到具体的中间件, 消息的消费也是由中间件到绑定层输入到具体的消费者。
这样做的好处在于
API
一样, 可以简单的切换中间件 (目前只支持2种)。核心概念:
Barista接口
:Barista接口是定义来作为后面类的参数,这一接口定义来通道类型和通道名称,通道名称是作为配置用,通道类型则决定了app会使用这一通道进行发送消息还是从中接收消息。通道接口如何定义:
@Output
:输出注解,用于定义发送消息接口
@Input
:输入注解,用于定义消息的消费者接口
@StreamListener
:用于定义监听方法的注解使用Spring Cloud Stream 非常简单,只需要使用好这3个注解即可
下面进行
RabbitMQ绑定器
快速入门。
1.0 生产者模块/引入依赖 (官网)
前提已经搭建好
RabbitMQ
环境并启动。要使用
RabbitMQ
绑定器,可以通过使用以下Maven坐标将其添加到Spring Cloud Stream应用程序中:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
或者,您可以使用Spring Cloud Stream
RabbitMQ
Starter,如下所示: (这里使用这个)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
1.1 编写application.yml
配置文件 (其他绑定属性)
spring:
application:
name: cloud-stream-provider
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
myRabbit: # 表示自定义的名称,用于于binding整合
type: rabbit # 消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
bindings: # 服务的整合处理
myOutput: # 表示自定义名字是一个通道的名称
destination: studyExchange # 表示要使用的Exchange名称定义
content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
binder: myRabbit # 设置要绑定的消息服务的具体设置
group: my-Queue-1 # group相当于RabbitMQ中Queue的名称
1.2 定义消息绑定接口 (单个建议使用默认)
Spring Cloud Stream已经为典型的消息交换合同提供了绑定接口:
Sink
与Source
public interface Sink { String INPUT = "input"; @Input(Sink.INPUT) SubscribableChannel input(); } public interface Source { String OUTPUT = "output"; @Output(Source.OUTPUT) MessageChannel output(); }
由于我定义的通道名称不是默认的:
output
所以我需要自定义接口。
public interface MyBinding {
String MY_OUTPUT = "myOutput";
@Output(MyBinding.MY_OUTPUT)
MessageChannel myOutput();
}
1.3 使用MessageChannel
发送消息
@EnableBinding(MyBinding.class) //定义消息的推送管道
public class MyMessage {
@Autowired
private MessageChannel output; // 消息发送管道
public boolean send()
{
// 发送UUID
String serial = UUID.randomUUID().toString();
// 构建消息Message
Message<String> message = MessageBuilder.withPayload(serial).build();
// 发送
boolean send = output.send(message);
return send;
}
}
2.0 消费者模块/引入依赖
引入的依赖和生产者一样。
2.1 编写application.yml
配置文件 (其他消费配置属性)
几乎一样
spring:
application:
name: cloud-stream-consumer
cloud:
stream:
binders:
myRabbit:
type: rabbit
environment:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
bindings:
myInput: # 不同点, 表示这个是个输入通道(接收消息)
destination: studyExchange # 不同点, 使用相同的Exchange名称
content-type: application/json
binder: myRabbit
group: my-Queue-1
rabbit:
bindings:
myInput:
consumer:
acknowledgeMode: MANUAL # 是否支持签收,签收模式:手工签收,Default: AUTO.
recoveryInterval: 3000 # 服务重连,Default: 5000.
# 是否持久化订阅,仅在group已设置的情况下有效,Default: true.
durableSubscription: true
maxConcurrency: 5 # 最大监听数,Default: 1.
2.2 定义消息绑定接口 (单个建议使用默认)
Spring Cloud Stream已经为典型的消息交换合同提供了绑定接口:
Sink
与Source
由于我定义的通道名称不是默认的:
input
所以我需要自定义接口。
public interface MyBinding {
String MY_INPUT = "myInput";
@Output(MyBinding.MY_INPUT)
MessageChannel myInput();
}
2.3 使用@StreamListener
注解监听消息进行消费
@Component
@EnableBinding(MyBinding.class) //定义消息的接收管道
public class ReceiveMessageListenerController
{
@Value("${server.port}")
private String serverPort;
@StreamListener(MyBinding.MY_INPUT)
public void input(Message<String> message)
{
System.out.println("消费者,----->接受到的消息: "+message.getPayload()+"\t port: "+serverPort);
}
}
1