分佈式系統中接口的接口的冪等性如何保證?接口的調用如何保證順序性?

1.分佈式服務接口的冪等性如何設計(比如不能重複扣款)?

 

所謂冪等性,就是說一個接口,多次發起同一個請求,你這個接口得保證結果是準確的,比如不能多扣款,不能多插入一條數據,不能將統計值多加了1。這就是冪等性,不給大家來學術性詞語了。

其實保證冪等性主要是三點:

(1)對於每個請求必須有一個唯一的標識,舉個例子:訂單支付請求,肯定得包含訂單id,一個訂單id最多支付一次,對吧

(2)每次處理完請求之後,必須有一個記錄標識這個請求處理過了,比如說常見的方案是在mysql中記錄個狀態啥的,比如支付之前記錄一條這個訂單的支付流水,而且支付流水採

(3)每次接收請求需要進行判斷之前是否處理過的邏輯處理,比如說,如果有一個訂單已經支付了,就已經有了一條支付流水,那麼如果重複發送這個請求,則此時先插入支付流水,orderId已經存在了,唯一鍵約束生效,報錯插入不進去的。然後你就不用再扣款了。

(4)上面只是給大家舉個例子,實際運作過程中,你要結合自己的業務來,比如說用redis用orderId作爲唯一鍵。只有成功插入這個支付流水,纔可以執行實際的支付扣款。

要求是支付一個訂單,必須插入一條支付流水,order_id建一個唯一鍵,unique key 所以你在支付一個訂單之前,先插入一條支付流水,order_id就已經進去了

你就可以寫一個標識到redis裏面去,set order_id payed,下一次重複請求過來了,先查redis的order_id對應的value,如果是payed就說明已經支付過了,你就別重複支付了

然後呢,你再重複支付這個訂單的時候,你寫嘗試插入一條支付流水,數據庫給你報錯了,說unique key衝突了,整個事務回滾就可以了

來保存一個是否處理過的標識也可以,服務的不同實例可以一起操作redis。

 

2.分佈式服務接口請求的順序性如何保證?

首先,一般來說,我個人給你的建議是,你們從業務邏輯上最好設計的這個系統不需要這種順序性的保證,因爲一旦引入順序性保障,會導致系統複雜度上升,而且會帶來效率低下,熱點數據壓力過大,等問題。

下面我給個我們用過的方案吧,簡單來說,首先你得用dubbo的一致性hash負載均衡策略,將比如某一個訂單id對應的請求都給分發到某個機器上去,接着就是在那個機器上因爲可能還是多線程併發執行的,你可能得立即將某個訂單id對應的請求扔一個內存隊列裏去,強制排隊,這樣來確保他們的順序性。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章