Kafka RocketMQ 是推还是拉?
推拉模式的时候指的是 Comsumer 和 Broker 之间的交互。
推模式
broker主动推消息给消费者,来一条推一条
优点:来一条推一条,实时性较高
缺点:消费者的消费能力有限,如果一时间大量的消息推过来 消费者并没有能力一下去消费这么多。不同的消费者消费速率可能不同,导致broker维护不同消费者推送速率较困难.
适用于: 消息量不大,消息实时性要求高场景
拉模式
消费者主动的去broker拉消息,消费者可根据自己的消费能力去拉消息
优点:broker只需要存储好生产者发来的数据,具体谁来拉 什么时候拉都不用管了。可以支持批量拉取,消费者根据自身条件选择批量拉取
缺点:消息延迟,消费者可能两秒发一次请求向broker拉数据(不能过于频繁)。 消息忙请求(可能连续拉了几个小时一条消息都没有,做无用功)
RocketMQ 和 Kafka 都选择了拉模式,当然业界也有基于推模式的消息队列如 ActiveMQ
消费者各种各样,身为 Broker 不应该有依赖于消费者的倾向,而是主要负责存储消息,方便消费者自己来拉消息。
RocketMQ 和 Kafka 都是利用“长轮询”来实现拉模式,
长轮询
RocketMQ长轮询
主要是两方面,
一个就是生产者发送拉消息请求到broker,判断一下当前是否有新消息,有就直接返回,没有轮询等待(每5秒重新查一次有没有新消息到了)
再一个就类似观察者模式,消费者的请求会放入pullRequestTable中,新消息来了会通知所有观察者消息到了。
Kafka长轮询
消费者底层最终会调用 Java nio 的 select(timeout),发送请求到broker。
消费者和 Broker 相互配合,拉取消息请求不满足条件的时候 hold 住,避免了多次频繁的拉取动作,当消息一到就提醒返回。