Spring Cloud架构教程 (六)消息驱动的微服务【Dalston版】
Spring Cloud Stream是一个用来为微服务应用构建消息驱动能力的框架。它可以基于Spring Boot来创建独立的、可用于生产的Spring应用程序。它通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动的微服务应用。Spring Cloud Stream为一些供应商的消息中间件产品提供了个性化的自动化配置实现,并且引入了发布-订阅、消费组以及消息分区这三个核心概念。简单的说,Spring Cloud Stream本质上就是整合了Spring Boot和Spring Integration,实现了一套轻量级的消息驱动的微服务框架。通过使用Spring Cloud Stream,可以有效地简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。由于Spring Cloud Stream基于Spring Boot实现,所以它秉承了Spring Boot的优点,实现了自动化配置的功能帮忙我们可以快速的上手使用,但是目前为止Spring Cloud Stream只支持下面两个著名的消息中间件的自动化配置:
RabbitMQKafka
快速入门
下面我们通过构建一个简单的示例来对Spring Cloud Stream有一个初步认识。该示例主要目标是构建一个基于Spring Boot的微服务应用,这个微服务应用将通过使用消息中间件RabbitMQ来接收消息并将消息打印到日志中。所以,在进行下面步骤之前请先确认已经在本地安装了RabbitMQ,具体安装步骤请参考此文。
构建一个Spring Cloud Stream消费者
创建一个基础的Spring Boot工程,命名为:
stream-hello编辑
pom.xml中的依赖关系,引入Spring Cloud Stream对RabbitMQ的支持,具体如下:
<parent> |
- 创建用于接收来自RabbitMQ消息的消费者
SinkReceiver,具体如下:
@EnableBinding(Sink.class) |
- 创建应用主类,这里同其他Spring Boot一样,没有什么特别之处,具体如下:
@SpringBootApplication |
到这里,我们快速入门示例的编码任务就已经完成了。下面我们分别启动RabbitMQ以及该Spring Boot应用,然后做下面的试验,看看它们是如何运作的。
手工测试验证
- 我们先来看一下Spring Boot应用的启动日志。
... |
从上面的日志内容中,我们可以获得以下信息:
- 使用
guest用户创建了一个指向127.0.0.1:5672位置的RabbitMQ连接,在RabbitMQ的控制台中我们也可以发现它。

- 声明了一个名为
input.anonymous.Y8VsFILmSC27eS5StsXp6A的队列,并通过RabbitMessageChannelBinder将自己绑定为它的消费者。这些信息我们也能在RabbitMQ的控制台中发现它们。

下面我们可以在RabbitMQ的控制台中进入input.anonymous.Y8VsFILmSC27eS5StsXp6A队列的管理页面,通过Publish Message功能来发送一条消息到该队列中。

