<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:介面冪等性
問題,對於開發人員來說,是一個跟語言無關的公共問題。對於一些使用者請求,在某些情況下是可能重複傳送的,如果是查詢類操作並無大礙,但其中有些是涉及寫入操作的,一旦重複了,可能會導致很嚴重的後果,例如交易的介面如果重複請求可能會重複下單。介面冪等性是指使用者對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點選而產生了副作用。
在HTTP/1.1中,對冪等性進行了定義。它描述了一次和多次請求某一個資源對於資源本身應該具有同樣的結果,即第一次請求的時候對資源產生了副作用,但是以後的多次請求都不會再對資源產生副作用。這裡的副作用是不會對結果產生破壞或者產生不可預料的結果。也就是說,其任意多次執行對資源本身所產生的影響均與一次執行的影響相同。
這類問題多發於介面的:
insert
操作,這種情況下多次請求,可能會產生重複資料。update
操作,如果只是單純的更新資料,比如:update user set status=1 where id=1
,是沒有問題的。如果還有計算,比如:update user set status=status+1 where id=1
,這種情況下多次請求,可能會導致資料錯誤。在介面呼叫時一般情況下都能正常返回資訊不會重複提交,不過在遇見以下情況時可以就會出現問題,如:
本文討論的是如何在伺服器端優雅地統一處理這種介面冪等性情況,如何禁止使用者重複點選等使用者端操作不在此次討論範圍。
冪等性是為了簡化使用者端邏輯處理,能放置重複提交等操作,但卻增加了伺服器端的邏輯複雜性和成本,其主要是:
所以在使用時候需要考慮是否引入冪等性的必要性,根據實際業務場景具體分析,除了業務上的特殊要求外,一般情況下不需要引入的介面冪等性。
冪等意味著一條請求的唯一性。不管是你哪個方案去設計冪等,都需要一個全域性唯一的ID ,去標記這個請求是獨一無二的。
全域性唯一性ID,我們怎麼去生成呢?你可以回想下,資料庫主鍵Id怎麼生成的呢?
是的,我們可以使用UUID
,但是UUID的缺點比較明顯,它字串佔用的空間比較大,生成的ID過於隨機,可讀性差,而且沒有遞增。
我們還可以使用雪花演演算法(Snowflake)
生成唯一性ID。
雪花演演算法是一種生成分散式全域性唯一ID的演演算法,生成的ID稱為Snowflake IDs
。這種演演算法由Twitter建立,並用於推文的ID。
一個Snowflake ID有64位元。
當然,全域性唯一性的ID,還可以使用百度的Uidgenerator
,或者美團的Leaf
。
冪等處理的過程,說到底其實就是過濾一下已經收到的請求,當然,請求一定要有一個全域性唯一的ID標記
哈。然後,怎麼判斷請求是否之前收到過呢?把請求儲存起來,收到請求時,先查下儲存記錄,記錄存在就返回上次的結果,不存在就處理請求。
一般的冪等處理就是這樣,如下:
可能會想到的是,只要請求有唯一的請求編號,那麼就能借用Redis做這個去重——只要這個唯一請求編號在Redis存在,證明處理過,那麼就認為是重複的。
方案描述:
所謂唯一請求序列號,其實就是每次向伺服器端請求時候附帶一個短時間內唯一不重複的序列號,該序列號可以是一個有序 ID,也可以是一個訂單號,一般由下游生成,在呼叫上游伺服器端介面時附加該序列號和用於認證的 ID。
當上遊伺服器收到請求資訊後拿取該 序列號 和下游 認證ID 進行組合,形成用於操作 Redis 的 Key,然後到 Redis 中查詢是否存在對應的 Key 的鍵值對,根據其結果:
適用操作:
使用限制:
主要流程:
主要步驟:
上面步驟中插入資料到 Redis 一定要設定過期時間。這樣能保證在這個時間範圍內,如果重複呼叫介面,則能夠進行判斷識別。如果不設定過期時間,很可能導致資料無限量的存入 Redis,致使 Redis 不能正常工作。
方案描述:
針對使用者端連續點選或者呼叫方的超時重試等情況,例如提交訂單,此種操作就可以用 Token 的機制實現防止重複提交。簡單的說就是呼叫方在呼叫介面的時候先向後端請求一個全域性 ID(Token),請求的時候攜帶這個全域性 ID 一起請求(Token 最好將其放到 Headers 中),後端需要對這個 Token 作為 Key,使用者資訊作為 Value 到 Redis 中進行鍵值內容校驗,如果 Key 存在且 Value 匹配就執行刪除命令,然後正常執行後面的業務邏輯。如果不存在對應的 Key 或 Value 不匹配就返回重複執行的錯誤資訊,這樣來保證冪等操作。
使用限制:
主要流程:
① 伺服器端提供獲取 Token 的介面,該 Token 可以是一個序列號,也可以是一個分散式 ID 或者 UUID 串。
② 使用者端呼叫介面獲取 Token,這時候伺服器端會生成一個 Token 串。
③ 然後將該串存入 Redis 資料庫中,以該 Token 作為 Redis 的鍵(注意設定過期時間)。
④ 將 Token 返回到使用者端,使用者端拿到後應存到表單隱藏域中。
⑤ 使用者端在執行提交表單時,把 Token 存入到 Headers 中,執行業務請求帶上該 Headers。
⑥ 伺服器端接收到請求後從 Headers 中拿到 Token,然後根據 Token 到 Redis 中查詢該 key 是否存在。
⑦ 伺服器端根據 Redis 中是否存該 key 進行判斷,如果存在就將該 key 刪除,然後正常執行業務邏輯。如果不存在就拋異常,返回重複提交的錯誤資訊。
注意,在並行情況下,執行 Redis 查詢資料與刪除需要保證原子性,否則很可能在並行下無法保證冪等性。其實現方法可以使用分散式鎖或者使用 Lua 表示式來登出查詢與刪除操作。
SpringBoot 介面冪等性實現的 4 種方案!這個我真的服氣了!
到此這篇關於淺談Redis處理介面冪等性的兩種方案的文章就介紹到這了,更多相關Redis 介面冪等性內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45