干货|Spring Cloud Stream 体系及原理介绍

640?wx_fmt=jpeg

Photo by Med Badr Chemmaoui on Unsplash


Spring Cloud Stream 在 Spring Cloud 体系内用于构建高度可扩展的基于事件驱动的微服务,其目的是为了简化消息在 Spring Cloud 应用程序中的开发。


Spring Cloud Stream (后面以 SCS 代替 Spring Cloud Stream) 本身内容很多,而且它还有很多外部的依赖,想要熟悉 SCS,必须要先了解 Spring Messaging 和 Spring Integration 这两个项目,接下来,文章将从围绕以下三点进行展开:


  • 什么是 Spring Messaging;

  • 什么是 Spring Integration;

  • 什么是 SCS 体系及其原理;


Spring Messaging


Spring Messaging 是 Spring Framework 中的一个模块,其作用就是统一消息的编程模型。

  • 比如消息 Messaging 对应的模型就包括一个消息体 Payload 和消息头 Header:

640?wx_fmt=jpeg

 
 
  • 消息通道 MessageChannel 用于接收消息,调用 send 方法可以将消息发送至该消息通道中 :

640?wx_fmt=jpeg

 
 
消息通道里的消息如何被消费呢?
  • 由消息通道的子接口可订阅的消息通道 SubscribableChannel 实现,被 MessageHandler 消息处理器所订阅:

 
 
  • MessageHandler 真正地消费/处理消息:

 
 
Spring Messaging 内部在消息模型的基础上衍生出了其它的一些功能,如:

1. 消息接收参数及返回值处理:消息接收参数处理器 HandlerMethodArgumentResolver 配合 @Header, @Payload 等注解使用;消息接收后的返回值处理器 HandlerMethodReturnValueHandler 配合 @SendTo 注解使用;

2. 消息体内容转换器 MessageConverter

3. 统一抽象的消息发送模板 AbstractMessageSendingTemplate

4. 消息通道拦截器 ChannelInterceptor


Spring Integration


Spring Integration 提供了 Spring 编程模型的扩展用来支持企业集成模式(Enterprise Integration Patterns),是对 Spring Messaging 的扩展。

它提出了不少新的概念,包括消息路由 MessageRoute、消息分发 MessageDispatcher、消息过滤 Filter、消息转换 Transformer、消息聚合 Aggregator、消息分割 Splitter 等等。同时还提供了 MessageChannelMessageHandler 的实现,分别包括 DirectChannel、ExecutorChannel、PublishSubscribeChannelMessageFilter、ServiceActivatingHandler、MethodInvokingSplitter 等内容。

这里为大家介绍几种消息的处理方式:
  • 消息的分割:

640?wx_fmt=png

  • 消息的聚合:

640?wx_fmt=png


  • 消息的过滤:

640?wx_fmt=png

  • 消息的分发:

640?wx_fmt=png


接下来,我们以一个最简单的例子来尝试一下 Spring Integration:

这段代码解释为:

 

SubscribableChannel messageChannel =new DirectChannel(); // 1

messageChannel.subscribe(msg-> { // 2
 System.out.println("receive: " +msg.getPayload());
});

messageChannel.send(MessageBuilder.withPayload("msgfrom alibaba").build()); // 3


1. 构造一个可订阅的消息通道 messageChannel

2. 使用 MessageHandler 去消费这个消息通道里的消息;

3. 发送一条消息到这个消息通道,消息最终被消息通道里的 MessageHandler 所消费。

最后控制台打印出: receive: msg from alibaba

DirectChannel 内部有个 UnicastingDispatcher 类型的消息分发器,会分发到对应的消息通道 MessageChannel 中,从名字也可以看出来,UnicastingDispatcher 是个单播的分发器,只能选择一个消息通道。那么如何选择呢? 内部提供了 LoadBalancingStrategy 负载均衡策略,默认只有轮询的实现,可以进行扩展。

我们对上段代码做一点修改,使用多个 MessageHandler 去处理消息:

 
 

