京東服務市場微服務架構和積木式賦能挑戰

京東服務市場是爲第三方軟件服務商和京東開放商家提供的交易服務平臺,爲第三方服務商賦能,併爲其搭建起與商家間交易合作的橋樑。

服務市場團隊在2018年完成了雲平臺京東服務市場的交接與POP平臺京麥插件市場的系統融合,並承載着京東自營與三方越來越多服務進行商業變現的業務訴求。相對於傳統的電商系統,服務市場面對着的是更復雜的業務領域,更靈活多變的交易組合場景,如何讓系統具備積木式賦能的能力,通過鬆耦合架構設計具有系統高內聚性,把耦合度降到最低,進一步實現較爲合理的微服務架構風格的應用系統,期間遇到了很大的挑戰也總結了很多經驗。本次分享和大家回顧這個艱辛卻有收穫的過程。

縱深化的業務整合

兩市融合 - 涅槃之路

2017年底,京東雲平臺京東服務市場交接到POP平臺京麥插件市場進行系統融合,我們稱之爲兩市融合。兩市融合是爲了實現對外統一的服務入口,實現兩個系統變成一個系統,但當時這兩個市場卻是兩套完整的系統閉環。

融合項目是對兩個市場進行深度的融合改造,融合不僅是進行流程融合和數據融合,其中最難的就是同時支持雙邊業務的並行運行,所以,整個融合過程在服務發佈、服務審覈、服務展示、服務訂購和服務使用等環節對兩個系統原業務進行了大量的兼容處理,造成了極高的系統複雜度和極差的穩定性。

webp

融合方案並沒有採取單邊市場下線的方案,而是採取了將兩個市場裁取縫合的處理方式,交易流程使用了京麥插件市場的流程,商品流程使用了服務市場的流程,這種融合方案現在看來的確不明智。

兩市融合 - 並行業務

並行業務的難度在於雙邊讀業務與寫業務的同時支持,因爲不能簡單的下線一邊的業務,但當時對數據的讀寫入口不能完全梳理清晰,所以融合過程中對上下游各種業務需要兼容支撐,因此在融合中的過渡階段產生了三套流程並行的尷尬階段,並且還需要同時雙寫三套數據庫表及同步多個數據緩存,複雜度可見一斑。

webp

當時兩個市場的兩個數據庫是獨立對外提供數據服務的,如何將兩個數據庫變成一個數據庫,是當時最大的難點。

而且服務市場作爲一個交易系統,數據庫是系統的核心,不僅MySQL有很多從庫,還有Redis、ES、Solr、HBase等作爲數據緩存,所以在數據異構方面做了很多功夫。

兩市融合 - 流程融合 & 數據融合

流程融合包括服務發佈審覈流程融合、評價評分流程融合、服務搜索流程融合、訂單訂購流程融合、結算流程融合、退款流程融合、取消訂單流程融合和發票流程融合等等。

以訂單訂購流程融合爲例,由於服務市場和插件市場融合切換是無縫的(不能停服務),且兩側訂購、訂單數據結構又不完全一致,同時數據切流又是逐步放量。所以訂購、訂單流程的融合採用數據庫雙寫的方式,所謂雙寫方式,是在寫原服務市場數據庫和插件市場數據庫時,通過訂閱Binlog,使用BinLake框架訂閱寫入sql再整理數據寫入新數據庫。最終所有服務通過調用新庫進行查詢服務。

這種雙寫機制可以很好的進行回滾,當新流程出現問題的時候,可以切回到老數據庫進行降級。當新訂購流程出現問題時,也可以通過關閉切流控制影響範圍,採用老流程進行訂購訂單處理流程。

webp

這裏補充說下,插件市場和服務市場的老流程都是寫到各自的老數據庫中,而新流程其實也是寫到服務市場的老數據庫中,新數據庫的數據都是通過BinLake寫入的,這樣保證在流程融合過程中的數據一致性。

而流程融合完成後,即讀入口都切到新數據後,就可以逐步切換寫入口了,把兩套數據庫變成一套數據庫。切換的方式其實很簡單,主要是通過配置中心進行逐步切換寫流程,但要考慮切換失敗如何處理異常流,假如遺漏了一個場景,還有業務讀老數據庫,但這時老數據庫裏是沒有數據的,怎麼辦?

所以,準備了兩套方案,一套回滾,另一套補償。考慮到回滾的操作難度很大,因爲代碼回退、流程回滾可能出現的風險會很高,因爲那時數據已經不一致了,所以首選方式是補償,當數據出現不一致時,啓動後端校驗Worker將數據補償到老數據庫中,並迅速修復線上問題。

兩市融合 - 系統架構

