關於web服務的介面冪等性

2021-07-15 20:17:18 字數 1723 閱讀 9207

絕大部分網路上對冪等性的解釋類似於:

"冪等性是指重複使用同樣的引數呼叫同一方法時總能獲得同樣的結果。比如對同一資源的get請求訪問結果都是一樣的。"

我認為這種解釋是非常錯誤的, 冪等性強調的是外界通過介面對系統內部的影響, 外界怎麼看系統和冪等性沒有關係. 就上面這種解釋, system.getcpuload(), 這兩次呼叫返回能一樣嗎? 但因為是唯讀介面, 對系統內部狀態沒有影響, 所以這個函式還是冪等性的.

首先了解一下什麼是冪等性,如果你沒有興趣可以直接跳過這段代數概念解釋 :)

冪等(idempotence)是來自於高等代數中的概念。

定義如下(加入了自己理解):

單目運算, x為某集合內的任意數, f為運運算元如果滿足f(x)=f(f(x)), 那麼我們稱f運算為具有冪等性(idempotent)

比如在實數集中,絕對值運算就是乙個例子: abs(a)=abs(abs(a))

雙目運算,x為某集合內的任意數, f為運運算元如果滿足f(x,x)=x, f運算的前提是兩個引數都同為x, 那麼我們也稱f運算為具有冪等性

比如在實數集中,求兩個數的最大值的函式: max(x,x) = x, 還有布林代數中,邏輯運算 "與", "或" 也都是冪等運算, 因為他們符合and(0,0) = 0, and(1,1) = 1, or(0,0) = 0, or(1,1) = 1

在將冪等性應用到軟體開發中,需要一些更深的理解. 我的理解如下:

數學處理的是運算和數值, 程式開發中往往處理的是物件和函式. 但是我們不能簡單地理解為數學冪等中的運算就是函式,而數值就是物件!!

比如有person物件有兩個屬性weight和age,但是所有的function只能對其中乙個屬性操作. 所以從這個層面我們可以理解為: 函式只對該函式所操作的物件某個屬性具有冪等性, 而不是說對整個物件有運算冪等性.

person 

//不是冪等函式

public void increaseage()

//是冪等函式

public void setweight(int v)

}

還有一點必須要澄清的是: 冪等性所表達的概念關注的是數學層面的運算和數值, 並沒有提及到數值的安全性問題.

比如上面的person的setage函式, 有兩種case不是冪等性所關心的, 但程式開發卻又必須要關心的:

1. 兩個執行緒同時呼叫

2. 因為age從業務上講不可能遞減, 如果前一次呼叫設定是30歲, 後一次呼叫變成了10歲或是更離譜的 -1 歲

所以restful設計中將冪等性和安全性是作為兩個不同的指標來衡量post,put,get,delete操作的:

重要方法

安全?冪等?

get是

是delete否是

put否

是post否否

就象cache有cache基本實現正規化一樣, 冪等也有自己的固定外部呼叫正規化

cache實現正規化:

value getvalue(key)

return value;

}

冪等外部呼叫正規化

client.age = 30;

while(一些退出條件) else

} else return;

} catch(exception)

}

冪等介面的內部實現需要有對內保護機制, 一般情況是用類似於樂觀鎖的版本機制.版本重點是體現時間的先後.

關於介面冪等性的設計

關於支付相關,訂單相關以及一些涉及費用的操作在業務上都是要求介面具有冪等性的。否則在高併發的場景下,同一筆交易請求多次,則會造成損失,這是不可忽視的錯誤。例如一筆訂單,因為網路或者操作的原因,造成同時發起了兩次申請。一般的介面設計中,對於重 起的交易都是先查詢是否存在這筆訂單,如果不存在,則繼續進行...

介面冪等性

例如 在http協議中,get請求,會得到同樣的資料 bool get money id,amount 1引數 id 使用者的賬戶 amount 表示取多少錢 返回值 true 表示取錢成功 false 表示取錢失敗 情景一 1 一位使用者a 取100塊錢,這個請求,傳送到了伺服器 2 伺服器正常的...

介面冪等性

token機制 服務端提供傳送token的介面,在分析業務的時候,哪些業務是存在冪等問題的,就必須在執行業務前,先去獲取token,伺服器會把token儲存到人redis中 然後呼叫業務介面請求時,把token攜帶過去,一般放在請求頭 伺服器判斷token是否存在redis中,存在表示第一次請求,然...