生產(chǎn)環(huán)境重復(fù)消費(fèi)消息的問(wèn)題
- 問(wèn)題
生產(chǎn)環(huán)境由用戶反映同一張發(fā)票收到幾十條短信和相關(guān)郵件
分析
用戶收到短信和郵件是發(fā)生在平臺(tái)推送發(fā)票的環(huán)節(jié)精居,通過(guò)查看線上日志,將問(wèn)題定位在IInvoiceService#recvInvoice處,在dubbo調(diào)用方時(shí)拋出TimeoutException。
查看此方法的代碼,這個(gè)方法的核心業(yè)務(wù)是發(fā)送短信众雷,發(fā)送郵件,修改數(shù)據(jù)。由于這些方法都是同步調(diào)用砾省,而且其中涉及到很多網(wǎng)絡(luò)IO操作鸡岗,耗時(shí)過(guò)長(zhǎng)是必然的現(xiàn)象。
由于rpc調(diào)用拋出了異常编兄,而rpc調(diào)用本身則是在消息隊(duì)列消費(fèi)過(guò)程轩性,消息隊(duì)列接收到這個(gè)異常,就會(huì)重試這個(gè)消息翻诉,但是由于每次重試都會(huì)超時(shí)炮姨,那么就造成業(yè)務(wù)上的死循環(huán)。而dubbo服務(wù)的提供者并沒(méi)有因?yàn)檎{(diào)用方拋出異常就停止執(zhí)行碰煌,所以每一次都會(huì)給客戶發(fā)送短信和郵件舒岸,就會(huì)導(dǎo)致客戶重復(fù)收到短信和郵件-
思考
通過(guò)上面的分析,問(wèn)題已經(jīng)很明確芦圾,超時(shí)導(dǎo)致了異常蛾派,異常導(dǎo)致了重試。這其中涉及了兩個(gè)中間件个少,dubbo和rocketmq洪乍。 解決方案
1.dubbo服務(wù)調(diào)用中涉及網(wǎng)絡(luò)IO的操作,可以考慮同步變異步卸伞,容忍失敗
2.dubbo服務(wù)做冪等性處理
3.rocketmq消息消費(fèi)過(guò)程中必須嚴(yán)格控制異常抹镊,正確理解返回值的業(yè)務(wù)意義
4.rocketmq消息消費(fèi)要做好消息重復(fù)消費(fèi)的控制