RabbitMQ有以下几种工作模式 :
- Work queues
- Publish/Subscribe
- Routing
- Topics
- Header
- RPC
Work模式
- 生产者创建发送多个消息
- 一个消息能被一个消费者接收
@Autowired
RabbitTemplate rabbitTemplate;
public void work() {
for (int i = 0; i < 20; i++) {
rabbitTemplate.convertAndSend("work", "一个消息");
}
}
@RabbitListener(queuesToDeclare = @Queue("work"))
public void receive1(String msg){
System.out.println("message1: " + msg);
}
@RabbitListener(queuesToDeclare = @Queue("work"))
public void receive2(String msg){
System.out.println("message2: " + msg);
}
发布订阅模式
- 所有订阅该交换机的消费者都能收到生产者发送的消息
- 一条信息能被所有订阅的消费者所接收
@Autowired
RabbitTemplate rabbitTemplate;
public void fanout() {
for (int i = 0; i < 20; i++) {
rabbitTemplate.convertAndSend("logs", "", "消息");
}
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "logs",type = "fanout")
)
})
public void receive3(String msg){
System.out.println("fanout_message 1= "+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "logs",type = "fanout")
)
})
public void receive4(String msg){
System.out.println("fanout_message 2= "+msg);
}
路由模式
- 每个消费者监听自己的队列,并且设置routingkey。
- 生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列。
@Autowired
RabbitTemplate rabbitTemplate;
public void route(){
for (int i = 0; i < 20; i++) {
rabbitTemplate.convertAndSend("amq.direct","warn", "一个消息");
}
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "amq.direct",type = "direct"),
key = {"info","error","warn","hi"}
)
})
public void receive5(String msg){
System.out.println("direct_message1= "+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "amq.direct",type = "direct"),
key = {"info"}
)
})
public void receive6(String msg){
System.out.println("direct_message2= "+msg);
}
topic模式
- 每个消费者监听自己的队列,并且设置带统配符的routingkey。
- 生产者将消息发给broker,由交换机根据routingkey来转发消息到指定的队列。
@Autowired
RabbitTemplate rabbitTemplate;
public void topics(){
for (int i = 0; i < 20; i++) {
rabbitTemplate.convertAndSend("amq.topic","user.good", "一个消息");
}
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(name = "amq.topic",type = "topic"),
key = {"user.save","user.*"}
)
})
public void receive7(String msg){
System.out.println("topics_message1="+msg);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(name = "amq.topic",type= "topic"),
key = {"user.good"}
)
})
public void receive8(String msg){
System.out.println("topics_message2="+msg);
}
应用场景
1. 异步处理
注册服务:
- 串行方式:将注册信息写入数据库—>发送注册邮件–>发送注册短信
- 消息队列方式:客户端没有必要等待全部处理完成后返回,在注册信息写入数据库后就返回,其他动作进入消息队列,延迟处理。
2. 应用解耦
订单库存:
- 普通方式:购买商品,用户下单后,订单系统会通知库存系统,如果库存系统故障,就会导致整个系统无法运行。
- 消息队列方式:购买商品后,订单系统将订单存入消息队列,即使库存系统故障,也能保证订单信息的可靠投递,服务的正常运行
3.流量削峰
秒杀活动:
- 消息队列方式:可以控制活动人数,超过一定阀值的订单直接丢弃。用户请求存入消息队列,系统根据消息队列的数据再进行处理