成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

消息隊列失敗經驗總結(冪等性概念以及影響)

開發 前端
相信大家都使用過消息MQ,他可以很好地進行系統解耦,減低變成的復雜度,又可以進行削峰,增加系統在高并發的穩定性。

 相信大家都使用過消息MQ,他可以很好地進行系統解耦,減低變成的復雜度,又可以進行削峰,增加系統在高并發的穩定性。那么使用MQ有哪些注意事項呢?是不是MQ就是萬無一失呢?一條MQ消息從產生到消費,有沒有可能失敗?在哪些環節可能失敗,如何處理?

[[330973]]

1.消息生產失敗

一般來說,從生產者到MQ中間件是通過網絡調用的,是網絡調用就有可能存在失敗。下面這些原因,都有可能造成MQ生產失敗,例如網絡波動,盡管生產者到MQ服務器之間是內網調用,并不意味著網絡調用的成功率就是百分之百,內網調用也會遇到網絡波動,造成調用超時或者失敗。又如調用的MQ機器瞬間Crash掉,這也是有可能造成調用失敗的。 面對生產者調用MQ的失敗,我們是容易比較容易處理的 , 我們只要簡單地進行重試即可,如果重試2-3次失敗,那么非常有可能是出現大問題,這個時候再重試意義不大,需要進行告警并處理。

2.MQ處理存儲失敗

消息到達消息中間件之后,通常是會被存儲起來的,只有被寫入到磁盤中,消息才是真正地被存儲,不會丟失。但是,大部分MQ中間件并不是收到消息就立馬寫入磁盤的,只是由于磁盤的寫入速度相對于內存,現得慢得多得多,所以,像Kafka這樣的消息系統,是會把消息寫到緩沖區中,異步寫入磁盤,如果機器在中途突然斷電,是有可能會丟失消息的。為了解決這個問題,大部分的MQ都是采用 分布式部署, 消息會在多臺機器上寫入緩存中成功才會返回給業務方成功,由于多臺機器同時斷電的可能性較低,我們可以認為這是比較低成本又可靠的方案。

3.消費者處理失敗

 

消息隊列失敗經驗總結(冪等性概念以及影響)

 

一般的MQ都有MQ重試機制,如果處理失敗,就會嘗試重復消費這個MQ。這個帶來的問題就是,MQ可能已經成功消費了,但是在通知MQ中間件的時候失敗了,這個時候帶來的結果就是消息重復消費。同理,在生產者重試的時候,也會遇到消息重復消費的問題。這個時候,就要求我們盡量把接口設計得有 冪等性 ,這個時候即便是重復消費,也不用擔心什么問題了?;旧献龊眠@三點,我們就能夠大大地提高我們地系統地可用性了!

這里需要關注幾個重點:

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

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

什么情況下需要冪等

業務開發中,經常會遇到重復提交的情況,無論是由于網絡問題無法收到請求結果而重新發起請求,或是前端的操作抖動而造成重復提交情況。 在交易系統,支付系統這種重復提交造成的問題有尤其明顯,比如:

用戶在APP上連續點擊了多次提交訂單,后臺應該只產生一個訂單;

向支付系統發起支付請求,由于網絡問題或系統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. 在服務改變狀態的業務邏輯前,保證防重復提交的邏輯

冪等的不足

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

增加了額外控制冪等的業務邏輯,復雜化了業務功能;

把并行執行的功能改為串行執行,降低了執行效率。

保證冪等策略

冪等需要通過 唯一的業務單號 來保證。也就是說相同的業務單號,認為是同一筆業務。使用這個唯一的業務單號來確保,后面多次的相同的業務單號的處理邏輯和執行效果是一致的。 下面以支付為例,在不考慮并發的情況下,實現冪等很簡單:

①先查詢一下訂單是否已經支付過,

②如果已經支付過,則返回支付成功;如果沒有支付,進行支付流程,修改訂單狀態為‘已支付’。

防重復提交策略

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

樂觀鎖

如果只是更新 已有 的數據,沒有必要對業務進行加鎖,設計表結構時使用樂觀鎖,一般通過version來做樂觀鎖,這樣既能保證執行效率,又能保證冪等。例如: UPDATE tab1 SET col1=1,version=version+1 WHERE version=#version# 不過, 樂觀鎖存在失效的情況,就是常說的ABA問題,不過如果version版本一直是自增的就不會出現ABA的情況。

防重表

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

分布式鎖

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

token令牌

這種方式分成兩個階段:申請token階段和支付階段。 第一階段,在進入到提交訂單頁面之前,需要訂單系統根據用戶信息向支付系統發起一次申請token的請求,支付系統將token保存到Redis緩存中,為第二階段支付使用。 第二階段,訂單系統拿著申請到的token發起支付請求,支付系統會檢查Redis中是否存在該token,如果存在,表示第一次發起支付請求,刪除緩存中token后開始支付邏輯處理;如果緩存中不存在,表示非法請求。 實際上這里的token是一個信物,支付系統根據token確認,你是你媽的孩子。 不足是需要系統間交互兩次,流程較上述方法復雜。

支付緩沖區

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

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2013-01-18 10:10:30

項目項目經理

2009-10-15 09:27:00

2010-01-12 16:44:53

VB.NET數組

2021-04-02 10:30:18

Vue3.0前端代碼

2009-09-16 17:13:54

學習Linq

2009-08-19 09:24:43

AJAX引擎經驗總結

2009-09-29 16:32:11

OJB Hiberna

2009-11-17 11:24:00

PHP應用技巧

2009-08-20 17:35:47

Servlet和JSP

2009-09-11 13:29:31

LINQ查詢操作

2009-09-16 17:44:54

LINQ to SQL

2011-07-08 13:15:52

JSP

2009-09-08 10:57:55

LINQ查詢操作

2009-09-08 16:02:47

Linq使用Group

2010-06-12 17:37:18

UML實踐指南

2009-10-22 15:07:12

綜合布線工程

2010-01-26 13:28:11

Android開發要點

2010-01-27 18:12:14

Android dia

2010-03-08 15:12:27

Python語言

2009-08-13 18:13:27

C#學習經驗
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美伊人影院 | 久久天天躁狠狠躁夜夜躁2014 | 国产精品综合久久 | 欧美四虎| 亚洲狠狠丁香婷婷综合久久久 | 精品久久久久香蕉网 | 日韩av第一页 | 日本精品一区二区 | 国产一区二区三区在线 | 欧美日韩精品综合 | 国产色婷婷精品综合在线手机播放 | 在线成人免费视频 | 成人影院av| 国产成人免费视频网站高清观看视频 | 欧美精品第一页 | 激情亚洲 | 日操操 | 日本一卡精品视频免费 | 一级毛片网 | 亚洲二区在线 | 欧美专区在线观看 | 日日夜夜精品免费视频 | 91精品国产91久久综合桃花 | 91精品久久久久久久久久 | 亚洲欧美一区二区三区视频 | 国产激情自拍视频 | 粉嫩国产精品一区二区在线观看 | 国产视频一区在线观看 | 天天干天天操天天射 | 国产目拍亚洲精品99久久精品 | 亚洲视频在线一区 | 在线视频成人 | 国产精品久久久久久中文字 | 黄色在线免费播放 | 亚洲精品一区中文字幕 | 91伊人| 99pao成人国产永久免费视频 | 亚洲一区久久 | 99久久国产精| 亚洲激情在线观看 | 蜜桃在线视频 |