互聯(lián)網(wǎng)高頻面試題,什么是冪等?如何解決冪等性問(wèn)題
一個(gè)在傳統(tǒng)行業(yè)工作了 7 年的粉絲私信我。說(shuō)他最近去很多互聯(lián)網(wǎng)公司面試,遇到的很多技術(shù)和概念都沒(méi)聽(tīng)過(guò)。其中就有一道題是:”什么是冪等、如何解決冪等性問(wèn)題“?他說(shuō),這個(gè)概念聽(tīng)都沒(méi)聽(tīng)過(guò),怎么可能回答出來(lái)。
接下來(lái),我借這位同學(xué)的問(wèn)題,給大家分享一下我對(duì)這個(gè)問(wèn)題的理解。
1.什么是冪等?
其實(shí)冪等,是一個(gè)數(shù)學(xué)上的概念。而在計(jì)算機(jī)編程領(lǐng)域中,冪等是指一個(gè)方法被多次重復(fù)執(zhí)行的時(shí)候所期望的結(jié)果要和第一次執(zhí)行所期望的結(jié)果保持一致。簡(jiǎn)單理解就是,一個(gè)邏輯即使被重復(fù)執(zhí)行多次,也不影響最終結(jié)果的一致性,這叫冪等。
之所以要考慮到冪等性問(wèn)題,是因?yàn)樵诰W(wǎng)絡(luò)通信中,有這兩種行為都有可能會(huì)導(dǎo)致接口被重復(fù)執(zhí)行。
第一種是,用戶的重復(fù)提交或者用戶的惡意攻擊;
第二種是,分布式系統(tǒng)中,為了避免數(shù)據(jù)丟失,采用的超時(shí)重試機(jī)制。
這兩種情況都有可能導(dǎo)致服務(wù)接口被重復(fù)調(diào)用。所以在程序設(shè)計(jì)中,對(duì)于數(shù)據(jù)變更類操作的接口,需要保證接口的冪等性。
而冪等性的核心思想,其實(shí)就是保證這個(gè)接口的執(zhí)行結(jié)果只影響一次,后續(xù)即便再次調(diào)用,也不能對(duì)數(shù)據(jù)產(chǎn)生影響,所以基于這樣一個(gè)需求,我們?nèi)绾谓鉀Q冪等性問(wèn)題呢?
2.如何解決?
解決冪等性問(wèn)題的方法有很多,下面我分享一下常用幾種方案。
第1種方案,就是使用數(shù)據(jù)庫(kù)的唯一約束來(lái)實(shí)現(xiàn)冪等,比如對(duì)于數(shù)據(jù)插入類的場(chǎng)景,比如創(chuàng)建訂單,因?yàn)橛唵翁?hào)肯定是唯一的,所以如果是多次調(diào)用就會(huì)觸發(fā)數(shù)據(jù)庫(kù)的唯一約束異常,從而避免一個(gè)請(qǐng)求創(chuàng)建多個(gè)訂單的問(wèn)題。
第2種方案,就是使用 Redis 提供的 setNX 指令,比如對(duì)于 MQ 消費(fèi)的場(chǎng)景,為了避免 MQ 重。
復(fù)消費(fèi)導(dǎo)致數(shù)據(jù)多次被修改的問(wèn)題,可以在接受到 MQ 的消息時(shí),把這個(gè)消息通過(guò) setNX 寫入到 Redis 中,一旦這個(gè)消息被消費(fèi)過(guò),就不會(huì)再次消費(fèi)。
第3種方案,使用狀態(tài)機(jī)來(lái)實(shí)現(xiàn)冪等,所謂的狀態(tài)機(jī)是指一條數(shù)據(jù)的完整運(yùn)行狀態(tài)的轉(zhuǎn)換流程,比如 ,因?yàn)樗臓顟B(tài)只會(huì)向前變更,所以多次修改同一條數(shù)據(jù)的時(shí)候,一旦狀態(tài)發(fā)生變更,那么對(duì)這條數(shù)據(jù)修改造成的影響只會(huì)發(fā)生一次。
當(dāng)然,除了以上3種常用的意外,還可以基于 Token 機(jī)制或者增加去重表等方法來(lái)實(shí)現(xiàn),但是不管是什么方法,無(wú)非就是兩種思路,要么就是接口只允許調(diào)用一次,比如唯一約束、基于 Redis 的鎖機(jī)制。
要么就是對(duì)數(shù)據(jù)的影響只會(huì)觸發(fā)一次,比如樂(lè)觀鎖等。
以上就是我對(duì)這個(gè)問(wèn)題的理解。
技術(shù)這個(gè)行業(yè)的發(fā)展是很快的,如果自己的技術(shù)能力和認(rèn)知跟不上變化。那基本上可以說(shuō)是被時(shí)代淘汰了,所以保持持續(xù)學(xué)習(xí)是非常重要的。