面試官心理剖析: 主要是看你對消息隊列數據重復消費的問題,是否有了解,是否知道怎么解決?如果這塊不知道,那么面試官會覺得如果交給你做功能,可能會出現多次消費的情況。
回答:
為什么會出現重復消費? 分析: 如圖,在什么場景會出現消息重復消費?比如說消費端已經消費了 offset=2,offset=3,offset=4 的三條數據,正准備把這個 offset 的值傳給 kafka,這時候消費端機器宕機了,這個數據沒傳過去;重啟之后,消費端同步 kafka,kafka 那邊消費的記錄 offset 還是 1,那么 kafka 會認為之前的 2、3、4 都沒有消費過,會把這幾個數據在傳給消費端;這樣消費端這邊就重復對這幾條數據進行消費了。在數據庫里面可能就多了很多重復的數據。 像其他的 MQ,也是一樣,消費端再返回給 MQ 的時候,當機了或者重啟了,那么都會出現重復消費的問題。
問題解決:
冪等性:一個請求,不管重復來多少次,結果是不會改變的。
每個消息都會有唯一的消息 id。 1)、先查再保存 每次保存數據的時候,都先查一下,如果數據存在了那么就不保存。這個情況是並發不高的情況。
2)、業務表添加約束條件 如果你的數據庫將來都不會分庫分表,那么可以在業務表字段加上唯一約束條件(UNIQUE),這樣相同的數據就不會保存為多份。
3)、添加消息表 再數據庫里面,添加一張消息消費記錄表,表字段加上唯一約束條件(UNIQUE),消費完之后就往表里插入一條數據。因為加了唯一約束條件,第二次保存的時候,mysql 就會報錯,就插入不進去;通過數據庫可以限制重復消費。
4)、使用 redis 如果你的系統是分布式的,又做了分庫分表,那么可以使用 redis 來做記錄,把消息 id 存在 redis 里,下次再有重復消息 id 在消費的時候,如果發現 redis 里面有了就不能進行消費。
5)、高並發下 如果你的系統並發很高,那么可以使用 redis 或者 zookeeper 的分布式對消息 id 加鎖,然后使用上面的幾個方法進行冪等性控制。
鏈接:https://hacpai.com/article/1542160729029
來源:黑客派