當當網海量信息的組織與發(fā)布經驗分享
當當網自成立以來,內部技術體系的發(fā)展已經有15年左右的歷史了。系統架構也經歷了從高度集成的軟件向分布式、低耦合、SOA化系統的演進過程,形成全面支持網上零售業(yè)各種業(yè)態(tài)模式的系統架構,每天支撐著千萬級的
當當網自成立以來,內部技術體系的發(fā)展已經有15年左右的歷史了。系統架構也經歷了從高度集成的軟件向分布式、低耦合、SOA化系統的演進過程,形成全面支持網上零售業(yè)各種業(yè)態(tài)模式的系統架構,每天支撐著千萬級的PV訪問,承載了超過100億元人民幣的年營業(yè)額,2013年雙11峰值流量達到日常的10倍。
作為一個典型的自營與開放平臺相結合的網上零售電子商務平臺,當當網網上購物流程由多達上百個大小系統共同實現。當當網最終服務于消費者,良好的用戶體驗、錢物準確是立足的根本,因此對系統穩(wěn)定性、可靠性、準確性有非常嚴格的要求。任何時候都能保證線上系統的穩(wěn)定運行,是我們工作的第一優(yōu)先級。電商系統的運行峰值通常出現在各類促銷、營銷活動期間,以及大量集中收訂的訂單帶來很大的生產和配送壓力時。
除了參加每年的雙11和雙12大促、每年的10月店慶、業(yè)內重要的慶典、兩次開學季圖書大促、換季服裝大促、常規(guī)的新品和尾品大促以外,當當網每個月至少會有一次公司級別大促,而各種中小型大促常年不斷。各種促銷活動均可以閃購、秒殺、大量SKU促銷等模式實現。網站流量的來源除了新老用戶的直接登錄以外,還包括多種站外引流方式如網址導航、聯盟、搜索引擎、各種線上線下媒介、短信、郵件、微信等通道。
因流量來源的不同,相應用戶的瀏覽、購物模式也大有不同。如很多促銷落地頁是當當網的館”,或者專題頁,那么我們可以在活動之前做非常有針對性的準備;有時用戶已提前準備好了購物清單,如雙11這樣的促銷中,訂單轉化率會比平時高,體現在訂單收訂和賣場流量不會成比例上漲——如訂單收訂上漲6倍,賣場流量可能只會漲3~4倍;而一些外部引流方式會帶來大量無效、垃圾流量,所以訂單轉化率會比正常流量低。
有的活動流量會對首頁有較大影響;有的活動會對購物車有較大影響,如閃購類的限時購買或復雜的促銷邏輯;有的活動會對當當網的倉儲、配送系統有較大影響,如當當網配送的訂單;有的活動會對開放平臺有較大影響,如商家訂單。
因此,摸清業(yè)務模式和活動特點,是設計和運維高峰值電商系統,即高伸縮性系統的重中之重。但從另一個角度來說,在沒有動態(tài)彈性部署的前提下,過度的設計和服務器部署是一種浪費,特別是硬件非常有限的壽命會帶來每年巨大的成本攤銷。
當當網根據業(yè)務發(fā)展速度和業(yè)務運營規(guī)律,結合多年的經驗,制定的系統伸縮性的設計原則和硬件常備策略使各流程能夠直接應對日常5倍業(yè)務量的上漲。通過增加服務器的方式,能夠應對10倍業(yè)務量上漲。而如果要應對10倍以上的上漲,則需要提前做有針對性的系統優(yōu)化。但無論當前承受的業(yè)務量是否超過了設計范圍,都不能影響設計范圍內業(yè)務量的正常處理。
設計和部署大流量、高并發(fā)系統的技術方案選擇比較多,業(yè)內有很多成功經驗和案例。但根據我們的經驗,設計高峰值的網上零售業(yè)電商應用系統通常要面對以下幾大難點。
應用架構復雜,業(yè)務發(fā)展快,迭代速度快,各系統之間盤根錯節(jié),歷史包袱重。不僅有牽一發(fā)而動全身的風險,更有邊緣case出錯影響主流程處理、耗盡過多資源的隱患。從前臺到后臺的業(yè)務流程長,用例多。在能承受的最大峰值上,存在短板效應。設計實現時要面面俱到。通常促銷活動的持續(xù)時間短而集中,前期推廣活動已經啟動,在活動期間,短暫的系統不可用,也會帶來慘重的銷售損失與負面影響,沒有亡羊補牢的機會。要確保系統的穩(wěn)定性,平時的工作就要做足。針對這幾大難點,有以下幾大應對策略。
基于SOA架構理念,降低系統耦合性,接口定義清晰明確,保證獨立子系統的健壯性高,降低故障跨系統擴散風險,從而將伸縮性的困難逐步分解到各個系統。對系統進行分級,集中力量,突出重點系統。當當網從賣場到交易流程均屬于一級系統,這部分系統直接關乎用戶體驗和訂單量。在系統穩(wěn)定性和可靠性等指標上,設計標準高于后臺系統。優(yōu)先考慮用異步處理代替同步處理,做好系統異常的降級方案,保證有限的合格服務。在描述電商平臺峰值系統的設計之前,通過下圖可簡單了解當當網電商平臺的幾大組成系統:賣場系統,促銷、會員系統,商品管理系統,交易系統,訂單管理系統,倉儲與調撥系統,物流與配送系統,客服與退換貨系統等。
系統分級
對于電商網站,用戶體驗是第一位的,系統穩(wěn)定運行是保證用戶良好體驗的基礎。在資源有限的條件下,采取對系統進行級別劃分的方式,對高級別系統保持重點關注,在設計、部署、監(jiān)控等方面確保高級別系統具備良好的伸縮性、健壯性和敏感度,能夠應對電商業(yè)務中不確定的極限峰值沖擊。
當當網基于可能對用戶產生影響的程度與敏感度,將所有應用系統分為三級,簡單描述如表。
依此標準,當當網的一級系統主要包括賣場系統、商品詳情、價格系統、庫存系統、促銷系統、購物車、交易系統、支付系統、會員系統等。
二級系統則包括商品信息系統、訂單系統、ERP、倉儲系統、物流與干線運輸系統等。
三級系統主要是結算系統、報表系統,以及運營、活動管理類系統。
其中一級系統基本可分為兩類,第一類為面向用戶訪問的前端頁面,第二類為購買流程所涉及的系統。一級系統的關鍵指標是可用性,在設計和部署時都要高標準嚴要求,要求具備完善的容錯降級機制,日常保持較低的系統運行負載,配置高級別的監(jiān)控告警流程,出現問題在要求的SLA標準內修復與解決。這兩類系統的核心業(yè)務功能定位不同,采用的技術也不同,前端頁面系統主要使用PHP語言,購買流程則主要由Java語言實現。
前端頁面系統是電商業(yè)務的流量入口,需解決的核心問題是保證大流量高并發(fā)情況下的快速展示可用,這方面業(yè)界已有較為成熟的解決方案,如CDN、緩存、靜態(tài)化、異步加載、與依賴的數據源解耦、同機部署、數據庫讀寫分離等。通過這樣的設計使前端無狀態(tài)頁面應用可以水平擴展,增加Web服務器即可提升系統能力。
為充分發(fā)揮系統資源潛力、提高性能,我們引入HHVM對PHP代碼進行優(yōu)化加速,經過性能測試驗證,取得了顯著效果,性能提升超過100%?,F在當當網前端頁面系統具備支撐10倍流量沖擊的能力,面對超出極限的流量峰值,我們也有預案,主要采取延長緩存時效、本地靜態(tài)化方式,屏蔽峰值流量對后端系統的沖擊,并具備容錯機制,在后端非關鍵服務失效時優(yōu)雅展示等。賣場系統作為生成各種活動專題頁面的工廠,支持通過配置將頁面組件靜態(tài)化,以滿足更高訪問量的要求。
購買流程是電商業(yè)務流程中至關重要的環(huán)節(jié),一旦出現問題,將使前面的引流、促銷、搜索、推薦等營銷成果付諸東流,因此購物車、交易系統和支付系統必須確保用戶購買結算過程的高效穩(wěn)定,并保證數據持久化的準確性和一致性。
購物車與交易系統邏輯復雜,依賴服務眾多,其中交易流程的實現依賴超過100個服務。我們梳理出核心業(yè)務流程,再根據與核心業(yè)務流程的關系,區(qū)分出對服務的依賴性強弱。弱依賴服務如積分、禮券、收藏夾等,通過較好的容錯和降級機制,在業(yè)務量達到峰值時,可通過服務降級維持核心業(yè)務流程的穩(wěn)定運行。對于強依賴服務中數據變化較少的配置查詢類服務,則通過緩存數據來降低服務依賴關系,犧牲部分數據的及時性換取系統的健壯性。
交易型系統的業(yè)務,成功率是關鍵指標,可能因為分布式服務集群中部分實例異?;蚓W絡問題導致調用強依賴的服務失敗,需要發(fā)起重試,為兼顧用戶體驗和減少對系統資源的占用,采用設置較短超時時間及重試其他服務節(jié)點方式更為合理。經過優(yōu)化,購買流程的系統可用性指標達到了99.99%。
二級系統多數為后臺訂單與履約系統。在流量漏斗模型下,在一級系統內形成訂單后,訂單流轉到二級系統,二級系統面對的峰值壓力要小得多。
二級系統多采用異步方式進行系統交互,對于超出處理能力的業(yè)務數據,異步機制削峰填谷,使系統得以在可控的壓力下運行。系統資源占用維持在較高水位,既能充分利用系統資源,又可以保證較高的處理效能。當然,異步機制帶來的延遲問題也必須控制在合理范圍之內,在業(yè)務量驟增時可以容忍一定程度延遲。如果平時就經常出現延遲,則需要進行優(yōu)化,或者重新進行容量規(guī)劃,提高系統整體的吞吐能力。2014年為應對雙11及未來業(yè)務發(fā)展,當當網對訂單系統數據庫進行了擴容,規(guī)模達到之前的5倍,其他部分系統也進一步分庫分表,使之具備承載更高業(yè)務峰值的能力。
系統分級是根據不同系統的特點,結合公司業(yè)務戰(zhàn)略關注點進行的差異化處理。電商業(yè)務鏈貫穿多個系統,每一個環(huán)節(jié)都不容忽視。一級系統固然是核心優(yōu)化的重點,二三級別系統的技術指標要求也同樣嚴格。
我們對每個系統的可用性都有嚴格要求,并將監(jiān)控系統列為一級系統,時刻關注木桶理論中最短的那塊板子,我們的目標是打造一套性能均衡,沒有明顯短板,日常能夠應對5倍業(yè)務峰值壓力的電商系統平臺。
解耦與SOA實踐
經過多年實踐,當當網逐步完成系統架構的SOA化改造,并通過SOA化,實現了服務解耦與高內聚,簡化了架構復雜度,這是主流零售型電商平臺通常選擇的道路?;诜植际降姆帐瓜到y具備更強的伸縮性和擴展性,系統瓶頸更易定位和優(yōu)化,滿足業(yè)務快速增長的需要。
SOA即面向服務的架構,在業(yè)界并沒有統一的標準,但有一些公認的設計原則:標準合約、松散耦合、服務抽象、可復用性、服務自治、無狀態(tài)性、可發(fā)現性、可組合性。
在實際應用過程中,根據系統情況以其中部分原則為側重點,不求全責備,簡單實用為上。
2012年起,當當網啟動一系列重點項目,首先對開放平臺進行重構,使開放平臺成為搭建在PIM、庫存、價格、促銷、訂單、TMS等主業(yè)務系統之上一套具備更靈活的擴展性的業(yè)務平臺。
這次重構是當當網近年的重大架構調整之一,之后各主業(yè)務系統陸續(xù)實現業(yè)務平臺化,支持多商家甚至是平臺級跨商家的業(yè)務模式。開放平臺將原有獨立管理的商家商品信息、訂單流程遷移至PIM系統和訂單系統進行統一管理,充分發(fā)揮服務的可復用性,減少重復邏輯的多點實現帶來的開發(fā)和維護成本。
商品信息是電商業(yè)務系統中的核心主數據,是促銷、價格、庫存、禮券、搜索等系統的基礎數據來源。PIM系統作為商品主數據系統,承擔著管理商品基礎數據、關系、品牌、類目和狀態(tài)等信息的職能,商品數據量在千萬級別。
PIM系統的SOA建設經過了兩個階段。第一階段主要是實現服務化,因服務設計粒度過細,發(fā)布的服務達到數百個,其他系統要完成一個業(yè)務功能可能需要調用多個PIM服務,增加了服務使用方的邏輯復雜度,也帶來了更多的網絡交互開銷,不能稱為SOA的最佳實踐。
為此,又進行了第二階段改造,將第一階段實現的服務定義為基礎服務,根據業(yè)務需要將其組合,提供粗粒度的對外服務,解決了之前的問題。粗粒度服務能夠提供獨立的業(yè)務功能,可能同時依賴于多個系統的基礎服務,當服務使用方因業(yè)務需要調用多個粗粒度服務時,可能會對同一個基礎服務發(fā)起多次訪問,產生疊加的系統壓力。我們經過分析認為,底層服務資源的消耗能夠簡化上層應用邏輯,對于系統架構層次的合理性更為有益,只要提高底層基礎服務的性能,上層服務能力將更具彈性。
遵循SOA的系統解耦有時會增加系統資源開銷,甚至降低部分服務性能指標,但可使系統架構更為清晰,增加服務復用性,具備更強的業(yè)務擴展性,提高開發(fā)測試效率,降低開發(fā)運維的人力成本,及時響應業(yè)務創(chuàng)新,使IT系統重現活力。
通過上述系統架構治理,當當網以很少的臨時性系統準備順利度過2013年雙11大促。
海量動態(tài)信息流的快速發(fā)布
當當網打造綜合品類電商平臺,開放商家入駐,隨之而來的是商品數據量迅速突破千萬。商品信息是電商業(yè)務流程前端的重要數據,是進行營銷活動、生成訂單的基礎。商品信息在前臺有多種展示頁面,大規(guī)模營銷活動期間運營人員需要進行大量操作設置,價格、庫存等也會更為頻繁地更新。目前庫存日更新量峰值超過1500萬SKU的變化;價格日更新數據量達500萬以上SKU,極限峰值超過1000萬,每秒可能超過1萬。數據同步及時性、一致性指標關乎用戶體驗和營銷活動執(zhí)行效率,如此大量的數據,在各業(yè)務系統之間高效穩(wěn)定傳輸,對系統架構提出了很大的挑戰(zhàn)。
當當網的商品數據有多個來源,自營實物商品來源于ERP系統,電子書來源于數字業(yè)務系統,商家商品來源于開放平臺,最終這些商品的數據都由主業(yè)務系統中的PIM、庫存系統、價格系統集中統一管理,再發(fā)布到搜索系統、推薦系統、前端頁面展示等系統。為了對商品信息中的關鍵數據同步時效進行監(jiān)控,當當網建立了啄木鳥監(jiān)控系統,覆蓋了近20個信息流路徑數百個節(jié)點,對超出同步時限的環(huán)節(jié)自動報警,以便及時處理,避免發(fā)生嚴重的延遲。
商品的關鍵數據包括商品基本信息、庫存和價格,庫存和價格都依賴于商品基本信息,對于不同類型的數據,根據應用場景區(qū)別對待。平臺化之后,每個商品都歸屬于一個商家,以商家ID為維度進行散列,將商品基本信息保存在數據庫中,支持水平擴展,可以滿足商品數據不斷增長的需要。對于歷史版本的商品信息,則遷移至歷史版本庫,作為訂單交易快照供用戶查詢。庫存數據在前端展示只關注是否有貨,并不需要將每一次庫存變化同步,在庫存變?yōu)?或從0變?yōu)檎麛禃r觸發(fā)狀態(tài)同步,交易下單時實時查詢當前庫存即可,此種變數量為狀態(tài)的方式極大地減少了同步數據量,提高了數據一致性。
價格屬于高度敏感的數據,對于手機專享價等類型,業(yè)務運營有設置生效時間、失效時間的要求,為保證前端按照時間動態(tài)展示,我們將生效時間段數據也發(fā)布到前端系統,由使用方判斷當前有效價格。圖2中給出了主要信息流。
即便已經對不同類型的商品信息數據流進行了差異化處理,仍然不能排除短時間內會發(fā)生大量數據造成系統同步阻塞,影響正常業(yè)務運營操作的及時發(fā)布。極端情況下,超出系統處理能力還可能導致系統崩潰。為解決此類問題,我們采用批量、異步、分流、限流等手段進行處理。
批量、批次操作
限制API調用頻次的同時,我們提供批量API供商家對商品信息進行更新,批量更新方式減少了各環(huán)節(jié)交互次數,提高了系統吞吐量,更好地貼合營銷活動中批量處理的需求。在系統內部,批量方式能夠有效降低系統資源開銷,并能對頻繁更新的商品數據進行合并處理,提高處理速度,使數據更新及時準確。
增加異步處理,減少同步處理
信息流同步經過多個系統,每個系統處理邏輯和吞吐能力不同,采用同步機制可能導致上游系統將下游系統拖垮,因此采用異步機制最為穩(wěn)妥。異步方式有兩點好處:一方面起到緩沖的作用,下游系統依據自身能力控制處理數據量,避免遭受超負荷的沖擊,保證系統穩(wěn)定運行;另一方面實現系統隔離解耦,一旦下游系統出現異常,上游系統仍然能正常處理數據,不至于引發(fā)連鎖反應。
分流
不同的信息對處理時效的要求也不同,庫存、價格、商品上下架狀態(tài)同步及時性要求很高,而商品基本信息,如名稱、副標題、詳情則相對較低。拆分不同的同步路徑,對及時性要求高的數據配置更多的系統資源,既保障了敏感數據的及時性,又避免了數據積壓相互干擾。同理,針對三種不同的數據來源渠道(ERP、數字業(yè)務系統、開放平臺),也可通過分流方式保證自營實物、電子書和商家商品信息的及時同步。
限流
多數的商品數據來源于商家,商家會通過一些第三方系統與當當網開放平臺對接,調用API進行數據同步。一些不合理的同步機制設置會頻繁發(fā)起大量的數據同步請求,而多數請求屬于無效數據,這類數據難以識別,會浪費大量的系統資源,干擾有效數據的處理。我們在開放平臺對每個商家調用API的頻次進行限制,根據商家商品數量合理分配,有效地抑制了無效數據的泛濫。
隨著多年雙11和集中促銷模式的考驗,電商系統的峰值設計理念和實踐已經慢慢趨于成熟,但仍然是所有電商類公司技術團隊的最重要任務之一。
當當網技術團隊經過多年的沉淀,積累了大量處理電商業(yè)務峰值的經驗。通過深入分析應用場景,對系統進行分級,SOA化完成系統解耦,并采用多種技術手段實現海量數據的高效處理發(fā)布,不斷提升系統吞吐能力,確保為用戶提供穩(wěn)定友好的購物服務體驗,充分體現技術力量在產業(yè)中的重要作用。
促銷系統重構
如今大規(guī)模促銷已經成為大大小小的電商平臺及入駐商家運營的常態(tài)。隨著業(yè)務的復雜化、運營的精細化,以及品類、平臺、渠道的不斷豐富,各種新的促銷形式也層出不窮,貫穿從商品展示、搜索、購買、支付等整個流程,電商對于精細化、精準化促銷運營的需求也越來越強烈。
一次促銷活動幾十萬商品,一天之內幾十個、上百個促銷活動已是家常便飯,至于入駐商家的常態(tài)促銷更是不勝枚舉。雙十一期間,電商平臺和商家更是會使出渾身解數,火力全開,無品不促銷。
促銷規(guī)則支持分時段設置,多個活動能夠疊加,促銷系統中的數據量甚至會超過商品信息系統,而且促銷內容會根據執(zhí)行效果快速調整,這些都對促銷系統提出了更高的要求,促銷系統越強大,促銷活動才能玩得越瘋狂。
我們在重構前面臨的狀況,是促銷模型比較陳舊、擴展性差,促銷系統成熟度低、與其他系統耦合嚴重,新增一個促銷類型可能牽動從單品展示、搜索、推薦、購物車、交易、訂單、退換貨、庫存、價格、促銷自身等一系列產品線的變更。因此,促銷系統的重構勢在必行,數據模型與運營的貼合度決定的擴展性、靈活性,系統解耦和更強大的數據處理能力,是核心改進點。
最基本的促銷模型很簡單,如下圖:
在當當,有一些類促銷”業(yè)務,從廣義上可以歸入促銷范疇,但業(yè)務與數據均不屬于促銷系統,在設計中,我們考慮將這類業(yè)務逐漸回收;另外,促銷系統能不能承擔一些營銷的功能?帶著這兩點考慮,在促銷基礎上進一步抽象出活動模型。
什么是活動?我們認為任何一個有時間范圍的事件/動作均可稱為活動,活動則抽象為三要素組成:基礎信息、維度(條件)、工具(動作)
例如,在11月1日10:00-12:00在第一會議室開雙十一準備會,討論雙十一各系統需要準備的事項,需要各系統負責人參加;那么這個活動的基礎信息包括時間(11月1日10:00-12:00)、主題(雙十一準備會),維度包括地點(第一會議室)、與會人員(各系統負責人),工具(動作)包括議題以及討論本身。
那么推而廣之,理論上,只要有相應的工具對接,可以用這個極簡的活動模型,去管理任何一類活動,這樣模型就變?yōu)榱藘蓪樱?/p>
實際業(yè)務中我們遇到過的一些關于促銷計算單元的頭疼問題。買了一堆商品,到底哪幾個應該作為一組計算條件和優(yōu)惠,在促銷疊加的場景這一點顯得更為復雜。所以我們引入作用域來定義這個計算單元的范圍。例如常規(guī)的限時搶促銷,每個SKU有自己的價格,那么SKU就是這個促銷的計算單元,也就是促銷的作用域;例如第二件5折,可能會按SPU來做,你買一個紅的一個藍的,還是能享受促銷,那么SPU成為了這個促銷的計算單元;諸如此類,現有及未來可擴展的還有店鋪、品類、品牌等等。簡言之,這個作用域成為促銷計算引擎進行計算單元分組的依據。于是模型又變成了這樣:
舉個例子,我們要在11月11日11:00-12:00針對IT技術類圖書進行滿200元減100元促銷,購買過此類圖書的客戶每本書每人限購一冊。那么這個活動的基礎信息包括時間(11月11日11:00-12:00)、主題(程序猿光棍節(jié)福利);維度包括商品品類(IT技術)、用戶范圍(購買過此類圖書的客戶);工具是滿額減促銷、以金額滿200元為條件、減100元為優(yōu)惠,此外還有限購策略為限購1本,作用域為參與活動的所有商品;
可能這里會引發(fā)困擾,基礎信息的時間為何不能算做時間維度?維度也定義了一些限制條件,那和促銷工具模型里的條件有什么區(qū)別?時間之所以不歸入維度,是基于前面對活動的定義,時間范圍是必須的,而維度是可選的;促銷模型中的條件只對于促銷工具有效和有意義,而維度則有更廣泛的普適性,例如平臺、渠道、地區(qū)、用戶、商品等,與工具是什么并無關系。
基礎模型定型之后,我們開始著手解耦方面的設計:
首先是系統交互解耦,將直讀DB和存儲冗余促銷數據的系統修改為調用服務及監(jiān)聽MQ;然后是邏輯回收,包括將促銷校驗與促銷計算提取為交易服務,將原先由購物車、交易系統自行處理的促銷邏輯回收;從業(yè)務上,將促銷工具的屬性進行提取,諸如類型枚舉、促銷標簽、限購策略、庫存策略等,以期外圍系統盡量少的關注促銷類型,通過促銷ID拿到所需信息直接使用;未來則關注于業(yè)務層面的梳理與整合,逐步回收適用于活動模型的其他類促銷”業(yè)務。
系統解耦后,促銷系統需要提供各系統所需要的服務,必須具備更強大的數據處理能力和更好的性能表現。應用架構實現上,從前端頁面到后端邏輯,盡量避免有邏輯與促銷類型直接綁定,全部以插件化方式與促銷模型對接,完全根據促銷類型的配置進行組裝。針對不同維度、條件、優(yōu)惠、促銷屬性,定制頁面模板及業(yè)務邏輯,使得新增一種促銷類型(在已有維度、條件、優(yōu)惠下)僅需配置即可完成。
促銷系統的查詢服務需要同時為多個系統提供數據,對TPS要求很高,同時促銷的時效性又要求很高的實時性。我們采用的方式是在數據庫前加Redis緩存,提高響應速度,同時監(jiān)聽MQ,根據事件清理相應的緩存數據。
這種設計方案也有一些可能的坑,例如Redis緩存雖然減輕了DB壓力,但對于計算密集型應用并未減輕應用服務器壓力,IO沒有節(jié)省還增加了序列化的開銷;事件驅動清理緩存在讀寫分離場景下,有可能比主從同步更快,造成緩存數據錯誤。這也是具體應用中需要注意的地方。
促銷系統重構上線后,使多渠道(終端)、多區(qū)域化營銷成為簡單易行的配置操作,顯著提高了當當運營能力,當當雙十一呈現出更多的想象空間。
交易系統重構
交易系統是客戶購物流程中最重要的環(huán)節(jié),主要任務是完成購物車中商品信息獲取、拆單、促銷計算、配貨計算、運費計算、非現金支付的使用以及生成訂單等操作,聚合各方面業(yè)務邏輯,計算非常復雜,而且響應速度影響購買轉化率,一旦出現故障,直接影響營業(yè)收入,可謂電商最為敏感的核心系統,決定對其進行重構需要極大的魄力。
當當原有交易系統采用.NET技術框架,運行多年,很好的支撐了購買流程,但是弊端逐漸顯露。首先是技術體系屬于微軟系,每年要花費大量成本購買服務;其次是隨著業(yè)務需求的不斷疊加,其結構及可維護性逐年下降,尤其是眾多小版本結算的存在,使得功能擴展異常艱難。
基于以上因素,交易系統團隊在2014年底啟動重構項目,2015年10月底新老版本完成切換。此次重構耗費約1500人天,重構代碼17萬行,全部切換至Java開源技術架構,為公司節(jié)約大量成本,并進行了架構優(yōu)化,整體性能平均提升25%。
交易系統業(yè)務主流程圖如下:
交易系統重構引入了許多業(yè)界成熟的技術實現方案,主要有以下幾點:
1. 集中化配置
集中化配置方式,一點配置,所有實例可見,更易于管理,而且配置修改后,通過熱加載方式,立刻生效,快速便捷。而原有交易系統修改配置后,必須重啟系統才能生效。
2. 頁面緩存技術
用戶請求一次交易結算頁面,會調用各種后端服務,而由于邏輯的復雜性,每次服務調用都會調用訂單計算大流程,導致頁面刷新緩慢。新交易系統將大流程計算結果進行緩存,在一次頁面請求范圍內,后續(xù)調用直接用緩存結果,極大提高了頁面的刷新速度。
3. 小版本合并
由于歷史原因,交易系統存在很多版本的結算邏輯。最常用的是統一結算,還有一些特殊類型的結算,如秒殺、一鍵下單、補發(fā)貨等等,邏輯與統一結算稍有不同,統稱為小版本結算。因小版本結算與統一結算大部分邏輯相同,因此新交易系統將二者合到了一起,共享基礎邏輯,而不同的邏輯則單獨處理,極大提高了可維護性。
4. 灰度發(fā)布、無縫切換
借助了Nginx在運行狀態(tài)下可以reload配置,而基本不影響對外提供服務的能力。每個Nginx負載兩臺應用服務器,灰度發(fā)布時,將Nginx配置更改為只負載一臺應用服務器,即可對另一臺進行部署。用戶請求不會導向正在部署中的服務器,從而不影響用戶下單。
5. 并行比對
交易系統重構后,盡管進行了大量的測試,仍不能放心部署上線。因為交易系統的計算都和金錢有關,必須慎之又慎,我們提出了線上并行比對方案,根據老交易系統比對新交易,保證其邏輯正確。原理如下:
1) 用戶請求到達老交易系統
2) 根據條件將部分請求數據復制,發(fā)送至調用mock服務的新交易系統
3) 新老交易同時計算,結果存入各自的數據庫,但只有老交易結果對用戶公開
4) 對新老計算結果進行比對
這樣,既實現了比對目的,又不會影響線上環(huán)境。
6. 分流
比對之后,新交易系統也不能立即全面上線,那樣可能有巨大風險。我們開發(fā)了分流功能,按照用戶id來分流,正式分流前,先使用測試白名單中的用戶進行預驗證。預驗證通過后,再按比例由低至高逐步切換。
7. Web服務器按需伸縮
基于前面所講的灰度發(fā)布技術,新交易系統很容易做到按需伸縮。正常情況下,每個Nginx負載兩臺應用服務器。雙十一需要擴容時,將待擴服務器ip地址加入Nginx配置,重新reload,該Nginx就可負載更多臺應用服務器了。
交易系統上線后為備戰(zhàn)雙十一,確保萬無一失,利用老交易系統還未下線的條件進行了線上壓測。為達到最準確的測試效果,且不影響正常系統運行,進行了以下的準備:
1. 測試環(huán)境、數據與生產環(huán)境一致
在準備測試環(huán)境方面,為了保證測試結果更接近真實結果,本次測試使用線上環(huán)境,通過大量測試賬號對線上的真實促銷商品進行測試,這樣也對新交易系統所依賴的各系統服務做了檢驗。
2. 線上業(yè)務運行保障
測試階段線上的請求切到老交易系統,壓測請求發(fā)送到新交易系統,使測試和生產業(yè)務進行分離,保證了各自服務器資源的獨立性。在應用服務器層面使測試過程不會影響到線上正常交易。
3. 攔截訂單回收庫存
由于使用線上環(huán)境測試,需要對測試訂單進行攔截,避免進入生產流程,并回收占用的庫存,使商品不會耗盡庫存,采用的方法是在自動審單系統中將測試賬戶加入黑名單,測試訂單提交后會被攔截,然后取消訂單釋放庫存。為防止測試過程占用了商品的全部庫存而影響線上銷售,測試商品池基數很大,并且過濾掉了庫存數量較少的商品,在執(zhí)行測試過程中控制每個商品的使用次數,保證可銷售庫存占用在安全范圍內。
4. 惡意用戶策略控制
因為在交易下單過程中包含惡意用戶判定的策略,會對用戶進行隔離,禁止連續(xù)大量下單,線上壓測時根據實際情況短時間內調整了安全級別,保證訂單成功率。
經過多輪線上壓測,新交易系統的高可用性得到驗證,得到了實際性能指標,并根據雙十一流量估算進行了擴容部署,將以嶄新的面貌為廣大客戶提供穩(wěn)定可靠便捷的網購服務。