推拉模式的時候指的是 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 住,避免了多次頻繁的拉取動作,當消息一到就提醒返回。