隨着融合的深入,服務市場的架構逐步演進成爲經典的三層架構,底部是外部依賴,概括主要是京東商城和京東金融的中臺服務;中間是服務市場的服務層,包括服務引擎、商品中臺、訂購履約中臺和支付中心等系統;上部是服務市場的應用層,包括服務市場大前端、商家工作臺、服務商後臺等系統。

webp

架構部署 - 調用關係

本着 SOA 微服務化的架構設計理念,將服務市場設計爲模塊化和層次化的架構風格,高層次模塊調用低層次模塊,低層次模塊通過接口向上提供服務,以實現系統之間的解耦。但是對模塊的設計粒度拆分的過細,這使得隨着業務的發展,整個系統變得愈加複雜,系統之間的業務調用關係也變得愈加混亂。

webp

架構部署 - 隔離防腐

複雜的調用鏈路,必然造成業務之間的相互影響,所以,通過對服務市場從部署、數據庫訪問、服務PRC調用、消息接收等進行了縱向垂直部署隔離,分爲商智、京麥、服務市場等多套隔離部署層,實現即使任一垂直域無論因爲服務器還是數據庫問題,影響不會擴散到其他業務上。

webp

化繁爲簡 - 簡化架構

複雜的架構,不僅造成新需求消化越來越慢,而且系統也愈加的不穩定起來,這在未來的發展過程中,效率和成本都將成爲很大的問題。所以,痛定思痛,決定進行簡化系統架構,將系統設計的越簡單越好,鏈路越短越好,流程越簡單越好。因爲‘A調B’一定比‘A調B調C調D’的鏈路要簡單,而且出現問題更易於排查。

所以,我們進行了逆向微服務化的架構改造,即系統的整合,確立了三個中心和一個引擎的系統架構,且是多層次的服務對外提供服務,而不是由一箇中心層統一對外,要去中心化,微服務化的架構設計思想也是去中心化,即每個中心都可對外提供服務,因爲層次降低和緯度降低之後,就非常容易定位問題。

系統複雜度等於系統個數加上系統之間的調用鏈路個數,相比簡化之後的架構,可見系統複雜度降低了多少。而且還在業務側逐步改造、遷移、下線一些老業務服務或功能,這相當於給系統做了瘦身,將無效代碼都清理掉了。

webp

化繁爲簡 - 隔離防腐

經過改造後的服務市場,由於系統進行了整合,系統變少了,雖然系統的隔離防腐在部署上看似沒有什麼變化,但每個系統橫跨的業務層是變多了的,我個人認爲這其實是就是組件化的方式,就是一個系統可以複用給多個業務場景。

webp

服務化改造 - SOA

隨着兩市融合的終結,流程融合和數據融合的完畢,系統實現了統一的服務層,這使得對外提供服務的難度降低很多,否則一個服務在多個系統提供相似的功能,這出了問題是很難快速排查的,所以融合不徹底是無法實現服務化的,服務化也要求必須統一入口、統一流程化。

所謂系統架構的終極思想,就是降低軟件複雜度,不是把系統做的越來複雜,而是把系統複雜度做的越來越低。

webp

當系統實現服務化之後,單品頁就不會三千多行的代碼的業務邏輯,還調用了很多接口,而是通過服務化在Action層進行服務接口的整合。同時,也可以靈活的實現各個服務的降級處理,以提高系統的穩定性。

webp

服務化改造 - 多級緩存

MySQL作爲當今主流的數據庫,業務中如果使用的好的話,決定能扛住上百萬,甚至上千萬的量,但是現在大多數系統做不到,這種情況下就要考慮如何做到MySQL防禦。服務市場是一個交易系統,如果把庫打掛了,那將造成系統不能生產,業務不能收錢,這是非常嚴重的線上事故。

早期的緩存架構設計是Jvm-Redis作爲熱點緩存,但是在冷啓動情況下,可能會出現緩存穿透,造成MySQL出現很大壓力。所以,後期設計完全避免這種穿透的可能,Redis完全作爲數據存儲,與MySQL進行隔離,Redis查詢不到數據,就直接返回,與MySQL的數據一致性通過數據異構來實現。

webp

服務化改造 - 數據異構

服務市場使用BinLake進行數據異構,即通過訂閱MySQL的Binlog日誌,通過接收JMQ進行數據異地構建存儲。

數據異構主要有兩種方式,一種是順序消費、另一種是並行消費。其中,在進行訂單、訂購的數據異構時是要求保證嚴格的順序性的,因爲並行消費是無法保證訂單的先後順序的,所以可能造成數據不一致。

