一、什么是Spring Cloud Stream?
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems.
The framework provides a flexible programming model built on already established and familiar Spring idioms and best practices, including support for persistent pub/sub semantics, consumer groups, and stateful partitions.
简而言之:其实一款易于扩展的消息驱动框架,用于微服务之间消息的传递,遵循发布订阅模式、支持分组、分区。
二、为什么学习Spring Cloud Stream?
当下流行的四大MQ(RocketMQ、RabbitMQ、ActiveMQ、Kafka),各有优势,有时面对复杂且变化的业务需求,可能面临随时切换MQ的需求,随之带来的是代码的更改变动,而Spring Cloud Stream就是解决这一问题的,其统一了编程模型,各个MQ均为该框架的实现层,屏蔽了底层MQ之间的差异,业务代码与MQ解耦,达到了随时切换MQ的目的。
三、框架组件
四、踩坑指南
坑1. 需要注意的是,最好不要自定义输入输出在同一个类里面。这样,如果我们只调用生产者发送消息。会导致提示Dispatcher has no subscribers for channel。并且会让我们发送消息的次数莫名减少几次。详细情况可以查看gihub官方issue,也给出的这种解决方法 官方解决方式
坑2. stream生成的exchang默认是topic模式。就是按照前缀匹配,发送消息给对应的队列。
*(星号):可以(只能)匹配一个单词
#(井号):可以匹配多个单词(或者零个)
fanout:广播模式,发送到所有的队列
direct:直传。完全匹配routingKey的队列可以收到消息。
坑3. 默认消息异常之后,都会往死消息队列里面写,然而异常是放到一个header里面去的。默认消息队列支持的最大frame_max 是128kb,超过这个大小,服务器就主动给你关闭连接,然后把你的消息会不断的重试。
坑4. @Output对MessageChannel,@Input对应SubscribableChannel 。
坑5. stream的destination对应生成rabbitmq的exchange。加上了group后,例如destination:wx-consumer,group:queue。那么经过stream后队列名称会变成wx-consumer.queue。如果使用group对应的是持久化队列,不会被rabbitmq删除。
五、高级特性
1、消息分组
通常在生产环境,我们的每个服务都不会以单节点的方式运行在生产环境,当同一个服务启动多个实例的时候,这些实例都会绑定到同一个消息通道的目标主题(Topic)上。默认情况下,当生产者发出一条消息到绑定通道上,这条消息会产生多个副本被每个消费者实例接收和处理,但是有些业务场景之下,我们希望生产者产生的消息只被其中一个实例消费,这个时候我们需要为这些消费者设置消费组来实现这样的功能。
2、消息分区
有一些场景需要满足, 同一个特征的数据被同一个实例消费, 比如同一个id的传感器监测数据必须被同一
个实例统计计算分析, 否则可能无法获取全部的数据。又比如部分异步任务,首次请求启动task,二次
请求取消task,此场景就必须保证两次请求至同一实例.
3、死信队列(DLQ)
消费失败的消息存入一个指定的队列,待程序Bug修复或网络恢复后,之后再进行消息的处理,这个存储消费失败的消息的队列就叫死信队列(死掉了的信息)。