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

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

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

縱深化的業務整合

兩市融合 - 涅槃之路

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

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

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

兩市融合 - 並行業務

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

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

並且服務市場做爲一個交易系統,數據庫是系統的核心,不只MySQL有不少從庫,還有Redis、ES、Solr、HBase等做爲數據緩存,因此在數據異構方面作了不少功夫。架構

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

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

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

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

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

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

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

兩市融合 - 系統架構

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

架構部署 - 調用關係

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

架構部署 - 隔離防腐

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

化繁爲簡 - 簡化架構

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

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

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

化繁爲簡 - 隔離防腐

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

服務化改造 - SOA

隨着兩市融合的終結,流程融合和數據融合的完畢,系統實現了統一的服務層,這使得對外提供服務的難度下降不少,不然一個服務在多個系統提供類似的功能,這出了問題是很難快速排查的,因此融合不完全是沒法實現服務化的,服務化也要求必須統一入口、統一流程化。

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

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

服務化改造 - 多級緩存

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

早期的緩存架構設計是Jvm-Redis做爲熱點緩存,可是在冷啓動狀況下,可能會出現緩存穿透,形成MySQL出現很大壓力。因此,後期設計徹底避免這種穿透的可能,Redis徹底做爲數據存儲,與MySQL進行隔離,Redis查詢不到數據,就直接返回,與MySQL的數據一致性經過數據異構來實現。

服務化改造 - 數據異構

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

數據異構主要有兩種方式,一種是順序消費、另外一種是並行消費。其中,在進行訂單、訂購的數據異構時是要求保證嚴格的順序性的,由於並行消費是沒法保證訂單的前後順序的,因此可能形成數據不一致。

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

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

因此,咱們的實踐中商品數據異構是訂閱商品的主表,其餘信息經過反查數據庫獲取的。但這個場景下,併發消息雖然會提升處理效率,但因爲反查數據庫會形成額外的IO開銷,並且反查數據庫仍是主庫,由於BinLake和數據庫主從同步都是基於Binlog,這二者之間的速度是沒法保證誰先誰後的。

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

積木式賦能挑戰

交易服務平臺

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

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

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

流程配置化 - 交易管道

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

其實,經過對業務不斷的沉澱,你會發現大多數服務流程都是有不少類似性的,惟一不一樣的就是之間的配置,那咱們把這個能夠複用的功能提煉出來,稱爲配置中心,用工做流的方式驅動這些數據在管道中進行流轉,這就是流程配置化。

流程配置化 - 配置中心

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

商品模版化 - 服務屬性

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

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

商品模版化 - 模版引擎

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

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

總結

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

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

做者介紹

做者:張鬆然

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

相關文章
相關標籤/搜索