但順序消息的問題主要是單點消費效率慢的問題,以及消費出了問題就會造成阻塞,之前使用服務器進行消費,通過ip限制保證單點,後期切換到流式計算平臺(strom/flink)進行處理,流式計算在並行寫es和jimdb有天然的優勢,但如果異常情況下出現寫操作失敗,對於JMQ的重試系統要做好冪等操作的處理。

webp

而商品數據異構是使用併發消費的,因爲商品數據不需要保證嚴格的順序,但商品數據異構的問題,是一條商品數據在MySQL中是存在多張表中,而異構到ES或JimDB中就是一條記錄,那對於商品數據是訂閱那哪些表的Binlog呢?

所以,我們的實踐中商品數據異構是訂閱商品的主表,其他信息通過反查數據庫獲取的。但這個場景下,併發消息雖然會提高處理效率,但由於反查數據庫會造成額外的IO開銷,而且反查數據庫還是主庫,因爲BinLake和數據庫主從同步都是基於Binlog,這兩者之間的速度是無法保證誰先誰後的。

webp

最後,考慮系統誰也無法保證不出問題,所以還使用定時任務在每天一個時間點進行數據一致性的校驗。

積木式賦能挑戰

交易服務平臺

在過去的一年裏,不僅服務市場的系統架構發生了巨大的改變。在融合之後,思考的重心也逐漸變成了如何將越來越多的服務接入到服務市場上進行售賣,所以,工作上,一是對服務市場已售賣的服務進行搜索優化、對先後端類目進行解耦、優化排行等,二是豐富服務市場業務場景覆蓋度,快速接入多樣服務入駐服務市場。

並通過拆解業務、抽象規則、能力下沉,構建積木式的交易服務平臺,實現快速接入官方&三方服務,賦能開普勒、×××零售、7Fresh、國際站等多個業務場景。

webp

服務市場通過服務交易能力提升項目,實現了服務交易流程配置化,將早期入駐服務市場時間需要花費2~4周減少到0天。

流程配置化 - 交易管道

所謂交易管道,簡單說,就是當有一個訂單來了,通過一個流程從訂購、訂單、支付、臺賬、發票、退款等節點往下走,這就是一個管道。但是,如果每有一類服務,就做一個流程,如SAAS一套流程、質檢一套流程、ERP一套流程等,那最終只能通過堆人的方式進行開發,而這種開發效率也是極低的。

其實,通過對業務不斷的沉澱,你會發現大多數服務流程都是有很多相似性的,唯一不同的就是之間的配置,那我們把這個可以複用的功能提煉出來,稱爲配置中心,用工作流的方式驅動這些數據在管道中進行流轉,這就是流程配置化。

webp

流程配置化 - 配置中心

配置中心採用多級緩存、數據庫拖底的方式來保障交易參數獲取效率和高可用,所以,在整個交易的全生命週期裏,都會依賴於配置中心,基於配置中心的參數進行流轉。

webp

商品模版化 - 服務屬性

所謂商品模版化,就是對商品的屬性進行緯度化和屬性化。

參考京東商城的服務發佈流程,一個實體商品的發佈信息,主要包括商品信息、商品屬性、圖片、簡介,及最重要的銷售屬性。一個商品可以認爲是一個SPU,而SKU是通過多個銷售屬性組合而成的,一個SKU纔會確定唯一的價格和庫存。

webp

商品模版化 - 模版引擎

基於模版引擎,在規則上進行剝離,在服務屬性低耦合下,可以通過模版的方式自定義一些服務的發佈信息和規則,並實現屬性與履約規則的配置關聯,作用於交易和訂購履約中。

服務市場發佈的SAAS服務都是需要進行履約的,履約的方式主要有周期+版本、週期+模塊、數量+模塊等,其中版本與模塊的區別在於訂購時升級與續費的邏輯不同。那發佈服務的銷售屬性如何與履約規則進行配置關聯,我們比較了三套方案,最終使用的是方案三。

webp

總結

最後,希望將京東服務市場打造成爲精品的交易服務平臺,做到服務市場更加穩定、交易流程更加便捷、接入服務更加高效。

同時,服務市場團隊也在不斷壯大,新思想的碰撞,有好的方面、也有壞的方面。我希望用自己的行動,不斷影響團隊,讓團隊變得更有凝聚力、更有戰鬥力。

作者介紹

作者:張鬆然

京東服務市場應用架構負責人,京東集團商家研發部架構師。10年的軟件開發和設計經驗,豐富的構建高性能高可用大規模分佈式系統的研發、架構經驗。在京東的五年多時間,負責了京麥平臺的升級改造及歷次618和雙11備戰,最近負責了京東服務市場應用系統的整體架構設計工作,對鬆耦合平臺系統和微服務架構進行了深入而有益實戰。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章