一 实现主要功能
- 简单的发送和接收消息
- 消息者分组
- 消费者数量控制
- 私信队列
二 show code
1. 引入jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
2. yml 配置
该配置实现一个生产者,两组消费者:
- 两组消费分别是input1-test和input2-test;
- 每组内又配置初始化消费者数量2,最大消费者数量为3,每个组内只有一个消费者能接收到消息。
auto-bind-dlq:true开启死信队列,springboot会自动创建死信队列,绑定默认交互机, 当消费者消费报错3次后,程序自动将消息转发到私信队列。
spring:
rabbitmq:
host:
port: 5672
username:
password:
virtual-host:
cloud:
stream:
rabbit:
bindings:
input1:
consumer:
max-concurrency: 3 # 最大消费者数量,只有rabbitmq支持,kafka不支持
input2:
consumer:
max-concurrency: 3 # 最大消费者数量,只有rabbitmq支持,kafka不支持
auto-bind-dlq: true #rabbitmq自动创建队列名为output-test.input2-test.dlq的私信队列
bindings:
out1:
destination: output-test #rabbitmq 交换机
content-type: application/json
input1:
destination: output-test #rabbitmq 交换机
content-type: application/json
group: input1-test #分组,rabbitmq 创建队列名为output-test.input1-test
consumer:
concurrency: 2 #初始/最少/空闲时 消费者数量。默认1
input2:
destination: output-test #rabbitmq 交换机
content-type: application/json
group: input2-test #分组,rabbitmq 创建队列名为output-test.input2-test
consumer:
concurrency: 2 #初始/最少/空闲时 消费者数量。默认1
3. 代码
3.1 声明一个channel
public interface Out1 {
String OUTPUT="out1";
@Output(OUTPUT)
SubscribableChannel send();
}
3.2 模拟消息的产生者
主要是绑定
@EnableBinding({Out1.class})
@RestController
@RequestMapping("stream")
@EnableBinding({Out1.class})
public class TestSend {
@Autowired
private Out1 out1;
@GetMapping
public String t() {
Person person = new Person();
person.setName("测试");
person.setAge(18);
boolean send = out1.send().send(MessageBuilder.withPayload(person).build());
return "ok";
}
}
3.3 消费者
和生产者类似,先声明channel,然后@EnableBinding绑定,再@StreamListener开启监听
public interface Input1 {
String Input = "input1";
@Input(Input)
SubscribableChannel in();
}
public interface Input2 {
String Input = "input2";
@Input(Input)
SubscribableChannel in();
}
@Component
@EnableBinding({Input1.class, Input2.class})
public class TestInput1 {
@StreamListener(Input1.Input)
public void in1(Person person){
System.err.println("1 收到" + JSONUtil.toJsonStr(person));
}
@StreamListener(Input2.Input)
public void in2(Person person){
System.err.println("2 收到" + JSONUtil.toJsonStr(person));
}
}
3.4 程序启动成功后,通过rabbitmq控制台可以看到自动创建的队列
三 其他
- stream默认创建的exchange属于topic交换机,routing key默认#
- 消息默认没有过期时间,可以配置消息的ttl,当消息在队列存活时间超过ttl,自动进入私信队列。