RabbitMQ的 五种工作模型

RabbitMQ 其实一共有六种工作模式:

java 复制代码
简单模式(Simple)、工作队列模式(Work Queue)、
发布订阅模式(Publish/Subscribe)、路由模式(Routing)、通配符模式(Topic)、
远程调用模式(RPC)。

其中发布订阅模式、路由模式、通配符模式这三种模型都属于订阅模式,只不过它们之间进行路由的方式不同罢了。
远程调用模式是RPC不属于MQ,所以最终统计下来就是五种工作模式。

总结:简单模式和工作队列模式,主要是【队列】和【消费者】的关系,一对一、一对多。

订阅模式包含:【交换机】和【队列】的关系,【队列】和【消费者】的关系。

队列和消费者是1对多时,那么就是采用平均的方式分给多个消费。队列里面的消息只有一个消费者会拿到。

一、简单模式(Simple)

【队列】和【消费者】

二、工作队列模式

java 复制代码
工作队列模式(Work Queue)多了一些消费者,该模式也使用direct交换机,应用于处理消息较多的情况。

特点: 一个队列对应多个消费者,通过队列进行消息传递 一条消息只会被一个消费者消费, 
消息队列默认采用轮询的方式将消息平均发送给消费者,使用Rabbitmq默认交换机direct 

应用场景: 对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
java 复制代码
缺点:因为消息是轮询平均发送给消费者。可能会有某个消费者Slow;
因为要处理其他复杂的业务逻辑,其消费的效率相对其他消费者比较慢,这个就会造成当其他消费者已经消费完处于空闲状态。
因平均分配原则,队列任会继续把消息发给 Slow 处于忙碌状态,大大降低了系统的性能。

正确的做法的是"能劳者多劳;消费越快的,让其消费的越多"

三、发布订阅模式、路由模式、通配符模式

他们三个都属于订阅模型,订阅模型的共同点: 生产者,一个交换机(fanoutExchange),多个队列,多个消费者。

生产者将消息不是直接发送到队列,而是发送到X交换机,然后由交换机发送给多个队列,多个消费者分别各自监听一个队列,来消费消息。

java 复制代码
交换机有哪些类型: 
1、Fanout:广播,将消息交给所有绑定到交换机的队列 
2、Direct:定向,把消息交给符合指定routing key 的队列 
3、Topic:通配符是最为常有用的一种,交换机把消息交给符合routing pattern(路由模式)的队列 

应用场景:电商网站的同一条促销信息需要短信发送、邮件发送、站内信发送等。此时可以使用发布订阅模式(Publish/Subscribe)

一、发布订阅模式

java 复制代码
生产者将消息发送给交换机,交换机将消息转发到绑定此交换机的每个队列中,注意是【同一个消息】会转给【所有的队列】。
这里还只是【交换机和队列的关系】,交换机会把一个消息给所有的队列,
但是一个队列,如果绑定多个消费者,那么这个队列,就会采用平均的方式分给消费者。

前面的【工作队列模式】的交换机只能将消息发送给【一个队列】,
而【发布订阅模式】的【交换机】能将【同一个消息】发送给【多个队列】。
注意是多个队列,而且交换机丢给队列的时候,也是采用【轮训】队列的方式,将消息丢给每个队列,发布订阅模式使用fanout交换机。


总结:
订阅模式中,多个消费者同时订阅一个队列,该队列会【轮询】地把消息平均分配给每个消费者,这也就是标准的【工作队列模式】的模型。
通过前面的demo工程可知,我们在使用发布订阅模式时,所有消息都会发送到绑定的队列中。

但很多时候,不是所有消息都【无差别】的发布到所有队列中,因为有的队列处理快有的队列处理慢,这无形当中就会照成不必要的资源浪费。
为了解决这个问题,路由模式就诞生了。

二、路由模式(Routing)

java 复制代码
路由(Routing)模式是发布订阅模式的升级版。
我们知道发布订阅模式是【无条件】地将所有消息分发给【所有消费者队列】,每个队列中都有相同的消息;
路由模式,由上图很容易理解,每个队列消息会因为绑定的路由不同而不同。 

