本文转载自微信公众号「 Java学习部落」,作者 Java学习部落 。转载本文请联系 Java学习部落公众号。
Spring Cloud Stream 简介
官方定义Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架。它为一些供应商的消息中间件产品提供了个性化的自动化配置实现,并且引入了发布-订阅、消费组以及分区这三个核心概念。
Spirng Cloud Stream 本质上就是整合了 Spring Boot 和 Spring Integration,实现一套轻量级的消息驱动的微服务框架。
通过使用 Spring Cloud Stream 可以有效简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。
Spring Cloud Stream 基于 Spring Boot 实现,所以它秉承了 Spring Boot 的优点,自动化配置功能可以帮助我们快速上手使用。
不过 Spring Cloud Stream 目前只支持 RabbitMQ 和 Kafka 这两个消息中间件的自动化配置。
相关知识点解读
「1. 什么是事件驱动架构?」
如上图所示,有时候系统中的某个服务会因为用户操作或内部行为发布一个事件,该服务知道这个事件在将来的某一个时间点会被其他服务所消费,但是并不知道这个服务具体是谁、也不关心什么时候被消费。同样,消费该事件的服务也不一定需要知道该事件是由哪个服务所发布。
事件生产者和消费者之间的虚线代表的是一种相互松散、没有直接调用的关联关系。满足以上特性的系统代表着一种松耦合的架构,通常被称为事件驱动架构,而这里的事件也可以被理解是服务与服务之间发送的一种消息。事件驱动架构本质上是一种架构设计风格,实现方法和工具有很多。在 Spring Cloud 家族中这个工具就是 Spring Cloud Stream。
其实,Spring Cloud Stream 是基于 Spring Integration 实现了消息发布和消费机制并提供了一层封装,很多关于消息发布和消费的概念和实现方法本质上都是依赖于 Spring Integration。而在 Spring Integration 的背后,则依赖于 Spring Messaging 组件来实现消息处理机制的基础设施。
「2. 什么是 Spring Messaging?」
Spring Messaging 是 Spring Framework 中的一个模块,其作用就是统一消息的编程模型。
每一个消息 Messaging 对应的模型就包括一个消息体 Payload 和消息头 Header。
- package org.springframework.messaging; public interface Message {
- T getPayload();
- MessageHeaders getHeaders();
- }
消息通道 MessageChannel 用于接收消息,调用 send 方法可以将消息发送至该消息通道中。
- @FunctionalInterface
- public interface MessageChannel {
- long INDEFINITE_TIMEOUT = -1;
- default boolean send(Message<?> message) {
- return send(message, INDEFINITE_TIMEOUT);
- }
- boolean send(Message<?> message, long timeout);
- }
「消息通道里的消息如何被消费呢?」
由消息通道的子接口可订阅的消息通道 SubscribableChannel 实现,被 MessageHandler 消息处理器所订阅:
- public interface SubscribableChannel extends MessageChannel {
- boolean subscribe(MessageHandler handler);
- boolean unsubscribe(MessageHandler handler);
- }
由MessageHandler 真正地消费/处理消息:
- @FunctionalInterface
- public interface MessageHandler {
- void handleMessage(Message<?> message) throws MessagingException;
- }
Spring Messaging 内部在消息模型的基础上衍生出了其它的一些功能,如:
- 消息接收参数及返回值处理:消息接收参数处理器 HandlerMethodArgumentResolver 配合 @Header, @Payload 等注解使用;消息接收后的返回值处理器 HandlerMethodReturnValueHandler 配合 @SendTo 注解使用;
- 消息体内容转换器 MessageConverter;
- 统一抽象的消息发送模板 AbstractMessageSendingTemplate;
- 消息通道拦截器 ChannelInterceptor;
「3.什么是Spring Integration?」
spring cloud stream是一个构建与Spring Boot和Spring Integration之上的框架,方便开发人员快速构建基于Message-Driven的系统。
Spring Integration & Enterprise Integration Patterns简介
Enterprise Integration Patterns 是由Gregor Hohpe和Bobby Woolf在 Enterprise Integration Patterns 一书中总结的企业应用开发实践中使用到的各系统间数据交换的方式。
Spring Integration是Spring框架对Enterprise Integration Patterns的实现和适配。
Spring Integration在基于Spring的应用程序中实现轻量级消息传递,并支持通过声明适配器与外部系统集成。与Spring对远程处理,消息传递和调度的支持相比,这些适配器提供了更高级别的抽象。
Spring Integration的主要目标是提供一个简单的模型来构建企业集成解决方案,同时保持关注点的分离,这对于生成可维护的可测试代码至关重要。
常见的企业集成数据传递模式有以下几种:
文件传输:系统A采用FTP轮询等方式获取系统B生成的文件等。
共享数据库:系统A和系统B共用一个数据库表,共用实体类。
RPC调用:系统A和B暴露互相之间能调用的服务,例如SOAP、REST。
消息传递:系统A和系统B通过消息中间价交换数据。
Spring Cloud Stream 作用
无感知的使用消息中间件
Spring Cloud Stream解决了开发人员无感知的使用消息中间件的问题,因为Spring Cloud Stream对消息中间件的进一步封装,可以做到代码层面对中间件的无感知。
中间件和服务的高度解耦
Spring Cloud Stream进行了配置隔离,只需要调整配置,开发中可以动态的切换中间件(如rabbitmq切换为kafka),使得微服务开发的高度解耦,服务可以关注更多自己的业务流程。
Spring Cloud Stream 核心概念和应用模型
「主要概念」
Spring Cloud Stream 为各大消息中间件产品提供了个性化的自动化配置实现,引用了发布-订阅、消费组、分区的三个核心概念。
Spring Cloud Stream提供了很多抽象和基础组件来简化消息驱动型微服务应用。包含以下内容:
- Spring Cloud Stream的应用模型
- 绑定抽象
- 持久化发布/订阅支持
- 消费者组支持
- 分片支持(Partitioning Support)
- 可插拔API
「应用模型」
Spring Cloud Stream由一个中立的中间件内核组成。
Spring Cloud Stream会注入输入和输出的channels,应用程序通过这些channels与外界通信,而channels则是通过一个明确的中间件Binder与外部brokers连接。
「Channel」
Channel描述的是消息从应用程序和Binder之间的流通的通道,也就是Application Model中的input和output。
「Binder」
Binder是Spring Cloud Stream中一个非常重要的概念,它是应用程序和消息中间件的中间层,完美屏蔽了不同消息中间件的实现差异,可以简单的类比为Adapter。
Spring Cloud Stream官方提供了spring-cloud-stream-binder-kafka和spring-cloud-stream-binder-rabbit两款主流消息中间件的Binder实现。并且还提供了专门用于测试的TestSupportBinder,开发者可以直接使用它来对通道的接收内容进行断言测试。
当然,Spring Cloud Stream也允许开发者通过它的SPI来实现其他MQ的Binder。目前已有多款MQ产品提供了第三方Binder实现,参考官方文档Binder Implementions。如要实现自己的Binder可以参考官方文档Binder SPI。
「Bindings」
Binding是用于描述MQ中间件到应用程序的桥梁模型,即是对于Binder加上inputs和outputs各个channel的绑定关系的描述
「各大消息中间件的绑定抽象」
Spring Cloud Stream提供对Kafka,Rabbit MQ,Redis,和Gemfire的Binder实现。Spring Cloud Stream还包括了一个TestSupportBinder,TestSupportBinder预留一个未更改的channel以便于直接地、可靠地和channels通信。
「集成Kafka」
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-stream-binder-kafka</artifactId>
- </dependency>
「集成RabbitMQ」
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
- </dependency>
「分区支持」
Spring Cloud Stream支持在一个应用程序的多个实例之间数据分区,在分区的情况下,物理通信介质(例如,topic代理)被视为多分区结构。一个或多个生产者应用程序实例将数据发送给多个消费应用实例,并保证共同的特性的数据由相同的消费者实例处理。
Spring Cloud Stream提供了一个通用的抽象,用于统一方式进行分区处理,因此分区可以用于自带分区的代理(如kafka)或者不带分区的代理(如rabbiemq)
分区在有状态处理中是一个很重要的概念,其重要性体现在性能和一致性上,要确保所有相关数据被一并处理,例如,在时间窗平均计算的例子中,给定传感器测量结果应该都由同一应用实例进行计算。
Spring Cloud Stream 总结
本文是 Spring Cloud Stream 的第一篇,我们介绍了到底什么是Spring Cloud Stream以及相关知识点的解读,帮助我们从整体上认识Spring Cloud Stream。