本篇內(nèi)容主要講解“如何理解接口的冪等性的多重考慮”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“如何理解接口的冪等性的多重考慮”吧!
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營銷網(wǎng)站建設(shè)、龍子湖網(wǎng)絡(luò)推廣、微信小程序、龍子湖網(wǎng)絡(luò)營銷、龍子湖企業(yè)策劃、龍子湖品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供龍子湖建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:chinadenli.net
就是說在多次相同的操作下保證最終的結(jié)果是一致的。
其實(shí)這個(gè)概念還是比較簡單的,很容易理解,那我們思考一個(gè)問題,如果不保證接口冪等性會有什么問題?
我們簡單的舉個(gè)例子,現(xiàn)在有一個(gè)接口,提供了轉(zhuǎn)賬的功能,a要給b轉(zhuǎn)賬1000元,正常情況下我們接口一次性就調(diào)用成功了,但是卻因?yàn)榫W(wǎng)絡(luò)抖動等其它原因沒有成功,于是就開始不停的重試,突然網(wǎng)絡(luò)好了,但是這時(shí)卻連續(xù)發(fā)出去了三個(gè)請求,但是這個(gè)接口沒有保證冪等性,于是從結(jié)果上來看就是a給b轉(zhuǎn)了3000元,這顯然是程序業(yè)務(wù)邏輯上不能接受的(其實(shí)moon可以當(dāng)b的)。
token機(jī)制其實(shí)是比較簡單的,我們先來簡單的說一下流程。</br>
首先客戶端先請求服務(wù)端,服務(wù)端生成token,每次請求生成的都是一個(gè)新的token(這個(gè)token一定要設(shè)置超時(shí)時(shí)間),將token存入redis當(dāng)中,然后將token返回給客戶端。
客戶端攜帶剛剛返回的token請求服務(wù)端做業(yè)務(wù)請求。
服務(wù)端收到請求,做判斷。
如果token在redis中,則直接刪除該token,然后繼續(xù)做業(yè)務(wù)請求。
如果token不在redis中,代表已經(jīng)執(zhí)行過當(dāng)前業(yè)務(wù)了,則不執(zhí)行業(yè)務(wù)。
圖示如下:

token機(jī)制實(shí)現(xiàn)方式還是比較簡單的,但是其實(shí)對于我們某些響應(yīng)速度要求很高的業(yè)務(wù)不太友好,缺點(diǎn)就是需要多一次請求獲取token的過程。
正常來說是每次請都會生成一個(gè)新的token,如果有極限情況下,有兩個(gè)請求都帶著相同的token進(jìn)來,會存在都走入判斷是否存在的過程,可能都會同時(shí)查到存在,這樣也會有問題,針對這種情況,我們可以在刪除前判斷下是否存在,存在就刪除,為了保證原子性,這部分邏輯建議使用lua腳本完成。
去重表的機(jī)制是根據(jù)MySQL唯一索引的特性來的,我們先來說下它的流程:
首先客戶端先請求服務(wù)端,服務(wù)端先將這次的請求信息存入一張mysql的去重表中,這張表要根據(jù)這次請求的其中某個(gè)特殊字段建立唯一索引,或者主鍵索引。
判斷是否插入成功
如果插入成功,則繼續(xù)做后續(xù)業(yè)務(wù)請求。
如果插入失敗,則代表已經(jīng)執(zhí)行過當(dāng)前請求。
圖示如下:

去重表機(jī)制的問題有兩點(diǎn):
1.mysql容錯(cuò)性,也就是mysql本身如果不是高可用的那么業(yè)務(wù)可能會受到影響:
2.既然是唯一索引,自然在寫表的時(shí)候就沒有辦法用到changbuffer,每次都要從磁盤查出來判斷再寫入,對于一個(gè)高并發(fā)的接口來說,這些都是需要考慮的因素。
過程如下:
首先客戶端先請求服務(wù)端,服務(wù)端將能代表這次請求業(yè)務(wù)的唯一字段以 SETNX 的方式存入redis,并設(shè)置超時(shí)時(shí)間,超時(shí)時(shí)間可以根據(jù)業(yè)務(wù)權(quán)衡。
判斷是否插入成功
如果插入成功,則繼續(xù)做后續(xù)業(yè)務(wù)請求。
如果插入失敗,則代表已經(jīng)執(zhí)行過當(dāng)前請求。
這里我們是利用了redis setnx 的特性來完成的。</br>
setnx:只在鍵key不存在的情況下,將鍵key的值設(shè)置為value。若鍵key已經(jīng)存在,則SETNX命令不做任何動作。命令在設(shè)置成功時(shí)返回1,設(shè)置失敗時(shí)返回0。
圖示如下:

這種方案可以說是針對上一個(gè)方案改進(jìn)的,效率也會提高很多。
這種機(jī)制適用于有不同狀態(tài)的業(yè)務(wù),moon的上一家公司就是這樣做的。
我們的訂單系統(tǒng),一條訂單會有多個(gè)狀態(tài),如:待付款,鎖定,已付款等狀態(tài),而這些狀態(tài)都是有流程和邏輯的,我們可以根據(jù)這個(gè)狀態(tài)判斷是否執(zhí)行后續(xù)業(yè)務(wù)操作。
就是數(shù)據(jù)庫中增加版本號字段,每次更新根據(jù)版本號來判斷
過程如下:
首先客戶端先請求服務(wù)端,先查詢出當(dāng)前的version版本。
select version from .. where ..
根據(jù)version版本來做sql操作
UPDATE .. SET ... version=(version+1) WHERE .. AND version=version;
這個(gè)圖示我就不再畫了,還是比較簡單的
假設(shè)每一次拿數(shù)據(jù),都有認(rèn)為會被修改,所以給數(shù)據(jù)庫的行上鎖,也是基于數(shù)據(jù)庫特性來完成。
當(dāng)數(shù)據(jù)庫執(zhí)行select for update時(shí)會獲取被select中的數(shù)據(jù)行的行鎖,因此其他并發(fā)執(zhí)行的select for update如果試圖選中同一行則會發(fā)生排斥(需要等待行鎖被釋放),因此達(dá)到鎖的效果。
START TRANSACTION; # 開啟事務(wù) SELETE * FROM TABLE WHERE .. FOR UPDATE; UPDATE TABLE SET ... WHERE ..; COMMIT; # 提交事務(wù)
到此,相信大家對“如何理解接口的冪等性的多重考慮”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
當(dāng)前名稱:如何理解接口的冪等性的多重考慮
網(wǎng)站鏈接:http://chinadenli.net/article44/ppdhhe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、、微信小程序、定制網(wǎng)站、企業(yè)建站、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)