介绍
- spring cloud stream 出现的目的是为了统一不同消息中间件底层差异。
- spring cloud stream 是一个构建消息驱动微服务应用的框架。
相关文档
使用demo
说明
基于注释的编程模型,@EnableBInding、@StreamListener 和所有相关注释现在已被弃用。取而代之的是函数式编程模型。有关更多详细信息,请参阅Spring Cloud Function 支持。
示例版本:3.2.2
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
连接配置
spring:
rabbitmq:
host: 127.0.0.1
username: guest
password: guest
生产者
spring:
cloud:
stream:
bindings:
okSend: # bindings名称
destination: my-topic # 理解为主题 交换机 队列都可以
@Resource
private StreamBridge streamBridge;
public void test(){
// okSend 是和配置文件 对应的
streamBridge.send("okSend","hello stream rabbit ");
}
消费者
@Component
public class Consumer {
//名字定义好,需要在yaml文件中配置,可以定义不配置,但不能配置不定义
//Consumer 表示定义了一个消费者
@Bean
public java.util.function.Consumer<String> okConsumer(){
return message ->{
System.out.println("=====okConsumer :" + message);
};
}
@Bean
public java.util.function.Consumer<String> failConsumer(){
return message ->{
System.out.println("=====okConsumer :" + message);
};
}
}
spring:
cloud:
stream:
function:
# 多个消费者,分号分割,代码中定义的函数名
definition: okConsumer;failConsumer
bindings:
#函数名 - in(表示消费者) out(表示生产者) - 0(表示数据通道,固定0)
okConsumer-in-0:
#生产者nacos里定义的 destination
destination: my-topic
#消费者组,一个消息会被不同消费者组消费,在一个组里只会被消费一次
group: okConsumer
failConsumer-in-0:
destination: my-fail-topic
group: failConsumer
多binder配置(多队列)
spring:
cloud:
stream:
defaultBinder: testbinder
binders:
testbinder: # binder名称
type: rabbit # 队列类型
environment:
spring:
rabbitmq:
addresses: 127.0.0.1
username: guest
password: guest
@Resource
private StreamBridge streamBridge;
public void test(){
//参数 : bindings名称,binder名称,消息内容,消息类型(JSON,text,png,html..)
streamBridge.send("okSend","testbinder","my message ",
MimeTypeUtils.TEXT_PLAIN);
}
其他函数
//表示一个生产者
//向通道发送消息
//可以配合 @PollableBean 做定期发送消息
@Bean
public Supplier<String> supplier(){
return () -> {
String message = "Hello from Supplier";
System.out.println(message);
return message;
};
}
//是一个消费者,同时也是一个生产者
//接受消息并且打印,同时处理结束继续发送到队列
@Bean
public Function<String,String> transfer(){
return (message) ->{
System.out.println("=====transfer :" + message);
return "transfer" + message;
};
}
//消费者
@Bean
public Consumer<String> consumer(){
return message ->{
System.out.println("=====consumer :" + message);
};
}
spring:
cloud:
stream:
function:
definition: supplier;transfer;consumer
bindings:
supplier-out-0:
destination: destination1
transfer-in-0:
destination: destination1
group: transfer
transfer-out-0:
destination: destination2
consumer-in-0:
destination: destination2
group: consumer
#supplier 产生消息发送到destination1,transfer从destination1获取消息,并发送发destination2,consumer从destination2中消费消息
FQA
1 . 为什么发送了消息,但是没有新的队列产生?
初次使用时,要先保证队列存在,队列是 [名字+分组]的组合
创建队列的动作是由 consumer 去完成的,初次使用时,先启动消费.
队列存在后,消息就能正常入队
2.按照文档配置,本地消费者无法监听消息
当前示例的版本基于3.2.2,配置文件的方式和 3.1x 及之前版本有差异