✅消息队列使用拉模式好还是推模式好?为什么?

典型回答

推和拉是两种消息传递的方式

推的模式就消费者端和消息中间件建立TCP长链接或者注册一个回调,当服务端数据发生变化,立即通过这个已经建立好的长连接(或者注册好的回调)将数据推送到客户端。


拉的模式就是消费者轮询,通过不断轮询的方式检查数据是否发生变化,变化的话就把数据拉回来。

如果使用拉的模式来实现消息队列的话,消费者可以完全自己掌控消息的数量及速度,这样可以大大的避免消息堆积的情况。但是,这种方案也有缺点,首先就是消费者需要不断的进行轮询,这种轮询也会对消息中间件造成一定的压力。

如果使用推的模式来实现,好处就是消息是实时的, 一旦有消息过来消费者马上就能感知到。而且对于消费者来说也比较简单,不需要轮询,只需要等推送就行了。但是缺点也比较明显,那就是如果消息的生产速度大于消费速度,可能会导致消息大量堆积在消费者端,会对消费者造成很大的压力,甚至可能把消费者压垮。

一般来说,推的模式适合实时性要求比较高的场景。而拉的模式适合实时性要求没那么高的场景。

还有需要注意的就是,在有些生产环境下,服务器环境只能单向通信,也就是只能通过一端访问另外一端,而不能在反方向通信,此时就需要消费方,使用拉模式,推模式是长链接,是双向通信,所以不行。

在很多中间件的实现上,可能并没有在直接用长连接或者轮询,而是把二者结合了一下,使用长轮询的方式进行拉消息的。

长轮询,就是消费者向消息中间件发起一个长轮询请求,消息中间件如果有消息就直接返回,如果没有也不会立即断开连接,而是等待一会,等待过程中如果有新消息到达,再把消息返回。如果超时还没有消息,那就结束了,等下次长轮询。

比如Kafka和RocketMQ都是支持基于长轮询进行拉取消息的。

原文: https://www.yuque.com/hollis666/xkm7k3/mq3pwg8ge56hfvhx