<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.tuicool.com/articles/fymANrJ


    冪等概念來自數學,表示N次變換和1次變換的結果是相同的。這里討論在某些場景下,客戶端在調用服務沒有達到預期結果時,會進行多次調用,為避免多次重復的調用對服務資源產生副作用,服務提供者會承諾滿足冪等。

    舉個栗子,雙十一零點剛過,小明就迫不及待地點擊提交訂單按鈕,選擇在線支付,點了確認支付按鈕,這時候網絡有些慢,小明擔心心愛的商品被搶購一空,就點了多次確認付款按鈕,如果這個訂單扣款多次,客服熱線估計會被小明打爆。

    什么是冪等性

    HTTP/1.1中對冪等性的定義是:一次和多次請求某一個資源 對于資源本身 應該具有同樣的副作用(網絡超時等問題除外)。也就是說, 其任意多次執行對資源本身所產生的影響均與一次執行的影響相同 。

    Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

    這里需要關注幾個重點:

    1. 冪等不僅僅只是一次(或多次)請求對資源沒有副作用(比如查詢數據庫操作,沒有增刪改,因此沒有對數據庫有任何影響)。
    2. 冪等還包括第一次請求的時候對資源產生了副作用,但是以后的多次請求都不會再對資源產生副作用。
    3. 冪等關注的是以后的多次請求是否對資源產生的副作用,而不關注結果。
    4. 網絡超時等問題,不是冪等的討論范圍。

    冪等性是系統服務對外一種承諾(而不是實現),承諾只要調用接口成功,外部多次調用對系統的影響是一致的。聲明為冪等的服務會認為外部調用失敗是常態,并且失敗之后必然會有重試。

    什么情況下需要冪等

    業務開發中,經常會遇到重復提交的情況,無論是由于網絡問題無法收到請求結果而重新發起請求,或是前端的操作抖動而造成重復提交情況。

    在交易系統,支付系統這種重復提交造成的問題有尤其明顯,比如:

    1. 用戶在APP上連續點擊了多次提交訂單,后臺應該只產生一個訂單;
    2. 向支付寶發起支付請求,由于網絡問題或系統BUG重發,支付寶應該只扣一次錢。
      很顯然,聲明冪等的服務認為,外部調用者會存在多次調用的情況,為了防止外部多次調用對系統數據狀態的發生多次改變,將服務設計成冪等。

    冪等VS防重

    上面例子中小明遇到的問題,只是重復提交的情況,和服務冪等的初衷是不同的。重復提交是在第一次請求已經成功的情況下,人為的進行多次操作,導致不滿足冪等要求的服務多次改變狀態。而冪等更多使用的情況是第一次請求不知道結果(比如超時)或者失敗的異常情況下,發起多次請求,目的是多次確認第一次請求成功,卻不會因多次請求而出現多次的狀態變化。

    什么情況下需要保證冪等性

    以SQL為例,有下面三種場景,只有第三種場景需要開發人員使用其他策略保證冪等性:

    1. SELECT col1 FROM tab1 WHER col2=2 ,無論執行多少次都不會改變狀態,是天然的冪等。
    2. UPDATE tab1 SET col1=1 WHERE col2=2 ,無論執行 成功 多少次 狀態 都是一致的,因此也是冪等操作。
    3. UPDATE tab1 SET col1=col1+1 WHERE col2=2 ,每次執行的結果都會發生變化,這種不是冪等的。

    為什么要設計冪等性的服務

    冪等可以使得客戶端邏輯處理變得簡單,但是卻以服務邏輯變得復雜為代價。滿足冪等服務的需要在邏輯中至少包含兩點:

    1. 首先去查詢上一次的執行狀態,如果沒有則認為是第一次請求
    2. 在服務改變狀態的業務邏輯前,保證防重復提交的邏輯

    冪等的不足

    冪等是為了簡化客戶端邏輯處理,卻增加了服務提供者的邏輯和成本,是否有必要,需要根據具體場景具體分析,因此除了業務上的特殊要求外,盡量不提供冪等的接口。

    1. 增加了額外控制冪等的業務邏輯,復雜化了業務功能;
    2. 把并行執行的功能改為串行執行,降低了執行效率。

    保證冪等策略

    冪等需要通過 唯一的業務單號 來保證。也就是說相同的業務單號,認為是同一筆業務。使用這個唯一的業務單號來確保,后面多次的相同的業務單號的處理邏輯和執行效果是一致的。

    下面以支付為例,在不考慮并發的情況下,實現冪等很簡單:①先查詢一下訂單是否已經支付過,②如果已經支付過,則返回支付成功;如果沒有支付,進行支付流程,修改訂單狀態為‘已支付’。

    防重復提交策略

    上述的保證冪等方案是分成兩步的,第②步依賴第①步的查詢結果,無法保證原子性的。在高并發下就會出現下面的情況:第二次請求在第一次請求第②步訂單狀態還沒有修改為‘已支付狀態’的情況下到來。既然得出了這個結論,余下的問題也就變得簡單:把查詢和變更狀態操作加鎖,將并行操作改為串行操作。

    樂觀鎖

    如果只是更新 已有 的數據,沒有必要對業務進行加鎖,設計表結構時使用樂觀鎖,一般通過version來做樂觀鎖,這樣既能保證執行效率,又能保證冪等。例如:

    UPDATE tab1 SET col1=1,version=version+1 WHERE version=#version# 

    不過,樂觀鎖存在失效的情況,就是常說的ABA問題,不過如果version版本一直是自增的就不會出現ABA的情況。(從網上找了一張圖片很能說明樂觀鎖,引用過來,出自 Mybatis對樂觀鎖的支持 )

    防重表

    使用訂單號orderNo做為去重表的唯一索引,每次請求都根據訂單號向去重表中插入一條數據。第一次請求查詢訂單支付狀態,當然訂單沒有支付,進行支付操作,無論成功與否,執行完后更新訂單狀態為成功或失敗,刪除去重表中的數據。后續的訂單因為表中唯一索引而插入失敗,則返回操作失敗,直到第一次的請求完成(成功或失敗)。 可以看出防重表作用是加鎖的功能。

    分布式鎖

    這里使用的防重表可以使用分布式鎖代替,比如Redis。訂單發起支付請求,支付系統會去Redis緩存中查詢是否存在該訂單號的Key,如果不存在,則向Redis增加Key為訂單號。查詢訂單支付已經支付,如果沒有則進行支付,支付完成后刪除該訂單號的Key。通過Redis做到了分布式鎖,只有這次訂單訂單支付請求完成,下次請求才能進來。相比去重表,將放并發做到了緩存中,較為高效。思路相同, 同一時間只能完成一次支付請求 。

    token令牌

    這種方式分成兩個階段:申請token階段和支付階段。

    第一階段,在進入到提交訂單頁面之前,需要訂單系統根據用戶信息向支付系統發起一次申請token的請求,支付系統將token保存到Redis緩存中,為第二階段支付使用。

    第二階段,訂單系統拿著申請到的token發起支付請求,支付系統會檢查Redis中是否存在該token,如果存在,表示第一次發起支付請求,刪除緩存中token后開始支付邏輯處理;如果緩存中不存在,表示非法請求。

    實際上這里的token是一個信物,支付系統根據token確認,你是你媽的孩子。不足是需要系統間交互兩次,流程較上述方法復雜。

    支付緩沖區

    把訂單的支付請求都快速地接下來,一個快速接單的緩沖管道。后續使用異步任務處理管道中的數據,過濾掉重復的待支付訂單。優點是同步轉異步,高吞吐。不足是不能及時地返回支付結果,需要后續監聽支付結果的異步返回。

    posted on 2016-12-14 13:34 jinfeng_wang 閱讀(179) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲成a人片在线观| 亚洲av成人一区二区三区在线观看| 两个人看的www免费视频中文| 亚洲国产精品99久久久久久| 久久精品国产亚洲AV久| 亚洲av永久无码嘿嘿嘿| 亚洲综合中文字幕无线码| 亚洲乱码一二三四区乱码| 2020亚洲男人天堂精品| 中国亚洲呦女专区| 亚洲一日韩欧美中文字幕在线| 亚洲一区二区三区深夜天堂| 波多野结衣亚洲一级| 亚洲乱妇熟女爽到高潮的片| 亚洲成a人片在线不卡一二三区| 亚洲av综合日韩| 男女交性无遮挡免费视频| 一个人看的免费高清视频日本| 91国内免费在线视频| 久久国产精品免费视频| 在线观看永久免费| 成年女人喷潮毛片免费播放| 热99re久久免费视精品频软件| 日韩亚洲国产综合久久久| 亚洲一区视频在线播放| 亚洲AV永久无码精品一百度影院 | 午夜免费福利片观看| 最近新韩国日本免费观看| 1024免费福利永久观看网站| 午夜毛片不卡免费观看视频| vvvv99日韩精品亚洲| 亚洲精品亚洲人成人网| 亚洲色图.com| 亚洲成av人无码亚洲成av人| 男女拍拍拍免费视频网站| 午夜免费福利片观看| 韩国欧洲一级毛片免费| 激情97综合亚洲色婷婷五| 亚洲高清无在码在线电影不卡| 亚洲色偷偷色噜噜狠狠99| 一级午夜免费视频|