由于 DirectChannel 内部的消息分发器是 UnicastingDispatcher 单播的方式,并且采用轮询的负载均衡策略,所以这里两次的消费分别对应这两个 MessageHandler。控制台打印出:

 
 

既然存在单播的消息分发器 UnicastingDispatcher,必然也会存在广播的消息分发器,那就是 BroadcastingDispatcher,它被 PublishSubscribeChannel 这个消息通道所使用。广播消息分发器会把消息分发给所有的 MessageHandler

 
 

发送两个消息,都被所有的 MessageHandler 所消费。控制台打印:

 
 


Spring Cloud Stream


SCS与各模块之间的关系是:

  • SCS 在 Spring Integration 的基础上进行了封装,提出了 Binder, Binding, @EnableBinding, @StreamListener 等概念;

  • SCS 与 Spring Boot Actuator 整合,提供了 /bindings, /channels endpoint;

  • SCS 与 Spring Boot Externalized Configuration 整合,提供了 BindingProperties, BinderProperties 等外部化配置类;

  • SCS 增强了消息发送失败的和消费失败情况下的处理逻辑等功能。

  • SCS 是 Spring Integration 的加强,同时与 Spring Boot 体系进行了融合,也是 Spring Cloud Bus 的基础。它屏蔽了底层消息中间件的实现细节,希望以统一的一套 API 来进行消息的发送/消费,底层消息中间件的实现细节由各消息中间件的 Binder 完成。

Binder 是提供与外部消息中间件集成的组件,为构造 Binding提供了 2 个方法,分别是 bindConsumerbindProducer ,它们分别用于构造生产者和消费者。目前官方的实现有 Rabbit BinderKafka BinderSpring Cloud Alibaba 内部已经实现了 RocketMQ Binder

640?wx_fmt=png

从图中可以看出,Binding 是连接应用程序跟消息中间件的桥梁,用于消息的消费和生产。我们来看一个最简单的使用 RocketMQ Binder 的例子,然后分析一下它的底层处理原理:

  • 启动类及消息的发送:

 
 
  • 消息的接收:

 
 

这段代码很简单,没有涉及到 RocketMQ 相关的代码,消息的发送和接收都是基于 SCS 体系完成的。如果想切换成 RabbitMQ 或 Kafka,只需修改配置文件即可,代码无需修改。

我们来分析下这段代码的原理:


1. @EnableBinding 对应的两个接口属性 Source 和 Sink 是 SCS 内部提供的。SCS 内部会基于 Source 和 Sink 构造 BindableProxyFactory,且对应的 output 和 input 方法返回的 MessageChannel 是 DirectChannel。output 和 input 方法修饰的注解对应的 value 是配置文件中 binding 的 name。

 
 

配置文件里 bindings 的 name 为 output 和 input,对应 SourceSink 接口的方法上的注解里的 value:

 
 

2. 构造 CommandLineRunner,程序启动的时候会执行 CustomRunner run 方法。

3. 调用 Source 接口里的 output 方法获取 DirectChannel,并发送消息到这个消息通道中。这里跟之前 Spring Integration 章节里的代码一致。

  • Source 里的 output 发送消息到 DirectChannel 消息通道之后会被 AbstractMessageChannelBinder#SendingHandler 这个 MessageHandler 处理,然后它会委托给 AbstractMessageChannelBinder#createProducerMessageHandler 创建的 MessageHandler 处理(该方法由不同的消息中间件实现);

  • 不同的消息中间件对应的 AbstractMessageChannelBinder#createProducerMessageHandler 方法返回的 MessageHandler 内部会把 Spring Message 转换成对应中间件的 Message 模型并发送到对应中间件的 broker;

4. 使用 @StreamListener 进行消息的订阅。请注意,注解里的 Sink.input 对应的值是 "input",会根据配置文件里 binding 对应的 name 为 input 的值进行配置:

  • 不同的消息中间件对应的 AbstractMessageChannelBinder#createConsumerEndpoint 方法会使用 Consumer 订阅消息,订阅到消息后内部会把中间件对应的 Message 模型转换成 Spring Message;

  • 消息转换之后会把 Spring Message 发送至 name 为 input 的消息通道中;

  • @StreamListener 对应的 StreamListenerMessageHandler 订阅了 name 为 input 的消息通道,进行了消息的消费;

