批量汉柒、增量接口并發(fā)問題和NTP協(xié)議

背景

項(xiàng)目中存在「批量接口」和「增量接口」误褪,兩個(gè)接口都更新DB中的數(shù)據(jù)。

如存在以下表格碾褂,主鍵為shopId兽间,shopName表示店名。

shopId shopName
111 info111
222 info222
333 info333

有以下兩個(gè)接口:

updateShopNameBatch(List<Integer> shopIdList, String shopName);

updateShopName(Integer shopId, String shopName);

兩個(gè)接口的功能分別為批量修改門店名稱和單個(gè)修改門店名稱正塌。

忽略接口中的其他操作嘀略,主要執(zhí)行了以下兩句sql。

update Shop set shopName = #{shopName} where shopId in 
<foreach collection="shopIdList" item="shopId" index="index" open="(" separator="," close=")">
            #{shopId}
</foreach>

update Shop set shopName = #{shopName} where shopId = #{shopId}

兩個(gè)sql可能會修改同個(gè)shopId的shopName屬性乓诽,存在一定的并發(fā)問題帜羊。

從數(shù)據(jù)庫層看,兩個(gè)sql的執(zhí)行過程完全隔離问裕,即先到先執(zhí)行逮壁。

從接口層面看,批量更新接口和增量更新接口的并發(fā)執(zhí)行會遇到以下情況:

  1. 批量接口先于增量接口收到請求粮宛,然而由于批量接口中執(zhí)行了一些額外操作窥淆,導(dǎo)致增量接口先執(zhí)行sql。最終結(jié)果被批量接口覆蓋巍杈。
  2. 接口調(diào)用發(fā)起方先調(diào)用批量接口忧饭,再調(diào)用增量接口,然而由于網(wǎng)絡(luò)問題筷畦,增量請求先于批量請求到達(dá)服務(wù)提供方词裤。
  3. 用戶先點(diǎn)擊批量修改按鈕,再修改了單個(gè)門店的名稱鳖宾。在分布式系統(tǒng)中吼砂,兩個(gè)請求打到了不同服務(wù)器,由于服務(wù)器負(fù)載不均鼎文,導(dǎo)致增量接口的sql先于批量sql執(zhí)行渔肩。
  4. ……

這個(gè)例子較為常見,由于分布式拇惋,網(wǎng)絡(luò)周偎,處理速度等原因抹剩,用戶先發(fā)起的請求,可能會被延后蓉坎。

問題

這里就引出請求順序的問題澳眷,請求A和請求B,到底是哪個(gè)先發(fā)生蛉艾。

在分布式系統(tǒng)中钳踊,一般很少去關(guān)注兩個(gè)請求哪個(gè)先發(fā)生,因?yàn)椋?/p>

  1. 多數(shù)接口為查詢接口伺通,并不關(guān)心請求的先后順序箍土。
  2. 很少存在批量接口和增量接口同時(shí)被調(diào)用的場景。

當(dāng)同時(shí)使用批量接口和增量接口時(shí)罐监,則需要著重關(guān)注這個(gè)問題吴藻。

接口調(diào)用示意圖如下:

批量接口和增量接口調(diào)用順序

解決思路

考慮到需要區(qū)分請求發(fā)生的先后,首先想到的是時(shí)間戳弓柱。

調(diào)用發(fā)起方在調(diào)用批量和增量接口時(shí)沟堡,增加時(shí)間戳入?yún)ⅰ?/p>

在服務(wù)端,將時(shí)間戳作為當(dāng)前sql記錄的版本號矢空。

  1. 如果庫中的版本號小于入?yún)r(shí)間戳航罗,則支持更新。
  2. 如果庫中的版本號大于入?yún)r(shí)間戳屁药,則不更新粥血。表示已有后發(fā)起的請求更新了數(shù)據(jù)庫。

然而酿箭,在分布式環(huán)境下复亏,時(shí)間校準(zhǔn)也是個(gè)難題。

因?yàn)闊o法保證批量接口和增量接口從同個(gè)服務(wù)器發(fā)起缭嫡。

不同服務(wù)器之間存在時(shí)間誤差缔御,則無法保證入?yún)r(shí)間戳的準(zhǔn)確性。

分布式場景如下:

分布式場景

考慮到時(shí)間準(zhǔn)確性妇蛀,想到時(shí)間協(xié)議耕突。

在網(wǎng)絡(luò)時(shí)間協(xié)議中,有一種常用的協(xié)議评架,NTP眷茁。

其作用是讓服務(wù)器時(shí)間和源服務(wù)器時(shí)間對齊。

NTP協(xié)議的流程圖如下:

NTP協(xié)議

NTP協(xié)議過程:

  1. 客戶端向服務(wù)器發(fā)送請求纵诞,并記錄客戶端時(shí)間為T1上祈。
  2. NTP服務(wù)器收到請求,記錄服務(wù)端時(shí)間為T2。
  3. 服務(wù)端做一些處理雇逞,響應(yīng)客戶端請求,并記錄服務(wù)端時(shí)間為T3茁裙。
  4. 客戶端收到響應(yīng)塘砸,記錄客戶端時(shí)間為T4。

