這個夏天,配置項也要清清爽爽

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"任何業務系統在高速成長的過程中都需要快速的迭代交付,驗貨寶業務也不例外。這個過程中不可避免的會在系統代碼中不斷引入「壞味道」。下面我們來看看驗貨寶近期做的一個微小的優化和一些思考。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是「驗貨寶」"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏首先介(ān)紹(lì)一下閒魚的驗貨寶服務。在閒魚購買數碼產品、潮鞋、奢侈品包包等貴重物品時,買家可能會擔心買到假貨或者與賣家描述不符的寶貝,賣家也希望自己的優質寶貝能賣個好價格。爲了解決買賣雙方的信任問題,閒魚和專業機構合作,爲所有的驗貨寶商品提供權威的驗貨報告。當買家下單購買驗貨寶商品後,賣家將寶貝發貨至驗貨中心,驗貨中心出具驗貨報告後,買家可以根據報告決定購買或者不購買。驗貨寶服務一上線就深受用戶喜愛,短時間內圈粉無數。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"那女(運)孩(營)對我說,再再再來個新類目"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"驗貨寶上線也半年有餘,需求迭代速度也趨於平穩,得益於優良的整體架構設計,目前後端開發由我一個人即可 Cover 住。但在需求迭代的過程中還是有一些「痛點」,比如:我希望當運營同學後面不斷來找我新增類目時,我可以更快更簡單一點搞定。驗貨寶目前首批上線支持的品類有:手機、平板、筆記本、潮鞋、奢侈品包包、奢侈品腕錶、奢侈品飾品、奢侈品服裝。後續驗貨寶服務還將覆蓋更多品類,讓大家賣得舒心買得放心。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/db\/db2ad923aa84a4d98a00ab3c87a51f07.png","alt":"圖片","title":"null","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不同類目有着不同的驗貨費計算策略、不同的介紹頁 URL、不同的服務商、不同的可升級的價格區間(指定價格段的商品纔可以升級驗貨寶服務)、不同的內部 Code 等等。當然這些大部分內容是通過配置進行管理的,但配置散落在多個系統、多個 key 中,還有一部分是硬編碼在代碼中的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"配置分佈在多個系統中主要是因爲不同配置系統側重有所不同,比如有的配置系統面向開發同學、有的面向運營同學;硬編碼在代碼中主要是如一些全局的常量 Code 需要打到依賴的 JAR 包中。硬編碼的配置帶來的問題是上線新的品類需要進行服務端代碼發佈,會受節假日、封網等的影響,發佈週期長、不夠靈活。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實這個一個常見同時也容易忽視的場景,一條鏈路中相關聯的配置需要收口到一個「原子配置」(指的就是一個最小的下發單位)中,配置項過多且分散可能帶來的諸多負面影響:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 增加維護成本:變更流程繁瑣,需要修改多個配置;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 易出錯:容易出現錯配、漏配而不自知的情況;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 變更時間延長:每個配置都需要修改、走流程審批等;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 一致性問題:如果一條鏈路多個配置有時序依賴,那麼配置系統下發的延時可能引發一致性問題,需要額外的手段保障最終一致性,但原子配置就不存在這個問題。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了優化這個問題,同時爲了支撐後面新類目能夠快速上線,驗貨寶剛剛做了個專項優化:配置的歸一化改造。目標是新類目上線免發佈,同時配置統一按類目收口一處。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"簡單點,新增類目的方式簡單點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先從兩大主要鏈路入手梳理:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 商品升級鏈路"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 訂單履約鏈路"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整個鏈路涉及多個應用,配置的類型也多種多樣:String、Boolean、Map、Integer 等等。現有「Mach 雲投放平臺」剛好可以滿足這個配置中心的需求。Mach 提供獨立的配置定義和配置實例能力。配置定義採用 JSON Schema 對配置內容進行類型約束,配置實例可以創建不同投放時間段、不同優先級、不同環境的多個實例。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏我通過一個簡化的例子說明下這條鏈路,比如我梳理出來每個類目應有這 3 個配置:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 驗貨寶服務說明頁面 URL:字符串類型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 應收取的驗貨費金額:數值類型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• 該類目可以升級驗貨寶服務的分類:字符串列表類型(這項我解釋一下,是用來配置多個分類如籃球鞋、板鞋、帆布鞋等都可以開啓驗貨寶潮鞋類目驗貨服務)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼我在 Mach 上創建一個新配置:「驗貨寶配置集」,首先定義 JSON Schema:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/69\/690d9263bb592c221fd7375339ba05d6.png","alt":"圖片","title":"null","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後新建一個配置的實例,設定生效時間區間、優先級等信息。最後就填這 3 個配置的具體內容,Mach 會根據配置項的數據類型生成對應的 GUI 填寫頁面,比如 string 類型就是一個文本輸入框;array 是一個帶 + 按鈕的文本框列表;number 類型是一個帶數值校驗的文本輸入框。這裏例子就不貼頁面截圖了,用文本示意下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• introductionPageUrl: www.taobao.com\/yanhuobao\/introduction-page.html[1]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• platformServiceFee: 39"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"• cateIdUnderScene: [123, 234, 345]"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"OK,現在我們就可以通過 Mach 的服務接口拉取這個配置信息了,我們可以從接口獲取到這個配置實例的 JSON 字符串,通過 fastjson 就可以解析到對應的配置內容了。當然我們對配置定義的結構和實際使用的數據結構不一定完全一致,我們會將以上配置解析爲一個包含如下 3 個變量的配置 DO 對象:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/40\/409bd05f0cda8f6668de6be74d49cf8e.png","alt":"圖片","title":"null","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"線上業務 QPS 非常高,同時這些配置不要求實時獲取最新值,因此我們在本地做一份緩存,當然將解析好的 ConfigDO 對象保存下來是最好的選擇。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"煙花易冷,輪子少造"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個應用中會引用非常多的 Mach 配置,每個配置解析出來的 DO 數據結構各不相同,但如果每處使用都自己緩存勢必造成重複開發和資源的浪費。那麼我們這裏順帶引入了一個通用的配置緩存池。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/61\/61f54e43bb3b4730294605a070bbd995.png","alt":"圖片","title":"null","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存池採用的是 Guava 的 LoadingCache,通過抽象出一個 ConfigValueParser,各個配置使用者可以實現其對應的解析邏輯。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/34\/34b76ec2d8986e445865b08035fa2e78.png","alt":"圖片","title":"null","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 parseConfig 實現解析邏輯,返回上面提到的配置解析後的 YhbConfigDO 對象即可。在使用的時候就可以直接獲取:YhbConfigDO yhbConfigDO = configMachReader.get(CONFIG_MACH_ID);"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文通過一個驗貨寶近期的一個配置歸一化的優化介紹了產品鏈路中相關聯的配置分散可能會產生的問題,以及優化方案。希望能對大家有所幫助。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文轉載自:閒魚技術(ID:XYtech_Alibaba)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/NVlH_Y2SAodPEyyhgqPCwg","title":"xxx","type":null},"content":[{"type":"text","text":"這個夏天,配置項也要清清爽爽"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章