官方文档中文版!Spring Cloud Stream 快速入门
本文内容翻译自官方文档,spring-cloud-stream docs,对 Spring Cloud Stream的应用入门介绍。
一、Spring Cloud Stream 简介
官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架。

Spring Cloud Stream构建在SpringBoot之上,提供了Kafka,RabbitMQ等消息中间件的个性化配置,引入了发布订阅、消费组和分区的语义概念,有效的简化了上层研发人员对MQ使用的复杂度,让开发人员更多的精力投入到核心业务的处理。
在实际开发过程中,服务与服务之间通信经常会使用到消息中间件,而以往使用了哪个中间件比如RabbitMQ,那么该中间件和系统的耦合性就会非常高,如果我们要替换为Kafka那么变动会比较大,使用Spring Cloud Stream来整合我们的消息中间件,可以降低系统和中间件的耦合性。
二、Spring Cloud Stream 解决什么问题
无感知的使用消息中间件
Stream解决了开发人员无感知的使用消息中间件的问题,因为Stream对消息中间件的进一步封装,可以做到代码层面对中间件的无感知。
中间件和服务的高度解耦
Spring Cloud Stream进行了配置隔离,只需要调整配置,开发中可以动态的切换中间件(如rabbitmq切换为kafka),使得微服务开发的高度解耦,服务可以关注更多自己的业务流程。
关注公众号:架构进化论,获得第一手的技术资讯和原创文章
三、核心概念和应用模型
主要概念
Spring Cloud Stream 为各大消息中间件产品提供了个性化的自动化配置实现,引用了发布-订阅、消费组、分区的三个核心概念。
Spring Cloud Stream提供了很多抽象和基础组件来简化消息驱动型微服务应用。包含以下内容:
- Spring Cloud Stream的应用模型
- 绑定抽象
- 持久化发布/订阅支持
- 消费者组支持
- 分片支持(Partitioning Support)
- 可插拔API
应用模型
Spring Cloud Stream由一个中立的中间件内核组成。Spring Cloud Stream会注入输入和输出的channels,应用程序通过这些channels与外界通信,而channels则是通过一个明确的中间件Binder与外部brokers连接。

各大消息中间件的绑定抽象
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提供了一些预定义的注解,用于绑定输入和输出channels,以及如何监听channels。
通过@EnableBinding触发绑定
将@EnableBinding注解添加到应用的配置类,就可以把一个spring应用转换成Spring Cloud Stream应用,@EnableBinding注解本身就包含@Configuration注解,会触发Spring Cloud Stream 基本配置。
@Import(...)
@Configuration
@EnableIntegration
public @interface EnableBinding {
...
Class<?>[] value() default {};
}
@Input 与 @Output
一个Spring Cloud Stream应用可以有任意数目的input和output通道,后者通过@Input和@Output注解在接口中定义。
@StreamListener
定义在方法中,被修饰的方法注册为消息中间件上数据流的事件监听器,注解中属性值对应了监听的消息通道名。
Source,Sink和Processor
Spring Cloud Stream提供了三个开箱即用的预定义接口。
Source用于有单个输出(outbound)通道的应用。
public interface Source {
String OUTPUT = "output";
@Output(Source.OUTPUT)
MessageChannel output();
}
Sink用于有单个输入(inbound)通道的应用。
public interface Sink {
String INPUT = "input";
@Input(Sink.INPUT)
SubscribableChannel input();
}
Processor用于单个应用同时包含输入和输出通道的情况。
public interface Processor extends Source, Sink {
}
五、Stream极简实例
下面是一个非常简单的 SpringBootApplication应用,通过依赖Spring Cloud Stream,从Input通道监听消息然后返回应答到Output通道,只要添加配置文件就可以应用。
@SpringBootApplication
@EnableBinding(Processor.class)
public class MyLoggerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MyLoggerServiceApplication.class, args);
}
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public LogMessage enrichLogMessage(LogMessage log) {
return new LogMessage(String.format("[1]: %s", log.getMessage()));
}
}
下面解释下这个示例中相关注解的应用:
@EnableBinding声明了这个应用程序绑定了2个通道:INPUT和OUTPUT。这2个通道是在接口Processor中定义的(Spring Cloud Stream默认设置)。所有通道都是配置在一个具体的消息中间件或绑定器中。
@StreamListener(Processor.INPUT)表明这里在input中提取消息,并且处理。
@SendTo(Processor.OUTPUT)表明在output中返回消息。
总结
这篇文章根据Spring Cloud Stream的官方文档,对Stream做了一个整体的介绍,包括设计目标,应用场景,业务模型以及对外开放的注解,后面我会通过一个实例,演示 Spring Cloud Stream 的应用。