这个过程文字描述有点啰嗦,用一张图总结一下(黄色部分涉及到各消息中间件的 Binder 实现以及 MQ 基本的订阅发布功能):

640?wx_fmt=jpeg

SCS 章节的最后,我们来看一段 SCS 关于消息的处理方式的一段代码:

有没有发现这段代码跟 Spring MVC Controller 中接收请求的代码很像? 实际上他们的架构都是类似的,Spring MVC 对于 Controller 中参数和返回值的处理类分别是org.springframework.web.method.support.HandlerMethodArgumentResolverorg.springframework.web.method.support.HandlerMethodReturnValueHandler

Spring Messaging 中对于参数和返回值的处理类之前也提到过,分别是 org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverorg.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler

它们的类名一模一样,甚至内部的方法名也一样。


总结


640?wx_fmt=png

上图是 SCS 体系相关类说明的总结,关于 SCS 以及 RocketMQ Binder 更多相关的示例,可以参考 RocketMQ Binder Demos(Demos 地址:点击“阅读原文”,包含了消息的聚合、分割、过滤;消息异常处理;消息标签、SQL过滤;同步、异步消费等等。

下一篇文章,我们将分析消息总线(Spring Cloud Bus) 在 Spring Cloud 体系中的作用,并逐步展开,分析 Spring Cloud Alibaba 中的 RocketMQ Binder 是如何实现 Spring Cloud Stream 标准的。


欢迎大家使用钉钉扫描二维码加入 Spring Cloud Alibaba 开源讨论群:

640?wx_fmt=jpeg

扫码,加入我们


©每周一推

第一时间获得下期分享

☟☟☟

640?wx_fmt=gif

Tips:

# 点下“看”❤️

# 然后,公众号对话框内发送“雨伞”,试试手气??

# 本期奖品是 来自淘宝心选的全自动雨

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【2021年,将Spring全家桶系列课程进行Review,修复顺序等错误。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并新增高级的Spring Security等内容,通过手把手一步步教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待】 本课程是Spring案例精讲课程的第四部分Spring CloudSpring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Cloud的核心知识点:注册中心、服务提供者与消费者、服务的调用OpenFeign、Hystrix监控、服务网关gateway、消息驱动的微服务Spring Cloud Stream、分布式集群、分布式配置中心的案例介绍, 快速掌握Spring Cloud的核心知识,快速上手,为学习及工作做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring CloudSpring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 
储能开关储能后合闸不了可能是以下几个原因: 1. 储能电容电压过高:在储能过程中,电容充电电压可能会过高,导致储能开关无法合闸。解决方法是等待电容自行放电,或者通过外部装置放电。 2. 储能开关故障:储能开关可能出现故障,导致无法合闸。这种情况需要进行维修或更换储能开关。 3. 储能变流器故障:储能变流器可能出现故障,导致储能开关无法合闸。这种情况需要进行维修或更换储能变流器。 4. 控制系统故障:储能开关的控制系统可能出现故障,导致无法进行合闸操作。这种情况需要进行控制系统的维修或更换。 PCS储能变流器是储能系统的核心部件,它能够将电能从储能电池中提取出来,转换为交流电并输出给电网。重要的功能包括储能、放电、保护等。在实验中,可以通过对PCS储能变流器进行各种测试和分析,来验证其性能和功能是否正常。常见的实验包括: 1. 储能效率测试:测试储能电池在充电时,PCS储能变流器能够将多少电能转换为储存能量。 2. 放电效率测试:测试储能电池在放电时,PCS储能变流器能够将多少能量转换为电能输出。 3. 保护功能测试:测试PCS储能变流器的保护功能是否正常,包括过电流保护、过温保护等。 4. 输出电压稳定性测试:测试PCS储能变流器在输出交流电时,电压是否稳定。 通过这些实验,可以确保PCS储能变流器的性能和功能符合要求,保证储能系统的安全和可靠运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值