消費端要保證消費的順序性赶诊。
多個消息可能來源于一臺機器吱型,也可能來源于一個集群的多臺機器逸贾,也可能來源多個集群。消費者如何去保證消息的有效性?
可以借助"雙端列表"的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)消息節(jié)點的有效性耕陷。
場景:
- 消息1到達(dá)后掂名,直接進(jìn)行消費;
- 消息2到達(dá)后哟沫,在消息2的后繼指針域中獲取到消息1的key,去redis中進(jìn)行查詢:
2.1 若消息1不存在锌介,那么證明消息1未達(dá)到嗜诀,消息2存儲到Redis;
2.2 若消息1存在且狀態(tài)是已消費孔祸,那么消費者消費消息2隆敢,并且查詢消息2的后繼指針,查詢消息3是否存在崔慧,若消息3存在拂蝎,那么直接消費消息3。
2.3 若消息1存在且狀態(tài)是正在消費惶室,那么消息2阻塞1s(根據(jù)實際業(yè)務(wù)定阻塞時間,也可以通過CAS實現(xiàn)),1s后再次查詢redis阔墩,若消息1還是正在消費描姚,那么將消息2放入到延時隊列。若消息1狀態(tài)變?yōu)橐严M夹界,那么直接去消費消息2馆里。 - 當(dāng)消息3到達(dá)后,根據(jù)后繼指針查詢消息2可柿,若發(fā)現(xiàn)消息2未消費鸠踪,那么存儲消息3。
注意:
- 使用Lua腳本保證修改Redis消息狀態(tài)和獲取消息的原子性复斥。
- 消息的刪除:消息消費后营密,刪除Redis中消息實體,只保留狀態(tài)永票。(例如消息3的狀態(tài)是已消費卵贱,那么可以將消息1,2進(jìn)行永久刪除)侣集。
- 工作竊燃恪:當(dāng)消費者空閑時,可以直接去Redis獲取任務(wù)進(jìn)行處理世分。