特点:
1、每个队列绑定一个路由关键字RoutingKey,生产者将带有RoutingKey的消息发送给交换机,交换机再根据路由 RoutingKey关键字将消息定向发送到指定的队列中;
2、默认使用 direct 交换机。
java 复制代码
代码:

// 1、建立交换机
exchangeDeclare("exchange_topic", BuiltinExchangeType.TOPIC);

// 2、创建队列
queueDeclare("queue1"...);
queueDeclare("queue2"...);
queueDeclare("queue3"...);

// 3、交换机+队列+routeKey绑定关系
queueBind("queue1", "routeKey1", 交换机);
queueBind("queue2", "routeKey2", 交换机);
queueBind("queue3", "routeKey3", 交换机);

// 6、发送消息,基于routeKey来发
basicPublish("routeKey1", 消息内容1);
basicPublish("routeKey2", 消息内容2);

路由模式是一种精准的匹配,只有设置了 Routing Key 后消息才能进行分发。
但是,我们在实际的工作中开发需求时还有一些非常模糊的情况,比如消费者存在某种交集的联系只要符合某一个条件,
就需要有消息分发获取消息处理业务逻辑。这时候就需要用到"通配符模式"。

三、通配符模式(Topic)

java 复制代码
通配符模式(Topic)是在路由模式的基础上升级,给队列绑定带通配符的路由关键字,
只要消息的RoutingKey能实现通配符匹配而不再是固定的字符串,就会将消息转发到该队列。通配符模式比路由模式更灵活。 

特点:
1、消息设置RoutingKey时,RoutingKey由多个单词构成,中间以 . 分割。
2、队列设置RoutingKey时,#可以匹配任意多个单词,*可以匹配任意一个单词。
3、使用 topic 交换机。

代码:

java 复制代码
// 1、建立交换机
exchangeDeclare("exchange_topic", BuiltinExchangeType.TOPIC);

// 2、创建队列
queueDeclare("queue1"...);
queueDeclare("queue2"...);
queueDeclare("queue3"...);

// 3、交换机+队列+routeKey绑定关系
queueBind("queue1", "#.big.#", 交换机);
queueBind("queue2", "#.middle.#", 交换机);
queueBind("queue3", "#.small.#", 交换机);

// 6、发送消息,基于routeKey来发
channel.basicPublish("big.middle", 消息内容);
channel.basicPublish("small", 消息内容);

五种工作模式:全面解读

相关推荐
宸津-代码粉碎机1 小时前
OpenAI 连夜迎战 Grok Bot 和 Muse:AI 智能体从 “会聊天” 到 “能办事”,现在入场还来得及吗
java·大数据·人工智能·分布式·python
程序猿乐锅3 小时前
【黑马点评 | 第八篇】Redisson分布式锁
java·数据库·spring boot·redis·分布式·spring·缓存
ly76893 小时前
RabbitMQ 消费确认与预取:manual ack、reject、nack 与 QoS 的取舍
rabbitmq·死信队列·消息可靠性·消费确认·qos 预取
灯澜忆梦4 小时前
【RabbitMQ #7】 | 消息转换器
分布式·rabbitmq·ruby
需要8265 小时前
分布式事务:Seata AT/TCC/SAGA 的取舍与踩坑
java·spring boot·分布式·spring·spring cloud
CS创新实验室7 小时前
为什么三台机器就能选出一个“带头大哥“?——Raft 一致性算法,一次讲透
分布式·操作系统
本人手速666+9 小时前
企微开发API如何设计客户冻结状态?WeComApi 在删除、投诉和异常客户场景中的自动化边界
运维·分布式·自动化·企业微信·企微外部群开发·wecomapi·企业微信二次开发
灯澜忆梦10 小时前
【RabbitMQ #4】 | Work 任务模型
分布式·rabbitmq
程序猿乐锅11 小时前
【黑马点评 | 第七篇】Redis 分布式锁的两种实现
java·数据库·redis·分布式·spring·缓存
千里码aicood12 小时前
基于Hadoop的机票价格波动分析系统的设计与实现
大数据·hadoop·分布式