《京東技術解密》——海量訂單處理
OFC的重要性2014年的618顯得和以往任何店慶促銷日都不同,不僅僅是因為電子商務本身在中國不斷飛速發展對京東系統帶來的挑戰,更為重要的是2014年5月22日剛走入美國納斯達克殿堂的京東聚集了最耀眼的光芒,能不能保持這樣的光芒,618則會是一份很有說服力的答卷,當然我們最終給出了滿意的結果。作為一個普通的購物者,當我們在瀏覽器中輸入www.jd.com并回車,便可以看到京東商城的首頁,根據自己的需要選擇喜歡的商品,然后加入購物車,提交訂單后,即可享受京東的極速物流體驗,最終完成一次簡單快樂的購物歷程。其實,訂單提交后,需要經歷多個環節和各個系統的處理才能完成使命。其中有一個環節是訂單必須經過的,而且這個環節連接了用戶下單和訂單在庫房的生產,就是訂單履約中心(OFC,Order Fulfillment Center),本章我們就為各位解密這個部門。 2014年的618后,京東技術團隊分享了如何應對店慶日及以往促銷活動在技術方面的經驗和探索。其中有一講“電商海量訂單處理OFC系統的關鍵技術環節”(見京東技術開放日第一期),說的就是這個部門做的事情。 這個部門的職責,用彭青的話講就是,轉換用戶訂單為各終端系統的生產單,并且按要求送達到相應終端系統。舉個例子,就好比我們將采集到的原始食材按照客戶的不同口味(不同系統)進行烹制,并且在指定的時間內做好后送到客人(終端系統)那里,整個過程包括訂單的拆分轉移和訂單的下傳。其實我們從網站下的訂單(也叫原始單)在庫房是直接生產不了的,需要經過OFC這個環節的處理后,才能到達各個生產系統。由此可見,這個環節必然會有大量數據需要處理,而且還要保證時間。 想必大家知道關于京東的211、311等配送方式,如果用戶選擇不同的配送時間,京東的快遞就必須在用戶指定的時間送達,而如果下游的生產系統收到訂單數據比較晚,就會影響后續的配送時間,最終會影響客戶體驗?,F在訂單下傳,對接的全國庫房近150個,需要調用的外部處理訂單服務也有近20個,而每個系統的處理能力和響應能力又各不同,這就需要我們進行相應的調節流量的配置,這其中只要有一個系統存在問題,就可能會影響訂單的下傳。 OFC的形成2003年京東網站創立之后,迎來全國電商的快速發展,京東的業務隨之不斷增加,導致相應的業務系統也在持續增加。直到2011年,隨著系統增多及業務的需要,逐漸成長出來一個小團隊,負責在各個系統之間進行數據的傳輸,將客戶訂單數據傳到庫房,同時需要將非客戶訂單,如采購單、供應商、內配單等二十多個業務傳輸到相應的業務系統,至此OFC成形。 初期由于各個系統的不完善,導致數據傳輸總是存在各種各樣的問題,訂單總會卡在這一環節,而作為傳輸環節又必須保證數據能正確傳輸完畢,這就需要我們必須了解上下游系統的業務及數據處理的過程,只有這樣才能知道問題產生的原因,才能知道該如何去處理問題。但是由于上下游的系統是需要經常上線新需求的,我們每天需要及時了解上下游系統業務的處理,才能保證我們的環節沒有問題。 那段時間兄弟們真的很辛苦,每天需要處理上千個工單,加班更是常事,以至于一個同事說睡夢中都在處理問題單。由于業務領域劃分存在問題,系統邊界不明確,導致出現許多莫名其妙的問題,兄弟們干得很苦很累,直到彭青來了之后。彭青帶著一個厚厚的黑色全框眼鏡,個子不算太高卻有個小肚腩,學生族的發型讓人感覺很親切。彭青根據他多年的工作經驗和對系統的理解,對這塊業務進行重新劃分,逐漸將非客戶工單的數據傳輸工作交接給對應系統進行處理,將兄弟們解放出來,開始客戶訂單處理的新征程。 到2011年底的時候,在彭青的帶領下我們已經成為了二十多人的團隊。為了更進一步拓展在客戶訂單方面的業務領域,我們主動接手了訂單拆分系統和訂單轉移系統。這兩套元老級系統是用.Net編寫的,由于前輩們大都不在職了,文檔也不完善,對于系統內部業務了解的人很少,修改非常難。而此時每天由于系統問題導致的事件單多達上百,也就是說每天運維帶來的工作量都是可觀的,在這樣的情況下,接手這兩個系統自然全無阻力。 技術的改造.Net到Java系統接過來了,第一步要做的事情當然是重寫。對技術的選取,根據當時公司技術發展戰略以及Java的普及,我們選用了Java。重寫過程中需要梳理已有的業務,自然少不了不斷和原來系統的人員進行交流,去確認業務流程和技術處理細節。經過一個多月,系統的重寫總算完成,接下來的工作就是上線了。 開始小流量地切,我們通過開關進行控制,通過省市縣區域分流,到2012年2月系統算是上線了,而之前的.Net系統也逐漸退休了。到這時候,OFC逐漸根據業務劃分為3塊,第一塊是訂單拆分,第二塊是訂單的轉移,第三塊就是我們前面提到的訂單下傳和回傳。 這里要給大家解釋一下:
211訂單履約率提升項目重寫完之后,系統總算可以正常運轉了,而接下來的事情就是對系統的進一步梳理和優化,以更好地支持將來業務需求的發展以及技術方面的擴展。當然有的時候系統的改進往往是由于外部業務的無法適應導致的,這也符合變革的本質。用戶體驗至上一直是每一位京東人追求的目標,就連我們的老劉也會隔三差五在網上下單來體驗一下,而這次老劉發現了一些問題。當他下單后,等了半天才收到訂單,這讓老劉無法忍受。經過調查后發現,從下單到庫房竟然花了兩個多小時。
改造前的系統整體設計圖 于是老劉立即成立了一個叫作“211訂單履約率提升”的項目,該項目涉及11個系統的升級改造,包括訂單交易系統、訂單管道系統、拆分系統、轉移系統、訂單任務系統、OFC相關系統、預分揀系統、面單系統、增值稅資質服務、發票系統、WMS系統。其中4個系統需要全面改造,3個系統需要大量改造,剩下的4個需要少量改造,而且由于與訂單相關的業務點多且邏輯復雜,無法在測試環境下全面測試。這不僅影響著整個訂單的正常生產,甚至會影響財務相關業務。項目任務非常重要,要求兩個月內保證訂單從下單到庫房的時間縮短到5分鐘內。大家馬上開始了工作——需求討論6天,設計方案5天,開發15天,功能測試20天,性能測試44天,上線部署調試26天,總計工時達5066小時,最終實現了項目目標。與此同時訂單下傳各環節的服務性能指標也得到了規范,使得訂單下傳趨于穩定,理順了訂單下傳流程。技術方面也得到了鍛煉,使用了Zookeeper分布式配置、CXF Timeout設置、Log4j多Tomcat示例配置、Oracle數據庫分區轉歷史方案,數據庫使用了OracleExadata、MySQL。在這過程中和Oracle技術團隊直接溝通多達10次,在數據庫設計方面、性能調優、轉歷史數據方面都得到了提升。更為重要的是鍛煉了團隊,對于戰勝艱巨任務有了更大的信心。下面是系統的整體設計圖。
改造后的系統整體設計圖 對于拆分,在幾位大牛對系統的業務進行梳理后,發現部分業務有些混亂,業務領域劃分得不是很清楚,拆分系統中除了需要根據商品的不同屬性進行拆分外,還需要對訂單中使用的金額、優惠、運費等信息進行分攤處理。這幾位大牛敏銳地發現系統這樣設計是有問題的,于是就把金額信息處理邏輯拿出來,專門做成一個服務——OCS訂單金額計算服務(OCS),拆分只需要對其調用就可以。同時,我們對OCS分攤結果的數據進行了持久化數據存儲。系統這樣設計,不僅解耦了拆分服務之前混亂的業務處理邏輯,OCS的數據也一舉填補了公司這方面數據的空白,成為其他系統使用和處理業務邏輯的數據基礎來源。到現在為止,直接使用OCS數據的系統就有二十多個,其重要性不言而喻。 SOP合頁單項目2013年,公司級項目SOP合頁單要啟動,即用戶購物車里既有京東自營的商品同時有POP商家的商品(SOP)。在結算的時候只需要提交一次(之前只能分開提交,類似淘寶多商家的商品只能單獨提交)。為了改善用戶體驗,同時需要將提交之后拆分完的子單結果顯示出來,需要我們團隊提供一個拆分服務供交易組使用,這是一個重大的考驗。下單環節的速度非???,TP99一般都是幾十毫秒,而我們目前的服務則是幾十秒,完全不在一個數量級。為了保證項目能夠順利完成,我們既需要滿足日常的業務需求,同時要新切出一個分支進行修改,用于此次項目,同時需要將針對新需求的代碼及時同步到這兩個分支上,任務非常艱巨。解決了開發問題后,就要想著如何在性能上有所提升,比如,可以放在內存里處理的就放在內存中操作;盡量減少對外部服務的依賴;對于非同步化的操作進行異步化;對于部分服務我們甚至采用降級的方式,在必要時通過開關進行降級,保證整個服務的整體性能。如此這般后,我們主動要求性能測試組對我們的服務進行性能測試,在代碼級別進行了優化,最后在指定的時間內成功地完成項目。而此時我們在維護著同樣級別的3份拆分服務代碼,老的下單對應的我們前面說的老拆分,新的下單對應的我們新的拆分,還有我們為交易系統提供的預拆分。 而在此時最困擾我們的不是維護這些系統,而是經常會由于網絡不好,使一個訂單的服務超時,進而導致服務進行重試,而事實上訂單已經提交成功。這就可能使我們錯誤地提交兩次甚至是多次訂單,比如客戶下一個原始單,需要拆分成兩單,但是由于上述原因可能會得到多單;如果用戶選擇貨到付款,會給用戶造成困擾,會帶來配送的成本,如果是在線支付的話則會導致公司的損失。剛開始的時候沒有解決方案,只能通過監控去發現,發現后人為鎖定這些訂單,而這樣不但增加了運維壓力,而且人工處理難免會有失誤。由于我們在提交子單之前會獲取訂單號,每一次獲取的訂單號都是新的,這會導致調用這個服務時對訂單號是無法防重的。后來海波想到一個防重方案,就是我們在調用這個服務之前將訂單號信息輸入自己的防重庫,新訂單來的時候先在防重庫中進行查儲,如果有訂單信息則說明之前提交過,本次提交失敗,然后直接把庫里相同訂單號的數據拿出來提交即可,這樣還可以節省訂單號。如果庫里沒有查到,我們將該訂單號插入庫中,同時調用服務。問題得到有效解決。本次提交經過這一系列的處理優化,系統總算是比較穩定了。 轉移架構升級轉移系統也進行了大規模的調整,為了進一步保證訂單及時準確地轉移到下游的庫房系統,轉移團隊在業務和技術架構上進行了一系列的改進:業務和數據處理異步化,即將可以異步化處理的業務和數據放入分布式隊列,由對應的模塊處理;使主流程業務簡單快速流轉;數據處理并行化,將數據切割成多個業務單元,并行處理業務單元;針對變化少、實時性要求不嚴格的熱點數據,使用緩存并配以更新機制,以提高性能;對于業務洪峰,通過平滑控制保護后續系統不被洪峰壓垮。 在業務流程方面也進行了優化。由于涉及訂單生產流程,需求變化速度非???,需要不斷梳理現有流程,去除不必要的流程,減少有新需求時對不必要業務流程和分支的考慮。同時,需要對現有分散業務不斷地抽象和改造,以方便業務擴展。 面對這么多的優化和改進,每次上線的風險無疑是巨大的,如何規避風險呢?那就是要分流、可配置化,以及運營工具先行。由于新上線的項目風險較高,特別是容易忽視一些對外交互的小功能,而發生線上問題時又無法及時切換。因此,需要對業務上線進行分流,并且通過靈活便捷的配置中心隨時進行控制。對于異常情況一定要優先考慮,并且開發相應運營工具,以備緊急情況使用。尤其不能抱有僥幸心理,認為小概率事件不會發生在自己身上。 轉移團隊的負責人鐵總(大家總是這樣稱呼他)已經從事電商十余年了。這個來自湘西的漢子對待工作總是嚴肅認真,但面對生活卻又充滿熱情;結婚前總會泡在游戲中,或者癡迷羽毛球,女兒出生后便成為了他的一切。在談到轉移未來的規劃和發展時,他充滿自信地說:“將來會在保證客戶體驗的同時,更多地通過在成本和流程上優化來降低成本。庫存分配將在保證訂單履約的前提下,打破現在先下單先占庫存的規則,提高商品庫存周轉率和現貨率,同時給客戶提供更早的收貨時間選擇”。
轉移系統整體流程圖 不得不愛的運維剛開始負責客戶訂單系統時,每天要處理上千條Ticket(訂單事件),而現在只需處理幾十條。這種銳減,不僅說明了系統日漸健康、業務逐漸規范,更證明了我們的運維流程和運維制度正日趨成熟。這些成果都離不開善于分析總結的文杰,他是一位來自山東的80后,在團隊中主要負責運營流程優化和與協調相關的工作,團隊在運維方面的問題目前還沒有他解決不了的。OFC是連接用戶和全國終端庫房的重要的通道樞紐,這其中的任何系統出了問題,都會導致訂單無法正確實時地到達終端庫房,后果都是不堪設想的。因此,每新增加一個庫房都需要團隊進行庫房的終端系統部署和調試,直至生產系統測試完成為止,我們稱此為開倉過程。隨著公司不斷發展壯大,訂單業務不斷完善,全國現存倉庫已超過150個,這都是文杰和團隊無數日夜的付出換得的。支持審計也是不可忽略的一部分工作,每季度我們都會給同事講解新業務,給他們解釋差異訂單的原因。同時,我們還負責新業務的學習推廣,讓團隊的新成員能夠快速了解業務知識、熟悉業務系統。伴隨著業務和系統的日漸完善,我們也在不斷地嘗試和推廣系統的智能化運維與支持,相信在不久的將來我們一定會實現無人化系統運維。 從618到雙11從2012年開始,店慶促銷活動力度在逐次增加,訂單量則成倍增長。伴隨著訂單量的增加,系統面臨的挑戰與日俱增——訂單業務越來越繁雜,業務處理流程也越來越多,很容易出現數據不一致問題。因此,在處理海量訂單時保障數據一致性非常關鍵。系統整體控制上要采用流程控制中心,而不是階梯式控制。之前由于直接依賴數據庫,數據庫最終會成為影響訂單處理的瓶頸,數據的一致性很難得到保證,而采用流程控制中心模式則可以大大減少數據不一致發生的幾率,同時可以借助工作流和狀態機實現中心控制,這樣既便于運營,又方便及時發現和解決問題單據。
流程控制中心和階梯式控制 支持海量訂單處理無論系統如何優化,單個系統總有瓶頸,要支持不斷增長的訂單處理量,關鍵在于提高系統的擴展能力。首先,核心系統的每一層都要有擴展能力,可以以實例為單位進行擴展,也可以以集群為單位進行擴展。其次,系統整體要有擴展能力,可以根據實際業務特點,從業務上進行垂直拆分以實現擴展,也可以通過分布式部署來方便地增加一個具備整體功能的集群,從而快速增加處理能力。這相比僅做備份系統而言,節約了成本。 所有核心的OFC訂單處理系統已實現了水平擴展能力,部分系統實現了分布式部署改造。在2014年618大促前,正是由于系統具備這種擴展能力,才能夠在非常短的時間內擴展了處理能力,保障了大促的順利開展。我們的最終目標是,所有核心系統都要完成分布式部署。 解決數據一致性問題早期的訂單處理流程分散到多個應用系統中,數據來源不統一,也缺乏統一的狀態機控制,經常出現數據不一致問題。但同時,也不可能由一個系統來管理所有的流程,因為維護和管理工作會非常龐雜。解決辦法是,梳理出訂單處理的主流程和狀態機,然后由主流程系統負責整體流程的調度和數據的推送。這個主流程可能跨大的業務域,如物流領域和資金領域,每個領域內可以有工作流,但不能與主流程沖突。識別出主流程系統還有其他的優點:一是可只重點建設主流程相關系統,使其成為穩定的系統集群,而非主流系統則可以投入較少的成本,從而既有利于保障業務順利開展,又能降低整體建設成本;二是主流程系統可以有效地保障生產計劃的執行;三是主流程系統可調節系統流量,有效地平滑業務高峰,保護主流程相關各主要系統的穩定運行。 支撐運營工作對運營工作的支持,包括搶險、預防,以及“治理+預防的升級”。在早期階段,系統架構主要是支撐業務功能的實現,沒有為運營而設計,線上系統會因為各種意外而影響業務,讓系統團隊疲于應付。后來,確立了為可運營而設計的理念和原則,設計時必須考慮可監控、可運營,同時把可用性、穩定性、健壯性等列為設計的重點,在實踐過程中確立了自己的方法論。 第一,對系統進行梳理,識別出核心系統,把核心系統建設成為可用性高、可靠性高的系統,保障這些系統少出問題,出問題后系統要能自動恢復。 第二,保證系統出現問題后能快速發現問題,甚至在問題發生前發出報警。為此需要有對數據積壓量趨勢的監控,以及在有積壓情況下吞吐能力的監控。這些監控需要及時,我們針對分布式系統,開發了分布式監控系統,能夠迅速地反應每個部署的每一個實例的情況,又能收集整體的運行情況。 第三,保證發現問題后可以快速定位和處理。為此我們設計了集系統處理能力、數據積壓情況、數據處理情況、日志、系統負載于一體的統合分析工具。 第四,一個系統出現問題,往往會將影響傳遞到其他系統,系統治理勢在必行,目前我們已有SOA治理平臺(正在優化過程中),目標是能夠理清各系統的血緣關系,完善SLA體系;在出現問題后可以及時評估出受影響的系統,快速做出應急響應。 海量數據的開始總原則訂單處理系統與交易系統本身是存在區別的。交易系統直接面對客戶,所以系統可用性要求和性能要求非常高,特別是在高并發情況下的系統表現,所以交易系統在架構上的重點在于解決這兩個方面的問題。而訂單處理則不同,系統短時間不可用,響應出現延遲不會對客戶造成直接影響,也就說我們關心的是平均值而不是某時刻的峰值。訂單處理系統架構設計的關鍵在于如何處理海量數據,以及數據一致性的保障。近年來,京東的業務領域不斷拓展,訂單量飛速增加,所以必須保障系統吞吐能力得到提升。與此同時由于涉及的系統眾多,各系統業務處理方式和流程不同,導致各系統性能指標差異較大,所以要定義好各個系統的SLA指標。由于訂單的業務越來越復雜,那么系統的業務流程也會越來越多,這就需要我們劃分好主次業務流程以及優先級,同時需要設計靈活多樣的降級方案,保證主業務正常運營。
OFC整體架構圖 系統保護涉及OFC調用的訂單系統很多,而各個系統處理的能力均不相同,不是所有的系統都要承擔高峰值處理的壓力。這就需要有針對性地控制、調用這些系統,具備削峰和流量控制的功能,以間接保護上下游系統,防止調用方的系統雪崩式掛掉。還有就是監控,要有統一的產能監控;要防止過載,在過載之前要能進行控制,要保證自身系統的安全穩定,還可以采用快速拒絕的機制。 分布式系統主要是在擴展方面進行設計,保證系統每個切片可以水平擴展,也可以以集群為單位進行擴展,實現分布式任務隊列。我們每一個Group能處理的訂單量在可控制的范圍內,一旦某一處出現瓶頸,可以隨時部署一個或一套Group。下圖中不同Group可以彼此獨立部署,也可以整體部署,當某一處出現問題時可以單獨進行部署,或者整體流量大時也可以復制部署。
分布式系統架構 而分布式任務處理架構圖如下,在分布式任務處理引擎的基礎上,我們可以通過在圖下方左側的分布式任務隊列(Redis緩存)中取任務,然后由我們的引擎一步一步去調度相應的服務,將結果返回給對應的服務進行業務處理,同時也返回我們需要的結果,真正將交易快照數據轉換為生產單據,最后將數據推送到客戶端系統,比如庫房系統、POP商家系統。
分布式任務處理架構 分布式任務隊列設計可以通過下圖說明。首先我們會對任務進行分片,定義每一個任務為一片,然后將任務在任務執行器中加以處理,而每個任務執行器又有多個線程去處理和調用不同的服務,最終再將結果返回。這里還會有一個異常任務隊列,對于那些處理失敗的任務,會將其放入異常任務執行隊列,進行異常處理流程的執行??赡艽蠹視?,如果系統掛了,那個任務的數據也將丟失,沒有執行完任務怎么辦。事實上只要我們的原始訂單數據存在,完全可以恢復為再次執行,最多執行會緩慢,但不會導致數據一致性出現問題。
分布式任務隊列設計 我們的分布式任務隊列采用了工作流的機制,支持靈活的流程配置,這主要通過Zookeeper來進行分布式配置,可以動態添加業務處理環節。同時,可以自動調節系統的吞吐量,當任何一個環節出現問題時,都會進行自動降速,當問題得以解決后,我們會進行自動增速,保證系統的吞吐量;我們還可以通過配置對一些高級別的訂單進行優先生產處理。 系統部署如下圖所示:
系統部署圖 一直在路上的OFC人從2011年6月初只有五六個人的小組,到今天三十多人的團隊,從開始只負責非客戶訂單相關業務系統,到今天負責公司核心的0級訂單系統,OFC業務范圍橫跨了整個訂單生產過程的大半個生命周期。是的,就是這些普通人,在紛亂中不迷茫,在歡笑中不忘使命,表面屌絲內心渴望前進的OFC人,義無反顧地堅持在訂單系統的一線上?;赝哌^的路,我們竟如此平靜而淡定,遙望遠方,我們依舊充滿激情,依舊會綻放陽光般的笑容。因為這是個偉大的時代,偉大的國度,因為這里有一群偉大的人在做著一件偉大的事情——為了讓購物變得簡單快樂,而我們便是那群人。
OFC開發團隊及測試團隊合影 該文章在 2015/1/16 16:57:13 編輯過 |
關鍵字查詢
相關文章
正在查詢... |