官方文档中文版!Spring Cloud Stream 快速入门的更多相关文章
- Spring Cloud官方文档中文版-Spring Cloud Config(上)
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...
- Spring Cloud官方文档中文版-Spring Cloud Config(下)-客户端等
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_serving_alternative_formats 文中例子我做了 ...
- Spring Cloud官方文档中文版-Spring Cloud Config(上)-服务端(配置中心)
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...
- TestNG官方文档中文版(2)-annotation(转)
1. 介绍 TestNG是一个设计用来简化广泛的测试需求的测试框架,从单元测试(隔离测试一个类)到集成测试(测试由有多个类多个包甚至多个外部框架组成的整个系统,例如运用服务器). 编写一个测试的 ...
- Istio官方文档中文版
Istio官方文档中文版 http://istio.doczh.cn/ https://istio.io/docs/concepts/what-is-istio/goals.html 为什么要使用Is ...
- 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- 2DToolkit官方文档中文版打地鼠教程(二):设置摄像机
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- 2DToolkit官方文档中文版打地鼠教程(一):初始设置
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- 人工智能系统Google开源的TensorFlow官方文档中文版
人工智能系统Google开源的TensorFlow官方文档中文版 2015年11月9日,Google发布人工智能系统TensorFlow并宣布开源,机器学习作为人工智能的一种类型,可以让软件根据大量的 ...
随机推荐
- UVA 1625 "Color Length" (基础DP)
传送门 •参考资料 [1]:HopeForBetter •题意 •题解(by 紫书) •我的理解 用了一上午的时间,参考紫书+上述博文,终于解决了疑惑: 定义第一个颜色序列用串 s 表示,第二个用串 ...
- VScode快捷键(最全)
按 Press 功能 Function Ctrl + Shift + P,F1 显示命令面板 Show Command Palette Ctrl + P 快速打开 Quick Open Ctrl + ...
- Fetch 记录
encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号.正斜杠.问号和井字号:而encodeURIComponent()则会对它发现的任何非标准字符进行编码. Fetch 请求body ...
- ansible核心模块playbook介绍
ansible的playbook采用yaml语法,它简单地实现了json格式的事件描述.yaml之于json就像markdown之于html一样,极度简化了json的书写.在学习ansible pla ...
- UTF-8、UTF-16、UTF-32编码的相互转换(不使用现成的函数)
最近在考虑写一个可以跨平台的通用字符串类,首先需要搞定的就是编码转换问题. vs默认保存代码文件,使用的是本地code(中文即GBK,日文即Shift-JIS),也可以使用带BOM的UTF-8.gcc ...
- Integer类入门学习
Integer类 它是一个类,是 int 基本数据类型的封装类. 基本API Integer 类和 int 的区别 Integer 是 int 包装类,int 是八大基本数据类型之一(byte,sho ...
- VRChat之blender2.8版本设置
推荐先看:VRChat模型制作及上传总篇(包含总流程和所需插件):https://www.cnblogs.com/raitorei/p/12015876.html blender2.8视频:https ...
- 什么是神经网络 (Neural Network)
反向传播: 可以看作是再一次将传过来的信号传回去, 看看这个负责传递信号神经元对于”讨糖”的动作到底有没有贡献, 让它好好反思与改正, 争取下次做出更好的贡献. 生物神经网络和人工神经网络的差别: 人 ...
- 程序员必须掌握的性能调优 X Y Z
热评博文:<如何设计出优美的Web API?>,现阅读量超 2500,小伙伴们不要错过哦! 2003 ~ 2008 年,这五年老兵哥我在通信行业做实习生和开发岗,主要用 C / C++ / ...
- The sixth day of Crawler learning
爬取我爱竞赛网的大量数据 首先获取每一种比赛信息的分类链接 def get_type_url(url): web_data = requests.get(web_url) soup = B ...