分布式服務(wù)之間不可避免要相互通信,通信的結(jié)果有三種:成功,失敗,超時(shí)。而超時(shí)狀態(tài),有可能是接收方?jīng)]有接受到數(shù)據(jù),另一種情況是接受到數(shù)據(jù)處理完了,返回?cái)?shù)據(jù)的過程超時(shí)。一般地我們都會進(jìn)行業(yè)務(wù)補(bǔ)償操作,常見的模式有兩種
1 調(diào)用方查詢,根據(jù)結(jié)果決定是否重傳
2 調(diào)用方重傳,而接受方查詢是否已處理,若是沒有處理則進(jìn)行處理,否則返回結(jié)果。
第二種方式要求接口的冪等的。即一次調(diào)用產(chǎn)生的副作用與多次相同,如果用數(shù)學(xué)公式表示為f(x)=f(f(x))。
如何才能做到冪等呢?
1 首先需要一個(gè)唯一標(biāo)識,如全局唯一id,如UUID,雖然可以保證全局唯一,但是生成的id占用空間太大,不利于索引,而且隨機(jī)性太強(qiáng)無法看懂。比較推薦的是snowflake算法,全局id也可考慮加入業(yè)務(wù)字段。
2 處理的流程大致如下,調(diào)用方發(fā)送帶id的數(shù)據(jù),接受方先判斷此數(shù)據(jù)是否已經(jīng)處理,沒有則處理有則返回之前的處理結(jié)果。
3 流程優(yōu)化,上面的流程,每次都需要進(jìn)行一次查詢,出問題的概率其實(shí)并不大,所以呢,有點(diǎn)浪費(fèi)資源,優(yōu)化后流程:接受方接到請求后執(zhí)行不存在則插入,存在則更新的動作,如insert into ...on duplicate on key update....