消息队列一点感想
最简单的架构,使用master+worker的方式,一个master,多个worker,每个worker用于处理消息的接收和投递,而master用于管理各个worker,实际工作还是由worker进行。
不同的消息模式
发布-订阅模式
该模式下生产者向worker投递一个消息,worker push 到队列中,worker 会将这份消息投递给所有订阅了该消息的消费者。同时可以配置是否存入数据库,即是一次消费还是可以多次消费。
该场景类似于广播,A事件发生后,所有关注A事件的服务都需要作出相应的处理,比如通讯录模块的某人离职,其余的服务要做相应处理,这就是发布订阅,如果同一个服务又分布在很多不同的服务器上,则所有的进程都要被通知到。
点对点模式
该模式下一个topic可以有多个消费者,但是一个消息同时只能有一个消费者消费。该场景类似于RPC调用,比如某个回款服务新增一个回款,那么订单服务也需要作出同步更新其回款信息,此时回款服务发出一个消息,只有订单服务需要关注这个消息。
对于以上两种场景,如果一个服务有多个进程,那么每个进程都是一个消费者,为了区分出不同的进程,要在TOPIC 中加入特定标识某个进程的字段,才能保证每个进程处理特定的数据。
调查模式
查询所有的感兴趣的消息
负载均衡模式
点对点模式的优化,将消息分发给不同的消费者消费。
思路
每个worker 会收到两种请求:
- 来自生产者和消费者的连接请求,此时 worker 保存对端的连接,同时判断如果是消费者则进行一次消息投递
- 来自生产者发布消息的请求,收到消息后进行一次消息投递
针对以上场景,一次消息投递的逻辑如下:
- 发布订阅模式,遍历队列中的所有消息,对每一则消息,如果要求持久化,则先存到DB,然后投递给所有的消费者,任意一个消费者投递失败不管。如果不要求持久化,则直接投递到消费者。这里不关注是否成功的回调
- 点对点模式,遍历队列中的所有消息,对每一则消息,只投递给第一个消费者
- 负载均衡模式,其实是点对点模式的一种优化,旨在将短时间内的大量请求,分散平均到每个消费者上。与点对点模式的差别在于,投递的消费者每次是不一样的。选择消费者的方式有多种,比如轮询,或者hash散列。轮询模式下,使用一个flag指向已经使用过的消费者,使用后就后移。hash 散列模式下,根据不同的hash算法取出消费者。