RabbitMQ的使用场景

1.服务间异步通信:通过把把消息发送给消息中间件,消息中间件并不立即处

2.顺序消费:拆分多个 queue,每个 queue 一个 consumer,就是多一些 queue 而已,确实是麻烦点;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。

3.定时任务:
用户创建定时任务
往死信队列插入一条消息,并设置过期时间为首个任务执行时间
死信队列中的消息过期后,消息流向工作队列
任务执行消费者监听工作队列,工作队列向消费者推送消息
消费者查询数据库,读取任务信息
消费者确认任务有效(未被撤销),执行任务
消费者确认有下个任务,再往死信队列插入一条消息,并设置过期时间为任务执行时间
重复2-7的步骤,直到所有任务执行完成或任务撤销

4.请求削峰:在访问量剧增的情况下,但是应用仍然需要发挥作用,但是这样的突发流量并不常见。而使用消息中间件采用队列的形式可以减少突发访问压力,不会因为突发的超时负荷要求而崩溃

5.解耦:在项目启动之初是很难预测未来会遇到什么困难的,消息中间件在处理过程中插入了一个隐含的,基于数据的接口层,两边都实现这个接口,这样就允许独立的修改或者扩展两边的处理过程,只要两边遵守相同的接口约束即可

场景1:单发送单接收

使用场景:简单的发送与接收,没有特别的处理。

消息队列服务api接口 消息队列使用教程_消息队列服务api接口

场景2:单发送多接收

使用场景:一个发送端,多个接收端,如分布式的任务派发。为了保证消息发送的可靠性,不丢失消息,使消息持久化了。同时为了防止接收端在处理消息时down掉,只有在消息处理完成后才发送ack消息。

消息队列服务api接口 消息队列使用教程_rabbitmq_02


发送端和场景1不同点:

1、使用“task_queue”声明了另一个Queue,因为RabbitMQ不容许声明2个相同名称、配置不同的Queue

2、使"task_queue"的Queue的durable的属性为true,即使消息队列durable

3、使用MessageProperties.PERSISTENT_TEXT_PLAIN使消息durable

接收端和场景1不同点:
1、使用“task_queue”声明消息队列,并使消息队列durable
2、在使用channel.basicConsume接收消息时使autoAck为false,即不自动会发ack,由channel.basicAck()在消息处理完成后发送消息。
3、使用了channel.basicQos(1)保证在接收端一个消息没有处理完时不会接收另一个消息,即接收端发送了ack后才会接收下一个消息。在这种情况下发送端会尝试把消息发送给下一个not busy的接收端。

场景3:Publish/Subscribe

使用场景:发布、订阅模式,发送端发送广播消息,多个接收端接收。

消息队列服务api接口 消息队列使用教程_消息队列服务api接口_03


发送端:

发送消息到一个名为“logs”的exchange上,使用“fanout”方式发送,即广播消息,不需要使用queue,发送端不需要关心谁接收。

接收端:
1、声明名为“logs”的exchange的,方式为"fanout",和发送端一样。
2、channel.queueDeclare().getQueue();该语句得到一个随机名称的Queue,该queue的类型为non-durable、exclusive、auto-delete的,将该queue绑定到上面的exchange上接收消息。
3、注意binding queue的时候,channel.queueBind()的第三个参数Routing key为空,即所有的消息都接收。如果这个值不为空,在exchange type为“fanout”方式下该值被忽略!

场景4:Routing (按路线发送接收)

使用场景:发送端按routing key发送消息,不同的接收端按不同的routing key接收消息。

消息队列服务api接口 消息队列使用教程_消息队列服务api接口_04


发送端和场景3的区别:

1、exchange的type为direct

2、发送消息的时候加入了routing key

接收端和场景3的区别:

在绑定queue和exchange的时候使用了routing key,即从该exchange上只接收routing key指定的消息。

场景5:Topics (按topic发送接收)

使用场景:发送端不只按固定的routing key发送消息,而是按字符串“匹配”发送,接收端同样如此。

消息队列服务api接口 消息队列使用教程_java_05


发送端和场景4的区别:

1、exchange的type为topic

2、发送消息的routing key不是固定的单词,而是匹配字符串,如"*.lu.#",*匹配一个单词,#匹配0个或多个单词。

接收端和场景4的区别:
1、exchange的type为topic
2、接收消息的routing key不是固定的单词,而是匹配字符串。