背景:
項(xiàng)目中分C端和B端,數(shù)據(jù)通過(guò)redis同步苍凛,我在內(nèi)存里做了緩存,期望B端通過(guò)mq發(fā)送更新消息兵志,C端來(lái)實(shí)現(xiàn)主動(dòng)更新醇蝴,避免每次都進(jìn)行檢測(cè),項(xiàng)目選型使用了rabbitmq想罕,在一個(gè)生產(chǎn)者悠栓,多個(gè)消費(fèi)者的情景下發(fā)現(xiàn)。
根據(jù)場(chǎng)景提取需求:
1.隊(duì)列中消息應(yīng)該是即時(shí)的按价,不用消費(fèi)之前的消息惭适。
2.生產(chǎn)者發(fā)送的消息必須能夠被所有消費(fèi)者消費(fèi)到。
經(jīng)過(guò)探索rabbitmq并不能像kafka一樣楼镐,多個(gè)消費(fèi)者通過(guò)配置消費(fèi)模式癞志,不能保證所有C端都能接收到更新消息。
相關(guān)文檔
RabbitMQ tutorial - Publish/Subscribe — RabbitMQ官方文檔exchange框产、queue布置圖
node.js - RabbitMQ / AMQP: single queue, multiple consumers for same message? - Stack Overflow關(guān)于這種需求場(chǎng)景的討論
RabbitListener綁定隊(duì)列到多個(gè)交換 - Thinbug最終解決方案
Solution:
rabbitmq多個(gè)消費(fèi)者綁定同一隊(duì)列凄杯,默認(rèn)是通過(guò)Round-robin dispatching的模式错洁,保證一個(gè)消息只能被消費(fèi)一次,并不能滿足我們的需求戒突。那只有通過(guò)發(fā)送消息到一個(gè)exchange中屯碴,然后分發(fā)到多個(gè)queue實(shí)現(xiàn),但通過(guò)@bean的方式聲明又會(huì)導(dǎo)致queue重名妖谴。
所以最好的方法就是建立臨時(shí)queue窿锉,用后就可以刪除數(shù)據(jù),臨時(shí)queue又可以自動(dòng)生成queue名膝舅,避免沖突嗡载。
@RabbitListener(bindings = @QueueBinding(
value = @Queue(),
exchange = @Exchange(value = NOTIFY_EXCHANGE_NAME,type = ExchangeTypes.FANOUT,durable = "false")
)
)
public void listen(String aId) {
log.info("[aId:{}] got notify from mq, init.", aId);
}