此时,我们可以在当前启动的Spring Boot应用程序的控制台中看到下面的内容:
INFO 16272 --- [C27eS5StsXp6A-1] com.didispace.HelloApplication : Received: [B@7cba610e |
我们可以发现在应用控制台中输出的内容就是SinkReceiver中receive方法定义的,而输出的具体内容则是来自消息队列中获取的对象。这里由于我们没有对消息进行序列化,所以输出的只是该对象的引用,在后面的小节中我们会详细介绍接收消息后的处理。
在顺利完成上面快速入门的示例后,我们简单解释一下上面的步骤是如何将我们的Spring Boot应用连接上RabbitMQ来消费消息以实现消息驱动业务逻辑的。
首先,我们对Spring Boot应用做的就是引入spring-cloud-starter-stream-rabbit依赖,该依赖包是Spring Cloud Stream对RabbitMQ支持的封装,其中包含了对RabbitMQ的自动化配置等内容。从下面它定义的依赖关系中,我们还可以知道它等价于spring-cloud-stream-binder-rabbit依赖。
<dependencies> |
接着,我们再来看看这里用到的几个Spring Cloud Stream的核心注解,它们都被定义在SinkReceiver中:
@EnableBinding,该注解用来指定一个或多个定义了@Input或@Output注解的接口,以此实现对消息通道(Channel)的绑定。在上面的例子中,我们通过@EnableBinding(Sink.class)绑定了Sink接口,该接口是Spring Cloud Stream中默认实现的对输入消息通道绑定的定义,它的源码如下:
public interface Sink {
String INPUT = "input";
@Input(Sink.INPUT)
|
它通过@Input注解绑定了一个名为input的通道。除了Sink之外,Spring Cloud Stream还默认实现了绑定output通道的Source接口,还有结合了Sink和Source的Processor接口,实际使用时我们也可以自己通过@Input和@Output注解来定义绑定消息通道的接口。当我们需要为@EnableBinding指定多个接口来绑定消息通道的时候,可以这样定义:@EnableBinding(value = {Sink.class, Source.class})。
@StreamListener:该注解主要定义在方法上,作用是将被修饰的方法注册为消息中间件上数据流的事件监听器,注解中的属性值对应了监听的消息通道名。在上面的例子中,我们通过@StreamListener(Sink.INPUT)注解将receive方法注册为对input消息通道的监听处理器,所以当我们在RabbitMQ的控制页面中发布消息的时候,receive方法会做出对应的响应动作。

编写消费消息的单元测试用例
上面我们通过RabbitMQ的控制台完成了发送消息来验证了消息消费程序的功能,虽然这种方法比较low,但是通过上面的步骤,相信大家对RabbitMQ和Spring Cloud Stream的消息消费已经有了一些基础的认识。下面我们通过编写生产消息的单元测试用例来完善我们的入门内容。
- 在上面创建的工程中创建单元测试类:
@RunWith(SpringRunner.class) |
- 在应用了上面的消息消费者程序之后,运行这里定义的单元测试程序,我们马上就能在消息消费者的控制台中收到下面的内容:
INFO 50947 --- [L2W-c2AcChb2Q-1] com.didispace.stream.SinkReceiver : Received: produce a message :http://blog.didispace.com |
在上面的单元测试中,我们通过@Output(SinkSender.OUTPUT)定义了一个输出通过,而该输出通道的名称为input,与前文中的Sink中定义的消费通道同名,所以这里的单元测试与前文的消费者程序组成了一对生产者与消费者。到这里,本文的内容就次结束,如果您能够独立的完成上面的例子,那么对于Spring Cloud Stream的基础使用算是入门了。但是,Spring Cloud Stream的使用远不止于此,在近期的博文中,我讲继续更新这部分内容,帮助他们来理解和用好Spring Cloud Stream来构建消息驱动的微服务!源码来源
本文完整实例:
Spring Cloud架构教程 (六)消息驱动的微服务【Dalston版】的更多相关文章
- 第十章 消息驱动的微服务: Spring Cloud Stream
Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架. 它可以基于Spring Boot 来创建独立的. 可用于生产的 Spring 应用程序. 它通过使用 Sprin ...
- Spring Cloud 系列之 Stream 消息驱动(二)
本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Stream 消息驱动(一) 本篇文章讲解 Stream 如何实现消息分组和消息分区. 消息分组 如果有多个消息消费者 ...
- spring-cloud-stream消息驱动的微服务
Spring Cloud Stream 是 一 个用来为微服务应用构建消息驱动能力的框架. 它可以基于Spring Boot 来创建独立的. 可用于生产的 Spring 应用程序. 它通过使用 Spr ...
- Spring Cloud架构教程 (七)消息驱动的微服务(核心概念)【Dalston版】
下图是官方文档中对于Spring Cloud Stream应用模型的结构图.从中我们可以看到,Spring Cloud Stream构建的应用程序与消息中间件之间是通过绑定器Binder相关联的,绑定 ...
- Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务
首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...
- Spring Cloud架构教程 (四)服务网关(路由配置)
传统路由配置 所谓的传统路由配置方式就是在不依赖于服务发现机制的情况下,通过在配置文件中具体指定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由. 没有Eureka和Consul的服 ...
- Spring Cloud架构教程 (八)消息驱动的微服务(消费组)【Dalston版】
使用消费组实现消息消费的负载均衡 通常在生产环境,我们的每个服务都不会以单节点的方式运行在生产环境,当同一个服务启动多个实例的时候,这些实例都会绑定到同一个消息通道的目标主题(Topic)上. 默认情 ...
- Spring Cloud 系列之 Stream 消息驱动(一)
在实际开发过程中,服务与服务之间通信经常会使用到消息中间件,消息中间件解决了应用解耦.异步处理.流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构. 不同中间件内部实现方式是不一样的,这些中间 ...
- Spring Cloud架构教程 (二)Hystrix监控数据聚合
上一篇我们介绍了使用Hystrix Dashboard来展示Hystrix用于熔断的各项度量指标.通过Hystrix Dashboard,我们可以方便的查看服务实例的综合情况,比如:服务调用次数.服务 ...
随机推荐
- Mac020--常用插件
Google浏览器常用插件 1.github插件octotree 2.掘金Chrome网上应用商店 2-1.掘金/老司机的神兵利器 2-2.好用的Google插件:来自掘金 3.Gliffy Diag ...
- [转帖]100G QSFP28与CFP,CFP2,CFP4光模块的比较
100G QSFP28与CFP,CFP2,CFP4光模块的比较 https://www.eefocus.com/etulink/blog/17-09/423967_5c520.html 数据中心网络发 ...
- Java8---函数式编程-示例
// Java8函数式编程示例—(Predicate.Stream.Optional) https://blog.csdn.net/weixin_41950473/article/details/84 ...
- ajax的contentType和dataType
1.contentType,明确告诉服务器我的请求的编码类型是json(严格来说是application/json),不设置的话,有默认值application/x-www-form-urlencod ...
- Linux文件与目录操作 ls 命令(2)
说文件操作是最频繁地操作也不为过,在Linux中,使用ls命令可以列出当前目录中所有内容,本篇就先说说ls命令.本文所说的文件指文件和目录. ls命令常用选项 -a:显示指定目录下所有子目录与文件,包 ...
- 使用Docker部署Spring-Boot+Vue博客系统
在今年年初的时候,完成了自己的个Fame博客系统的实现,当时也做了一篇博文Spring-boot+Vue = Fame 写blog的一次小结作为记录和介绍.从完成实现到现在,也断断续续的根据实际的使用 ...
- 利用AXI-DMA批量发送数据到DMA
1.1 主函数 int main(void) { XGpio_Initialize(&Gpio, AXI_GPIO_DEV_ID); XGpio_SetDataDirection(&G ...
- Paper Reading_Distributed System
最近(以及预感接下来的一年)会读很多很多的paper......不如开个帖子记录一下读paper心得 Mark一个上海交通大学东岳网络工作室的paper notebook Mark一个大神的笔记 Ed ...
- git Permanently added the RSA host key for IP address '13.250.177.223' to the list of known hosts.
只要把那个ip地址添加进hosts列表中就可解决. 参见:https://blog.csdn.net/hunhun1122/article/details/79752125
- CSS选择符有哪些?哪些属性可以继承
下面是一些常用的选择器: 1.id选择器( # myid) 2.类选择器(.myclassname) 3.标签选择器(div, h1, p) 4.相邻选择器(h1 + p) 5.子选择器(ul > ...