首先kafka事務沒辦法做到這一點,事務只能保證以下幾點:
producer發送多條消息,要么同時成功,要么同時失敗;在沒有提交事務之前,消息對消費者不可見,事務失敗需要程序員自己調用kafka的 abort 回滾,kafka不會自己處理回滾,失敗的情況下,這些已經發送的消息會被kafka標記為無效,消費者看不到
? ? ? ? ** 多說一句,kafka事務是分布式事務,比如 producer 發送多條事務,任意一條事務可能發送到 broker1 或者 broker2 ...
對于 消費消息 -> 重新發送kafka -> 提交offset 這個業務場景來說,kafka 事務能保證在程序出現異常的情況下,重新發送到 kafka 的消息無效,也就是消費者看不到這些消息,然后 offset 提交失敗,也就是說消費者還是需要從上一次的offset繼續消費消息
所以如何保證消費者不重復消費消息?
這個需要程序員自己去實現
比如發送消息的時候,可以為消息添加一條唯一 id,然后消費消息的時候,把這個id寫入到數據庫,每次消費消息先從數據庫查詢看有沒有這個id,有的話就是已經消費過了,否則就是第一次消費
再者, 需要手動提交offset,而且提交的間隔不宜過長,比如可以設置每消費10條消息就提交offset,這樣即使消費失敗,最多也就需要判斷10條消息的id,防止消息過多,判斷這么多消息是否被消費過也是一種性能浪費
?