Spring Cloud Stream在同一通道根据消息内容分发不同的消费逻辑
应用场景
有的时候,我们对于同一通道中的消息处理,会通过判断头信息或者消息内容来做一些差异化处理,比如:可能在消息头信息中带入消息版本号,然后通过if判断来执行不同的处理逻辑,其代码结构可能是这样的:
@StreamListener(value = TestTopic.INPUT)
public void receiveV1(String payload, @Header("version") String version) {
if("1.0".equals(version)) {
// Version 1.0
}
if("2.0".equals(version)) {
// Version 2.0
}
}
那么当消息处理逻辑复杂的时候,这段逻辑就会变得特别复杂。针对这个问题,在@StreamListener注解中提供了一个不错的属性condition,可以用来优化这样的处理结构。
动手试试
下面通过编写一个简单的例子来具体体会一下这个属性的用法:
@EnableBinding(TestApplication.TestTopic.class)
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@RestController
static class TestController {
@Autowired
private TestTopic testTopic;
/**
* 消息生产接口
*
* @param message
* @return
*/
@GetMapping("/sendMessage")
public String messageWithMQ(@RequestParam String message) {
testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "1.0").build());
testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "2.0").build());
return "ok";
}
}
/**
* 消息消费逻辑
*/
@Slf4j无锡妇科医院哪家好 http://wapyyk.39.net/wx/zonghe/fc96e.html/
@Component
static class TestListener {
@StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='1.0'")
public void receiveV1(String payload, @Header("version") String version) {
log.info("Received v1 : " + payload + ", " + version);
}
@StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='2.0'")
public void receiveV2(String payload, @Header("version") String version) {
log.info("Received v2 : " + payload + ", " + version);
}
}
interface TestTopic {
String OUTPUT = "example-topic-output";
String INPUT = "example-topic-input";
@Output(OUTPUT)
MessageChannel output();
@Input(INPUT)
SubscribableChannel input();
}
}
内容很简单,既包含了消息的生产,也包含了消息消费。在/sendMessage接口的定义中,发送了两条消息,一条消息的头信息中包含version=1.0,另外一条消息的头信息中包含version=2.0。在消息监听类TestListener中,对TestTopic.INPUT通道定义了两个@StreamListener,这两个监听逻辑有不同的condition,这里的表达式表示会根据消息头信息中的version值来做不同的处理逻辑分发。
在启动应用之前,还要记得配置一下输入输出通道对应的物理目标(exchange或topic名),比如:
spring.cloud.stream.bindings.example-topic-input.destination=test-topic
spring.cloud.stream.bindings.example-topic-input.group=stream-content-route
spring.cloud.stream.bindings.example-topic-output.destination=test-topic
完成了上面配置之后,就可以启动应用,并尝试访问localhost:8080/sendMessage?message=hello接口来发送一个消息到MQ中了。此时可以看到类似下面的日志:
2018-12-24 15:50:33.361 INFO 17683 --- [content-route-1] c.d.stream.TestApplication$TestListener : Received v1 : hello, 1.0
2018-12-24 15:50:33.363 INFO 17683 --- [content-route-1] c.d.stream.TestApplication$TestListener : Received v2 : hello, 2.0
从日志中可以看到,两条带有不同头信息的消息,分别通过不同的监听处理逻辑输出了对应的日志打印。
Spring Cloud Stream在同一通道根据消息内容分发不同的消费逻辑的更多相关文章
- Spring Cloud Stream同一通道根据消息内容分发不同的消费逻辑
应用场景 有的时候,我们对于同一通道中的消息处理,会通过判断头信息或者消息内容来做一些差异化处理,比如:可能在消息头信息中带入消息版本号,然后通过if判断来执行不同的处理逻辑,其代码结构可能是这样的: ...
- 整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 Spring Cloud Stream专门用于事件驱动的微服务系统,使用消息中间件来收发信息.使用Spring ...
- 「 从0到1学习微服务SpringCloud 」08 构建消息驱动微服务的框架 Spring Cloud Stream
系列文章(更新ing): 「 从0到1学习微服务SpringCloud 」01 一起来学呀! 「 从0到1学习微服务SpringCloud 」02 Eureka服务注册与发现 「 从0到1学习微服务S ...
- 使用 Spring Cloud Stream 构建消息驱动微服务
相关源码: spring cloud demo 微服务的目的: 松耦合 事件驱动的优势:高度解耦 Spring Cloud Stream 的几个概念 Spring Cloud Stream is a ...
- Spring Cloud Alibaba学习笔记(12) - 使用Spring Cloud Stream 构建消息驱动微服务
什么是Spring Cloud Stream 一个用于构建消息驱动的微服务的框架 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互, ...
- 整合Spring Cloud Stream Binder与GCP Pubsub进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 之前的文章<整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收& ...
- Spring cloud stream【入门介绍】
案例代码:https://github.com/q279583842q/springcloud-e-book 在实际开发过程中,服务与服务之间通信经常会使用到消息中间件,而以往使用了哪个中间件比如 ...
- 简单聊一聊spring cloud stream和kafka的那点事
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected ...
- Spring Cloud Stream 进行服务之间的通讯
Spring Cloud Stream Srping cloud Bus的底层实现就是Spring Cloud Stream,Spring Cloud Stream的目的是用于构建基于消息驱动(或事件 ...
随机推荐
- Python -3-列表和元组
1.用list就可以像修改列表那样修改字符串了 >>> list('Hello') ['H', 'e', 'l', 'l', 'o'] 可将任何序列作为list的参数 2.列表的 ...
- 修正 FreeBSD 字体锯齿问题
如果你给 FreeBSD 安装完图形界面,一登录就被满屏幕不论中英全是锯齿且残缺不堪入目的文字吓了一跳,那一定是安装了文泉驿字体.先不必急着卸载文泉驿,只需简单修改相关配置即可恢复正常显示.这是因为文 ...
- JDBC事务之例子篇
上一篇随笔记了一些有关JDBC事务管理的理论知识.这篇来看例子(主要怕一篇随笔装所有东西太长了然后分开呵呵) 一般讲事务管理的,都是拿转钱来当例子的,嗯没错我们这也是. 这个是数据库中的t_accou ...
- [未读]编写可测试的JavaScript代码
- B. Dispersed parentheses 记忆化搜索 + 括号序列的状压表示
http://codeforces.com/gym/100633/problem/B B. Dispersed parentheses time limit per test 2 seconds me ...
- 《javascript设计模式》笔记之第五章:单体模式
一:单体的基本结构: 最简单的单体,实际就是一个对象字面量: var Singleton = { attribute1: true, attribute2, method1: function() { ...
- js实现屏幕自适应局部
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Spring注解和JDK注解
1.添加xsd约束 xmlns:context="http://www.springframework.org/schema/context" http://www.springf ...
- Android 开机启动服务
在xml中注册 <!-- 开机广播 --> <receiver android:name=".receiver.BootBroadcastReceiver"> ...
- ios UI自动化测试
转载:http://www.cnblogs.com/dokaygang128/p/3517674.html 一.一些注意事项: 1.做自动化测试时注意如果是真机话首先要设置不锁屏. 2.自动化测试过程 ...