通过本篇文章您可以了解到以下内容:
- 回顾
- Spring Cloud Stream 简介
- Spring Cloud Stream 深入介绍
- 总结
往期 · 推荐
首先让我们做一个简单的回顾:
在上一篇文章中我们深入的了解了 Spring Cloud。我们知道 Spring Cloud 提供了一系列开箱即用的组件,开发者只需要通过配置简单的注解以及编写少量的 yaml 就可以完成快速开发的工作。
这些组件解决的是微服务架构中常见的、共性的一些问题,比如网关、负载均衡、监控、应用层面的高可用(熔断、降级、限流)。但是我们会发现这些解决方案中并不包括对消息中间件的解决方案。例如有的项目使用 Kafka,有的项目使用 RabbitMQ 等等,那么对于这些消息中间件的整合,Spring Cloud 又会给出怎样的解决方案呢 ? 这时候 Spring Cloud Stream 就登场了。
Spring Cloud Stream 简介
在文章的开始,首先让我们看看官方对于 Spring Cloud Stream 的定义和介绍:
通过上述的介绍,不难看出,首先 Spring 关于对数据的集成是始于 Spring Integration 项目的。通过其编程模型,提供了对开发人员来说一致的开发体验。
但是在云时代下,微服务架构就变的尤为重要,几乎所有的 Java 开发人员都会使用 Spring Boot 作为微服务开发框架的首选。
此外在现有项目 Spring Integration 的基础上进行再次封装,并与 Spring Boot 体系进行融合,也就形成了一个新的项目,即 Spring Cloud Stream。
通过 Spring Cloud Stream 开发者又会具备哪些优势呢 ?
- 独立,隔离似的构建、测试和部署以数据为中心的应用程序。
- 应用现代微服务架构模式,包括通过消息传递的组合。
- 将应用程序职责与以事件为中心的思想分离。事件可以表示及时发生的事情,下游消费者应用程序可以对其做出反应,而不知道事件的起源或生产者的身份。
- 将业务逻辑移植到消息代理上 (例如 RabbitMQ, Apache Kafka, Amazon Kinesis)。
- 依赖于框架对常见用例的自动内容类型支持。使得扩展到不同的数据转换类型变得可能。
通俗一点来讲,比如在我们实际生产的业务系统中用到了 Kafka 和 RabbitMQ 等组件,众所周知的是 Kafka 和 RabbitMQ 这两个消息中间件在架构上是不尽相同的。举个例子,如果因为业务需要,将现有的 Kafka 迁移到 RabbitMQ 那么势必会面临大量代码以及配置修改的问题。这无疑对于开发人员来说是非常复杂的。而 Spring Cloud Stream 的出现恰恰很好的解决了这个问题。
Spring Cloud Stream 是一个构建消息驱动微服务的框架。对应的应用程序中需要通过 Inputs 亦或 Outputs 来与 Spring Cloud Stream 中的 Binder 进行交互即可。
通过指定对应消息中间件例如 kafka 或者 RabbitMQ 的 Binder 实现与外部代理链接,业务开发人员可以不再关注具体消息中间件,只需要关注 Binder 提供的抽象概念来使用与之对应的消息中间件即可。
Spring Cloud Stream 深入介绍
首先让我们对 Spring Cloud Stream 的核心概念有一个全面的认知:
Destination Binder
负责提供与外部消息传递系统集成的组件。
Binding
外部消息传递系统和应用程序提供的消息生产者和消费者(由目标绑定器创建)之间的桥梁。
从上图中可以看出,Binding 等同于连接应用程序和消息中间件的桥梁,用于生产消息和对消息进行消费。
在没有 Binding 时,我们使用 Spring Boot 应用要直接与消息中间件直接打交道,通过 Bingding 作为中间层,可以完美实现了应用程序与消息中间件细节的隔离和屏蔽。Spring Cloud Stream 对消息中间件进行了进一步的封装,可与做到代码层面的无感知,可以使得开发者动态切换消息中间件(例如从 Kafka 切换到 RabbitMQ)这样就做到了高度解耦,使得每一个服务更加关注自己的业务流程。此外 Input 对应消费者,Output 对应生产者。
Message
这个相对好理解,即生产者和消费者用于与目标绑定器(以及通过外部消息传递系统与其他应用程序)通信的规范数据结构。
接下来让我们看下 Spring Cloud Stream 架构以及常用注解:
@EnableBinding
该注解本身使用 @Configuration 进行元注释,触发 Spring Cloud Stream 基础架构的配置。
@StreamListner
用于消费者的队列进行消息的接收。
Middleware
消息中间件,可以理解为 RabbitMQ 或者 Kafka 等。
@Input
此注解表示输入的管道,即通过该输入管道接收到消息。
@Output
此注解表示输出的管道,即发布的消息通过此管道从该应用程序发送出去。
除了以上注解以外,Spring Cloud Stream 有两种消费类型,分别是推送模式,以及拉取模式。
推送模式
一旦新的消息出现,会立即发送给消费者。
拉取模式
消费者会主动从消息中间件拉取消息,此场景适用于如果希望控制消息的消费速度。
再了解完消息的消费类型以后,让我们看看关于 Spring Cloud Stream 对分区方面的支持,这里面值得注意的是,无论整合的中间件是否支持分区,例如 Kafka 本身支持分区。Spring Cloud Stream 中都能够使用分区的功能,这里 Spring Cloud Stream 对各种分区实现做出了抽象的处理。它会将消息传递给媒介,例如 Kafka 的 Topic,对于 RabbitMQ 就是 Exchange。
值得注意的是,在使用分区处理的时候,需要同时对 Producer 端和 Consumer 端进行配置。
与此同时在 Spring Cloud Stream 中也存在消费组的概念。对于处于同一消费组中的多个应用出现争抢时,那么该消息只会被消费组中的一个实例消费。
我们可以通过 spring.cloud.stream.bindings…group 参数来声明当前应用所属的消费组。当然如果不进行设置,Spring Cloud Stream 会默认创建一个。
最后关于 Spring Cloud Stream 的例子,大家可以参考如下链接:
总结
回顾全篇内容,整体包括以下内容:
- 首先在开篇我们对 Spring Cloud 组件进行了回顾。
- 其次对 Spring Cloud Stream 进行了宏观的介绍,包括该项目的由来,解决了什么问题等。
- 对 Spring Cloud Stream 进行了深入介绍。
参考链接:
1.https://spring.io/projects/spring-cloud-stream
2.https://github.com/spring-cloud/spring-cloud-stream-samples
内容来源|公众号:VMwareTanzu 云原生