業務設計原則 冪等設計

2021-09-28 23:21:52 字數 2279 閱讀 2435

一 介紹

在傳統的單體應用架構中,即同乙個程序內,對於乙個函式,或者一系列的函式呼叫,結果只有兩種,要麼成功,要麼失敗(我們可以通過事務的方式控制多個函式的事務呼叫)

但是在分布式架構系統中,服務與服務之間的呼叫通過網路遠端rpc呼叫的時候,除了呼叫成功或者失敗之外,還會出現第三個結果–超時,超時是分布式架構中,最為複雜的場景,

二 問題

我們以乙個簡單的示例為例,假設有乙個商品**,商品實際的庫存資料總和儲存在表t_goods中num欄位上,現在有乙個商品被購買,這個時候我們就需要通過一系列的操作,將商品表中的num資料減一。我們以商品發起扣款的服務為web,後端進行實際扣款的服務為service,中間的服務的排程為dubbo

實際上,對於dubbo而言,當我們的web發起dubbo呼叫進行商品庫存資料扣除的時候,如果呼叫超時,因為dubbo自身的重試機制,假設重試了3次,那麼我們第4四步中的簡單的資料t_goods 的num就會多次-1操作,這個顯然是在分布式系統中不允許的,

這個時候,我們就需要對業務的邏輯處理進行冪等性設計

什麼是冪等性

冪等性是分布式架構中對應業務涉及的乙個基本原則,他的設計思路即使用者對於同乙個操作(這個也可以理解服務以服務之間的方法呼叫),發起的一次請求或者是多次請求的結果都是一致的,不會因為多次請求而產生對應的***

如何做冪等設計

顯然,對應上面簡單的商品庫存容量的扣除,正是因為4的步驟不是冪等性,dubbo排程服務的重試機制最終導致了多次的操作影響了商品的實際庫存。

那麼我們應該如何進行冪等設計呢?

應用程式的冪等操作

對於應用程式而言,我們還是以上面的例子為例,對於3,dubbo呼叫,我們在dubbo呼叫中,將2步驟中對於指定訂單生成的orderid附帶傳遞到service中,對應4的操作,我們首先要驗證該orderid是否已經執行了商品數量扣除(日誌記錄),如果是,我們直接返回對應的扣除資訊,如果不是,我們再執行對應的商品數扣除操作

通過狀態機設計

涉及到資金交易的系統,通常會把交易流程分解成多個階段,每乙個階段用不同的狀態來標識。如在訂單受理或初始化階段,把訂單狀態設為0;開始付款時設為1,標識當前訂單是處於付款中狀態;支付完成後,根據實際的結果,將訂單狀態設為成功或者失敗。

我們在以商品交易為準,對於訂單支付的介面pay()介面實現的冪等偽**:

//1.查詢當前訂單

select order_status from t_pay where order_id=# and system_no='訂單系統'

訂單已經存在且狀態為終態,則直接返回

if("2".equals(orderstatus))

if("3".equals(orderstatus))

訂單已經存在且狀態非終態

if("1".equals(orderstatus))

訂單初始化

if("0".equals(orderstatus))

訂單不存在

if(null==orderstatus),'0',#,#,...)

各種準備工作,如路由,記賬等

更新為付款中

update t_pay set order_status='1' where order_id=# and system_no='訂單系統' and order_status='0'

//4.呼叫支付

status=dopay(accountid,amount);

更新訂單狀態

update t_pay set order_status=# where order_id=# and system_no='訂單系統' and order_status='1'

return status;

}

資料庫方面的考慮

在實際生產的高併發、高複雜業務中,僅僅靠應用程式做冪等性設計是不足的。如在上例中的極限情況下,兩筆相同的扣庫存總數同時執行的時候,因為這個時候對應商品數量扣除記錄中都不存在了當前orderid對應的扣除記錄,所以這兩筆還是能夠同時進行扣除操作。

針對這種請求,我們可以分布式鎖和資料庫的唯一性索引進行約定。

介面冪等設計

在系統設計時,經常會出現每次操作結果都需要一致的場景。比如典型的restful get請求 每次請求url student 1 查詢第乙個學生 結果都是一樣的。當然排除再修改學生資訊後又查詢的情況。介面冪等,通俗的定義可以為 每次同樣的請求操作該介面,得到的結果都是一樣的。先給個場景,同樣的訂單編號...

介面冪等性設計

在系統中,乙個介面執行多次,與執行一次的效果是一致的 冪等性的核心思想 通過唯一的業務單號保證冪等 update自身帶鎖。直接update不會出現併發修改問題。樂觀鎖是先查詢在修改 update 商品表 set 庫存 庫存 購買量 version 查詢version值 1 where version...

業務模組的設計原則

以下內容是工作中的幾點總結,總結的上下文是在關聯式資料庫的設計環境,還請各位朋友多多發表以下自己的想法。1 模組的最小單位根據乙個完整事務設計 2 模組的最小單位根據乙個完整流程設計 3 模組中,只能應用資料庫的連線,不能夠修改資料庫的連線,最好是在new方法中,獲取資料庫連線。4 業務模組中的演算...