- 什么是消息驱动
SpringCloud Stream消息驱动可以简化开发人员对消息中间件的使用复杂度,让系统开发人员更多尽力专注与核心业务逻辑的开发。SpringCloud Stream基于SpringBoot实现,自动配置化的功能可以帮助我们快速上手学习,类似与我们之前学习的orm框架,可以平滑的切换多种不同的数据库。
目前SpringCloud Stream 目前只支持 rabbitMQ和kafka - 消息驱动原理
通过定义绑定器作为中间层,实现了应用程序与消息中间件细节之间的隔离。通过向应用程序暴露统一的Channel通过,是的应用程序不需要再考虑各种不同的消息中间件的实现。当需要升级消息中间件,或者是更换其他消息中间件产品时,我们需要做的就是更换对应的Binder绑定器而不需要修改任何应用逻辑 。
在该模型图上有如下几个核心概念:
- Source: 当需要发送消息时,我们就需要通过Source,Source将会把我们所要发送的消息(POJO对象)进行序列化(默认转换成JSON格式字符串),然后将这些数据发送到Channel中;
- Sink: 当我们需要监听消息时就需要通过Sink来,Sink负责从消息通道中获取消息,并将消息反序列化成消息对象(POJO对象),然后交给具体的消息监听处理进行业务处理;
- Channel: 消息通道是Stream的抽象之一。通常我们向消息中间件发送消息或者监听消息时需要指定主题(Topic)/消息队列名称,但这样一旦我们需要变更主题名称的时候需要修改消息发送或者消息监听的代码,但是通过Channel抽象,我们的业务代码只需要对Channel就可以了,具体这个Channel对应的是那个主题,就可以在配置文件中来指定,这样当主题变更的时候我们就不用对代码做任何修改,从而实现了与具体消息中间件的解耦;
- Binder: Stream中另外一个抽象层。通过不同的Binder可以实现与不同消息中间件的整合,比如上面的示例我们所使用的就是针对Kafka的Binder,通过Binder提供统一的消息收发接口,从而使得我们可以根据实际需要部署不同的消息中间件,或者根据实际生产中所部署的消息中间件来调整我们的配置。
- Springboot整合
- 生产者
- 创建springboot项目 ,在pom.xml引入依赖
<!--rabbit消息驱动 如果需要配置kafka, 直接下面的rabbit换成kafka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> <version>2.0.1.RELEASE</version> </dependency>
- application.yml配置如下
server: port: 9000 spring: application: name: spingcloud-stream-producer ####默认rabbit配置 # rabbitmq: # host: 192.168.174.128 # port: 5672 # username: guest # password: guest
- 创建管道接口 SendMessageInterface.java
import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.SubscribableChannel; /** * Create by wangxb * 2019-09-06 7:48 */ // 创建管道接口 public interface SendMessageInterface { // 创建一个输出管道,用于发送消息 @Output("my_msg") SubscribableChannel sendMsg(); }
- 创建IndexController.java
import com.basic.service.SendMessageInterface; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.UUID; /** * Create by wangxb * 2019-09-06 7:49 */ @RestController public class IndexController { @Autowired private SendMessageInterface sendMessageInterface; @RequestMapping("/sendMsg") public String sendMsg() { String msg = UUID.randomUUID().toString(); System.out.println("生产者发送内容msg:" + msg); Message build = MessageBuilder.withPayload(msg.getBytes()).build(); sendMessageInterface.sendMsg().send(build); return "success"; } }
- 启动类,开启并绑定消息
// 默认是以通道名称创建交换机,帮我们创建队列名称import com.basic.service.SendMessageInterface; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.stream.annotation.EnableBinding; /** * Hello world! * */ @SpringBootApplication @EnableBinding(SendMessageInterface.class) // 开启绑定 public class AppStream { public static void main( String[] args ) { SpringApplication.run(AppStream.class, args); } }
- 消费者
这里把消费者pom.xml和配置都一样,就写在一个项目里了
- 创建消费者的管道接口,绑定消息,RedMsgInterface.java
import org.springframework.cloud.stream.annotation.Input; import org.springframework.messaging.SubscribableChannel; /** * Create by wangxb * 2019-09-07 10:09 */ public interface RedMsgInterface { // 从管道中获取消息 @Input("my_msg") SubscribableChannel redMsg(); }
- 创建消费者获取消息Consumer.java
import org.springframework.cloud.stream.annotation.StreamListener; import org.springframework.stereotype.Component; /** * Create by wangxb * 2019-09-07 10:12 */ @Component public class Consumer { @StreamListener("my_msg") public void listener(String msg) { System.out.println("消费者获取生产消息:" + msg); } }
- 启动项目,测试
- 上面的配置是整合kafka,如果我们要迁移其他rabbit,只需要在pom.xml引入依赖,yml配置地址就可以,代码逻辑不用改
- 消费者分组消费
未完待续.......................