何爲冪等可重試(安全操作)

google了一些中文的資料, 基本瞭解了冪等是怎麼回事兒. 備忘一下. 

PUT,DELETE操作是冪等的。所謂冪等是指不管進行多少次操作,結果都一樣。比如我用PUT修改一篇文章,然後在做同樣的操作,每次操作後的結果並沒有不同,DELETE也是一樣。順便說一句,因爲GET操作是安全的,所以它自然也是冪等的。 

POST操作既不是安全的,也不是冪等的,比如常見的POST重複加載問題:當我們多次發出同樣的POST請求後,其結果是創建出了若干的資源。 

安全和冪等的意義在於:當操作沒有達到預期的目標時,我們可以不停的重試,而不會對資源產生副作用。從這個意義上說,POST操作往往是有害的,但很多時候我們還是不得不使用它。 

還有一點需要注意的就是,創建操作可以使用POST,也可以使用PUT,區別在於POST是作用在一個集合資源之上的(/articles),而PUT操作是作用在一個具體資源之上的(/articles/123),再通俗點說,如果URL可以在客戶端確定,那麼就使用PUT,如果是在服務端確定,那麼就使用POST,比如說很多資源使用數據庫自增主鍵作爲標識信息,而創建的資源的標識信息到底是什麼只能由服務端提供,這個時候就必須使用POST。 

一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。冪等操作對於代理和緩存來說具有“友好性”,因爲冪等操作的額外執行不會對二者產生危害性後果(除了帶寬浪費)。 
PUT方法是冪等的,冪等性意味着對於一個成功執行的請求,不管其執行多少次,其結果都是一致的。也就是說,只要你願意,你可以用PUT方法對 Hotel資源進行任意次更新,其結果都一樣。如果兩個PUT方法同時發生,那麼只有其中之一會贏得最後的勝利並決定資源的最終狀態。刪除操作也是冪等的,如果一個PUT方法和DELETE方法同時發生,那麼資源或者被更新,或者被刪除,而不可能停留在某個中間狀態。 

如果你不確定是PUT還是DELETE被成功執行,並且沒有得到狀態碼409 (Conflict)或者 417 (Expectation Failed)的話,那麼就重新執行一遍。而不需要附加的可靠性協議來避免重複請求,因爲通常重複的請求不會有任何影響。 

上述描述對於POST方法就不適用了,因爲POST方法不是冪等的,若要兩次執行同一個POST請求那就要注意了。POST方法所缺失的冪等性就解釋了爲什麼當你每次重新發送POST請求時瀏覽器總是彈出警告。POST方法用於創建資源,而不需要由客戶端指定實例id 

冪等函數,或冪等方法,是指可以使用相同參數重複執行,並能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重複執行會對系統造成改變。例如,“getUsername()”函數就是一個冪等函數,“deleteFile()”函數就不是。“冪等”是HTTP Session和EJB失敗轉移中的一個重要概念。 
當正在進行方法調用的時候失敗了怎麼辦呢?答案是:處理過程中止,客戶端看見錯誤消息提示(除非方法是冪等方法)。只有方法是冪等方法的情況,一些負載均衡器才能試圖失敗轉移這些方法到別的實例。 

冪等爲何如此重要?因爲客戶端並不知道服務器何時失敗的(在方法剛開始調用或者快要調用完成的時候)。如果是非冪等方法,則兩次調用就會兩次改變系統狀態,系統就會處於不一致的狀態。 

在複雜應用中,不太可能把所有的方法都變成冪等方法。所以,只能通過失敗轉移減少錯誤,而不可能從根本上避免錯誤。 

把應用程序設計爲冪等的:冪等的的意思就是一個操做不會修改狀態信息,並且每次操作的時候都返回同樣的結果(換句話說就是:做多次和做一次的效果是一樣的),通常,WEB請求,特別是 HTML forms 都被髮送多次(當用戶點擊發送按紐兩次,重載頁面多次),導致多次HTTP請求。設計SERVLET和其他WEB對象爲 冪等的,可以容忍多次請求。詳細可以去參考設計模式“Synchronized Token ”和“Idempotent Receiver ”關於怎樣設計冪等的的應用程序。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章