为何引入cloudStream
MQ(消息中间件):ActiveMQ、RabbitMQ、RocketMQ、Kafka ? 痛点
cloudStream 屏蔽底层的具体MQ类型 ,
什么是SpringCloudStream
- 官方定义,Spring Cloud Stream 是一个
消息驱动微服务
框架。 - 应用程序通过
inputs 或者 output
来与 Spring Cloud Stream 中binder
对象交互。 - 通过
我们配置
来 binding (绑定),而 Spring Cloud Stream 的binder 对象负责与消息中间件交互。 - 所以,我们甚至需要搞清楚如何与 Spring Cloud Stream 交互就可以方便地使用消息驱动的方式,
- 通过使用
Spring Integration
来连接消息代理中间件省市县消息事件驱动
。 - Spring Cloud Stream 为一些供应商的消息中间件提供了个性化的自动化配置实现,引用了
发布 - 订阅、消费组、分区
的三个核心概念。 - 目前支持
RabbitMQ 、Kafka
。
一句话
: 屏蔽消息中间件的差异,降低切换恒本,统一的消息编程模型
Stream官网地址 : https://spring.io/projects/spring-cloud-stream
中文文档地址:https://m.wang1314.com/doc/webapp/topic/20971999.html
设计思想
标准MQ
- 生产者/消费者之间靠
消息媒介
传递内容 :Message
- 消息必须走特定的
通道
:消息通道 MessageChannel
- 消息通道中的消息如何被消费, 谁来负责收发
处理
:消息通道 MesssageChannel 的子接口 SubscribableChannel , 由 MessageHandler 消息处理器所订阅
为什么用 Cloud Stream
比方说我们用到了 RabbitMQ 和 Kafka , 由于这两个消息中间件的架构上的不同, 像RabbitMQ
有 exchange, kafka
有 topic 和 Partitions 分区。
这些中间件的差异导致了我们实际开发项目中成了一定的困扰,我们如果用这两个消息队列其中的一种, 后面的后续业务需求,我们想往另一种消息队列进行迁移
,这个时候就无疑是灾难性
的,一大堆东西都要推到了重新做
,应为他跟我们的系统耦合
了,这时候 springcloud stream 给我们提供了一种解耦
的方式。
Stream 为什么可以统一底层的差异
在没有绑定器这个概念的情况下,我们的 Spring Boot 应用要直接与消息中间件进行信息交互的时候,由于各个消息中间件构建的初衷不同,他们的实现细节上会有较大的差异性
通过定义绑定器作为中间层,完美实现了 应用程序与消息中间件细节之间的隔离。
通过向应用程序暴露统一的Channel 通道,使得应用程序不需要在考虑各种不同的消息中间件实习先。
通过自定义绑定器 Binder 作为中间层, 实现了应用程序与消息中间件细节之间的隔离
Binder
INPUT : 对应于消费者 / OUTPUT : 对应于生产者
在没有绑定器这个概念的情况下, 我们的 Spring Boot 应用要直接与消息中间件进行消息交互的时候,由于各消息中间件构建的初衷不同,他们的实现细节上会有较大的差异,通过自定义绑定器作为中间层,完美的实现了应用程序与消息中间件细节之间的隔离。Stream 对消息中间件的进步一风筝,可以做到代码层面对中间件的
无感知,甚至于动态的切换中间件
(rabbitmq 切换为 kafka ), 是的微服务开发法的高度解耦
, 服务可以关注更多自己的业务流程。
通过自定义绑定器 Binder 做为中间层,实现了应用消息与中间消息细节之间的隔离。
Stream 中的消息通讯方式遵循了发布-订阅模式
Topic 主题进行广播
- 在RabbitMQ 就是 Exchange
- 在Kafka中就是 Topic
Spring Cloud Stream 标准流程套路
Binder :很方便的连接中间件,屏蔽差异
Channel : 通道,是队列 Queue
的一种抽象
,在消息通讯系统中
就是实现存储
和转发
的媒介,通过channel 队列进行配置
Source 和 Sink : 简单的理解为参照对象 Spring Cloud Stream 自身,从 Steam发布消息
就是输出
,接受消息
就是输入
编码API 和 常用注解
组成 | 说明 |
---|---|
Meddleware | 中间件,目前只支持 RabbitMQ 和Kafka |
Binder | Binder 是应用消息中间件之间的封装, 目前实现了 Kafka 和 RabbitMQ 的Binder 通过 Binder 可以很方便连接中间件,可以动态 的改变消息类型(对于 Kafka 的 topic , rabbitMQ 的 exchange), 这些都可以通过配置文件 来实现。 |
@Input | 注解标识输入通道,通过该输入通道接收 到的消息进入应用程序 |
@Output | 注解标识输入通道 ,发布的消息将通过通道离开应用程序 |
@StramListener | 监听 队列,用于消费者的队列的消息接受 |
@EnableBinding | 指信道 channel 和 exchange 绑定在一起。 |