來源於 https://blog.csdn.net/qq_34796981/article/details/80777181
事件描述
公司使用的是Spring Cloud工作的微服務框架。其中做了SpringBoot和kafka的結合。但是意外的是enable.auto.commit參數設置成了false,kafka的offset依然提交了(也沒有進行人工提交offset)。為了驗證這個是否為真實情況,首先測試環境啟動項目,enable.auto.commit設置為false。首先記錄測試topic的偏移量和logsize(測試topic名字為topicTest),然后本地啟動Producer,向topicTest發送10條數據,通過kafka manager觀察是否發送到broker。經過查看,消息確實發送到了topicTest中。然后啟動Consumer來消費,其中消費組為groupTest。查看kafka manager結果發現offset竟然偏移了。
心中很是郁悶,於是再向topicTest發送10條數據,自己寫了個Consumer的main方法,配置也是enable.auto.commit為false。然后啟動開始消費,驚人的情況出現了,offset並沒有發生偏移。那么這就可以肯定問題出在了spring結合kafka這個點上。
查看spring的源碼查找問題
為什么enable.auto.commit設置為false了依然會提交。猜測一定是spring做了什么手腳所以才導致的提交。打斷點,追蹤斷點到KafkaMessageListenerContainer這個類里。可以發現一個很顯眼的地方。
如果我們enable.auto.commit設置為false,那么就會走標紅的if語句。而且下面有個stopInvokerAndCommitManualAcks()方法,看名字就知道是人工提交的意思。那么我們進去stopInvokerAndCommitManualAcks()方法瞅瞅。
如上圖所示有個processCommits()方法,那么繼續追進去:
單單看標紅的方法是不是就知道這方法里面是更新offset和提交offset的方法。那么我們繼續追進去:
看到這里是不是豁然開朗了。這tm明顯是手動提交offset的代碼啊。至此,終於明白為什么SpringBoot和Kafka結合后,用Spring的方法來初始化enable.auto.commit參數為false,offset依然會提交。
結論:Spring做為一個框架很明顯是想減少我們的工作量。這就造成,如果我們把enable.auto.commit參數設置成true。那么offset交給kafka來管理,offset進行默認的提交模式。
enable.auto.commit參數設置成false。那么就是Spring來替為我們做人工提交,從而簡化了人工提交的方式。
所以kafka和springboot結合中的enable.auto.commit為false為spring的人工提交模式。enable.auto.commit為true是采用kafka的默認提交模式。
最后終於送了一口氣,要是enable.auto.commit的設置為false,而且沒有進行人工提交offset,那么這將是一個巨大的工程事故。別看只是一個小小的參數。辛虧,Spring的開發者早已料到這一刻,從而防止小白忘記手動提交offset。另一方面也減少了開發的難易程度。