一、前言
前两篇博客提高了用线程池和消息队列才实现异步任务。本篇博客谈一谈用SpringCloud Stream来实现异步任务。
Spring Cloud Stream是一个用来为微服务应用构建消息驱动能力的框架。它可以基于Spring Boot来创建独立的、可用于生产的Spring应用程序。它通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动。
简单来说,Spring Cloud Stream本质上就是整合了Spring Boot和Spring integration,实现了一套轻量级的消息驱动的微服务框架。通过使用Spring Cloud Stream,可以有效简化开发人员对消息中间件的使用复杂度, 目前为止,它支持的消息中间件有RabbitMQ和Kafka。
二、入门demo
1、pom文件配置
新建springboot项目,添加对RabbitMQ的依赖。spring-cloud-starter-stream-rabbit是Spring Cloud Stream对RabbitMQ的封装,Spring Cloud Stream秉承了Spring Boot的优点,自动化配置可以帮助我们快速上手使用。它提供了默认地址:localhost,默认端口5672,默认用户名guest、默认密码guest。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency>
2、创建消费方
消费方的application.yml配置如下:
rabbitmq: host: 127.0.0.1 port: 5672 username: guest password: guest # virtual-host: prontera cloud: stream: bindings: input: destination: pdf2image
消费方代码:
@EnableBinding(Sink.class) public class SinkReceiver { private static Logger log = LoggerFactory.getLogger(SinkReceiver.class); @StreamListener(Sink.INPUT) public void receive(Object payload) { log.info("Received : " + payload); System.out.println("Received :"+payload); } }
Spring Cloud Stream核心注解说明:
@EnableBinding:该注解用来指定一个或多个定义了@Input或@Output注解的接口,以此来实现对消息通道(Channel)的绑定。我上面的例子中,我们通过@EnableBinding(Sink.class)绑定了Sink接口,该接口是Spring Cloud Stream中默认实现的对输入消息通道绑定的含义,它的源码如下:
public interface Sink { String INPUT = "input"; @Input("input") SubscribableChannel input(); }
它通过@Input绑定了一个名为input的通道。除了Sink之外,Spring Cloud Stream还默认实现了绑定output通道的Source接口,还有结合了Sink和Source的Processor接口。实际使用时我们也可以自己通过@Input和@Output注解来定义绑定消息通道的接口。
@StreamListener:它主要定义在方法上,作用是将被修饰的方法注册为消息中间件上数据流的事件监听器,注解中的属性值对应了监听的消息通道名。在上面的例子中,我们通过@StreamListener(Sink.INPUT)注解将receive方法注册为input消息通道的监听处理器。
在RabbitMQ控制台的Queues选项卡界面可以看到队列:pdf2image.anonymous.xxxxxxx。这就是要监听的队列。
在IDEA的consoconsole控制台,会看到监听打印出来的信息。到此为止,消费端的搭建基本完成。
3、创建生产方
创建项目、application.yml,和添加pom的依赖同上,在此不在赘述。
生产方代码如下:
@EnableBinding(Source.class) public class Sender { private static Logger log = LoggerFactory.getLogger(Sender.class); @InboundChannelAdapter(value = Source.OUTPUT,poller = @Poller(fixedDelay = "2000")) public String timerMessageSource() { String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); log.info("Send message : " + format); System.out.println(format); return format; } }
因为是发送消息,所以绑定了发送接口Source。Source源码如下:
public interface Source { String OUTPUT = "output"; @Output("output") MessageChannel output(); }
@InboundChannelAdapter用来表示每隔多少秒触发一次发送消息的接口。
三、总结:
对比上一篇博客的示例代码,Spring Cloud Stream通过注解进行了很多简化。提高了开发效率。