可得:

  1. NTP服務(wù)端處理時(shí)間為T3 - T2晤锥。
  2. 整個(gè)過程耗時(shí)為T4 - T1掉蔬。
  3. 得到往返網(wǎng)絡(luò)延時(shí)為(T4 - T1) - (T3 - T2)。
  4. 假設(shè)請求網(wǎng)絡(luò)延時(shí)為delay1矾瘾,響應(yīng)網(wǎng)絡(luò)延時(shí)為delay2女轿,客戶端和NTP服務(wù)端的時(shí)差為d。
  5. 得到T1 + d + delay1 = T2, T3 - d + delay2 = T4壕翩。
  6. 使用等式干申大那多蛉迹,得到(T2 - T1) + (T3 - T4) = 2d + (delay1 - delay2)。
  7. 在NTP協(xié)議中放妈,默認(rèn)delay1 = delay2北救,即d = ((T2 - T1) + (T3 - T4)) / 2。
  8. 當(dāng)網(wǎng)絡(luò)足夠穩(wěn)定時(shí)芜抒,delay1約等于delay2珍策。那么,網(wǎng)絡(luò)越不穩(wěn)定宅倒,誤差也就越大攘宙。
  9. 在分布式中,不同客戶端與NTP服務(wù)端之間的網(wǎng)絡(luò)情況不同拐迁,將引入另一個(gè)誤差因素蹭劈。

采用方案

查看NTP協(xié)議之后,發(fā)現(xiàn)其誤差為毫秒級別唠亚。

NTP意圖將所有參與計(jì)算機(jī)的協(xié)調(diào)世界時(shí)時(shí)間同步到幾毫秒的誤差內(nèi)链方。 —— 維基百科

正常情況下,批量接口和增量接口的響應(yīng)時(shí)間為毫秒級灶搜,所以NTP協(xié)議的誤差是不能接受的祟蚀。

最終采用了一種較為粗暴的方案:

  1. 每條sql記錄都有一個(gè)版本號,初始值為0割卖。
  2. 在執(zhí)行批量之前前酿,首先select,查出版本號為verison鹏溯。
  3. 執(zhí)行update時(shí)罢维,將版本作為參數(shù)帶上,即update Shop set shopName = #{shopName} where shopId = #{shopId} and version = #{version}
  4. 如果update語句返回結(jié)果為1丙挽,則表示執(zhí)行成功肺孵;如果返回為0匀借,則表示在批量select和update過程中,已被增量接口修改平窘,即遇到并發(fā)問題吓肋。
  5. 如遇到并發(fā)問題,執(zhí)行告警操作瑰艘,并進(jìn)行人工數(shù)據(jù)對齊是鬼。

因無法確認(rèn)批量接口和增量借口發(fā)生的先后順序,最終采用了出錯(cuò)告警紫新,人工校對的方案均蜜。

該方案low中帶著一些粗暴。

換個(gè)思維角度芒率,也算是一種樂觀并發(fā)的思維囤耳,樂觀地認(rèn)為批量接口和增量接口很少會出現(xiàn)并發(fā)。即使出現(xiàn)并發(fā)問題敲董,在服務(wù)器之間交錯(cuò)調(diào)用后紫皇,最終結(jié)果有一定概率是正確的。(逃

后記

求比較優(yōu)雅的腋寨,用于解決批量聪铺、增量接口并發(fā)問題的方案,感激不盡萄窜。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铃剔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子查刻,更是在濱河造成了極大的恐慌键兜,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穗泵,死亡現(xiàn)場離奇詭異普气,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)佃延,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門现诀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人履肃,你說我怎么就攤上這事仔沿。” “怎么了尺棋?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵封锉,是天一觀的道長。 經(jīng)常有香客問我,道長成福,這世上最難降的妖魔是什么碾局? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮奴艾,結(jié)果婚禮上擦俐,老公的妹妹穿的比我還像新娘。我一直安慰自己握侧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布嘿期。 她就那樣靜靜地躺著品擎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪备徐。 梳的紋絲不亂的頭發(fā)上萄传,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音蜜猾,去河邊找鬼秀菱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蹭睡,可吹牛的內(nèi)容都是我干的衍菱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼肩豁,長吁一口氣:“原來是場噩夢啊……” “哼脊串!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起清钥,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤琼锋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后祟昭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缕坎,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年篡悟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谜叹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恰力,死狀恐怖叉谜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踩萎,我是刑警寧澤停局,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響董栽,放射性物質(zhì)發(fā)生泄漏码倦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一锭碳、第九天 我趴在偏房一處隱蔽的房頂上張望袁稽。 院中可真熱鬧,春花似錦擒抛、人聲如沸推汽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歹撒。三九已至,卻和暖如春诊胞,著一層夾襖步出監(jiān)牢的瞬間暖夭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工撵孤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迈着,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓邪码,卻偏偏與公主長得像裕菠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子闭专,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 50個(gè)常用的sql語句Student(S#,Sname,Sage,Ssex) 學(xué)生表Course(C#,Cname...
    哈哈海閱讀 1,231評論 0 7
  • 不停指責(zé)自己怎么那么多的憤憤不平糕韧,應(yīng)該給他更多的溫暖,能夠感受到他的孤單喻圃,再也不說不開心的事情萤彩,平淡地過好這一段時(shí)間。
    Sansa777閱讀 271評論 0 0
  • 一直以來都是個(gè)很焦慮的人斧拍,所以很多人給我的建議是太急了雀扶,做事情急,說話急肆汹,可能好的一方面是反應(yīng)快速愚墓,但是另一方面卻...
    朱秀微閱讀 225評論 0 0
  • 作者:歡 Annie一直為了做到總經(jīng)理的位置而努力浪册,努力尋找在游總面前表現(xiàn)得機(jī)會,努力和Hanson斗智斗勇岗照。但是...
  • 高中一次偶然的機(jī)會村象,在語文試卷上發(fā)現(xiàn)了石評梅的一篇文章笆环,瞬間被她的文字吸引,以后的許多個(gè)晨讀里厚者,我都會拿著那張?jiān)嚲?..
    三池Mary閱讀 437評論 0 0