作者:閒魚技術——碼寶、泊垚
背景
閒魚同城作為閒魚本地生活的主戰場,維護閒魚基本盤閒置物品的同時,還針對閒置時間和閒置空間場景進行相關的孵化。
於買家而言:淘到經濟實惠的閒置物品(二手數碼),打發閒置時間(兼職,服務)去掙錢。
於賣家而言:閒置物品(二手數碼)賣錢,閒置空間(二手房租賣)換錢。
閒置時間(兼職)和閒置空間(租房)區別於同城傳統的閒置物品,閒置物品為傳統的C2C的商品,也就是買賣雙方均為C端的用戶。但是對於兼職、租房等業務來說,需要供應商入駐提供供給。因此一旦涉及到第三方提供的供給,就不得不面臨以下問題:
- 隨著業務的不斷髮展,必將有越來越多的供應商入駐。為了能讓供應商快速接入,除了必備的接入文檔之外在技術側應該能有一套動態響應機制,防止在供應商接入的過程中被問題頻繁的打斷(雙方數量對不齊、同步失敗原因等)。
- 每個供應商的供給質量和技術水平存在差異,如何控制好供給質量的同時保證服務的穩定性成為另一大關鍵因素。
技術方案
整體架構
整體架構設計會複用中臺的一些基礎能力,比如用戶、商品、交易等。抽象出三個領域,商家域、審核域和獨立業務域(每個業務可以單獨劃分)。安全生產層面,為了保證系統的穩定性,圍繞限流(高併發下限流重試)+ 監控(對異常的狀態出對應的報警)+ 數據安全(重試下情況下保證冪等性)展開。
數據對賬
注:
- 審核:複用了審核中心的能力(機審+人審)。機審:預置過濾規則,不滿足過濾規則的判定為審核失敗。
- 開放接口能力:提供查詢商品審核、校驗操作日誌。
異常回調
- 收到同步消息後會對數據進行校驗,包括不限於數據字段合規性校驗(長度、枚舉值等)、夾帶違禁詞、狀態更新異常(已經下架的寶貝執行下架動作)等。
- 針對上述初審通過,會進入審核中心二次審核,審核主要內容為語義違規。
兩種回調場景都複用了異常流轉的能力如下圖:
通過catch(LocalBizException e)
的方式,將e.getCode()和e.getMessage()封裝為response進行返回,不需要對不同的異常進行單獨catch讓異常邏輯在業務回調側閉環。
供應商獲取到錯誤信息後根據錯誤信息修改信息進行二次同步。
定時播報
採集狀態變更日誌表和業務商品表將對應的一個小時內發生狀態轉化的商品數量(上架、下架、編輯、審核不通過等)最後以釘釘消息播報到釘釘群中(按照釘釘的機器人api)。
兼職中主要關心的指標項為上下架成功與否、是否審核失敗等指標,兼職播報架構如下圖所示:
開放接口
與此同時開放的接口能力提供查詢商品審核、校驗操作日誌。接口定義如下,提供時間範圍、同步id、類型、分頁參數等信息。
注:涉及圖中狀態日誌表和商品表的插入部分參見下一章節“穩定性”。
穩定性(安全生產)
穩定性治理一直是一個系統繞不開的話題,在這個場景中涉及到第三方之間的交互,誰都無法確定對方是如何調用己方的系統。這種情況下,穩定性的重要性更加不言而喻。
流量控制
在數據同步時,將請求打入隊列對於第三方的同步請求使用異步返回。打入隊列的好處就是可以利用隊列實現流量控制,削峰填谷。
限流這部分依賴於阿里開源的Sentinel框架,網上對於Sentinel的分析很多這裡不多加贅述。
數據一致性保證
由於存在重試操作,所以必然需要在重試過程中保證數據的正確性。
- 狀態變更日誌表:數據庫採用的是nosql的數據庫,這邊會根據參數生成唯一id,進行覆蓋插入保證數據的唯一性。
- 業務商品表:採用先查後插的方式,同時利用分佈式鎖+itemId唯一鍵衝突保證數據的唯一性。
拿兼職插入一致性舉個栗子:
ic表:底層商品表,包括一些商品的基本信息。
崗位表:擴展信息的存儲,工作地點、工作時間等。
當一條兼職同步消息來了之後這邊會涉及到兩張表的維護。這裡採用的方式是以下架的方式插入ic表,如果業務表成功後去更新上架ic表中狀態(如下圖)。
異常監控告警
攻擊流量通常會偽裝成正常流量進入。在這種情況下,系統會一直無法消費此異常消息,所以這邊設置一個消費重試閾值,如果達到上限後對消息進行丟棄,同時進行系統告警(有的場景是需要強一致性保障,此時報警後需人工接入排查)。
兼職業務的告警場景包括:
- 限流觸發報警(持續時間超過10分鐘):限流期間被限制的消息業務會主動進行重試,控制重試n次整體持續時間不會超過10分鐘,如果限流超過10分鐘認定為異常情況會進行告警。(通常來說是供應商大批量上下架崗位導致,未通知前提下認定為他們系統問題)
- 狀態更新失敗(持續時間超過5分鐘,每分鐘數量大於n):小批量的更新失敗可以理解為是垃圾數據,持續時間過於長可以理解為供應商系統異常。
總結和展望
本章節主要介紹了閒魚同城業務在“閒置時間”和"閒置空間“場景下針對與第三方系統對接的過程中開發資源和穩定性問題展開。通過上述方案也解決了在開篇提到的2個問題:
- 動態響應機制:商品同步時通過實時回調和異步回調的方式將商品的每個異常狀態返回給供應商;提供了小時時間維度的統計播報,最後以釘釘消息通知至釘釘群中,如若發現異常也可根據開放接口去查詢商品歷史變更狀態。這樣就能很大程度上解放開發,不會因為對賬的問題被頻繁的打斷。
- 穩定性治理:通過接口限流保證異常流量打滿線程池進而影響系統;通過接口冪等保證數據的安全唯一性;通過監控(搭配合適的報警規則)去監控異常場景,如若出現問題人為介入。
隨著業務越來越複雜,對應的獨立業務域也將會越來越多,在獨立業務域上的開發精力也會越來越多。能否根據大量複雜業務場景的輸入找到共同點抽象出較為理想的架構將是努力的目標。
- 抽象出獨立業務域中的共同點,推動業務完善路徑:完善租房的訂單和履約路徑,統一抽取出訂單域和履約域。
- 針對不同業務的不同商家統一商家管理平臺,現階段每個業務都有自己的一套接入方式。