電商行業近年來發展勢頭迅猛,諸多巨頭成功上市,業務模式不斷升級,促銷手段花樣百出。雙十一成爲各路電商運營能力的年度大考,同時也是對電商技術平臺能力的極限測試,每一年進行了重大改版升級的系統只有通過雙十一的槍林彈雨才能浴火重生。前端
在噹噹,2015年的雙11,面臨考驗的是促銷系統和交易系統,二者都是電商體系的核心組成部分。這次雙11專題,InfoQ特別邀請EGO會員、噹噹架構部總監史海峯先生,爲你們講述噹噹雙11背後的技術故事。數據庫
另,ArchSummit全球架構師峯會北京站將於2015年12月18日~19日在北京國際會議中心召開,大會設置了《揭祕雙十一背後的技術較量》專題來深刻解讀雙十一背後的技術故事,歡迎關注。後端
相關廠商內容緩存
相關贊助商安全
ArchSummit深圳2017,7月7-8日,深圳·華僑城洲際酒店,精彩內容搶先看服務器
現在大規模促銷已經成爲大大小小的電商平臺及入駐商家運營的常態。隨着業務的複雜化、運營的精細化,以及品類、平臺、渠道的不斷豐富,各類新的促銷形式也層出不窮,貫穿從商品展現、搜索、購買、支付等整個流程,電商對於精細化、精準化促銷運營的需求也愈來愈強烈。微信
一次促銷活動幾十萬商品,一天以內幾十個、上百個促銷活動已經是屢見不鮮,至於入駐商家的常態促銷更是不勝枚舉。雙十一期間,電商平臺和商家更是會使出渾身解數,火力全開,無品不促銷。架構
促銷規則支持分時段設置,多個活動可以疊加,促銷系統中的數據量甚至會超過商品信息系統,並且促銷內容會根據執行效果快速調整,這些都對促銷系統提出了更高的要求,促銷系統越強大,促銷活動才能玩得越瘋狂。框架
咱們在重構前面臨的情況,是促銷模型比較陳舊、擴展性差,促銷系統成熟度低、與其餘系統耦合嚴重,新增一個促銷類型可能牽動從單品展現、搜索、推薦、購物車、交易、訂單、退換貨、庫存、價格、促銷自身等一系列產品線的變動。所以,促銷系統的重構勢在必行,數據模型與運營的貼合度決定的擴展性、靈活性,系統解耦和更強大的數據處理能力,是核心改進點。less
最基本的促銷模型很簡單,以下圖:
在噹噹,有一些「類促銷」業務,從廣義上能夠納入促銷範疇,但業務與數據均不屬於促銷系統,在設計中,咱們考慮將這類業務逐漸回收;另外,促銷系統能不能承擔一些營銷的功能?帶着這兩點考慮,在促銷基礎上進一步抽象出活動模型。
什麼是活動?咱們認爲任何一個有時間範圍的事件/動做都可稱爲活動,活動則抽象爲三要素組成:基礎信息、維度(條件)、工具(動做)
例如,在11月1日10:00-12:00在第一會議室開雙十一準備會,討論雙十一各系統須要準備的事項,須要各系統負責人蔘加;那麼這個活動的基礎信息包括時間(11月1日10:00-12:00)、主題(雙十一準備會),維度包括地點(第一會議室)、與會人員(各系統負責人),工具(動做)包括議題以及討論自己。
那麼推而廣之,理論上,只要有相應的工具對接,能夠用這個極簡的活動模型,去管理任何一類活動,這樣模型就變爲了兩層:
實際業務中咱們遇到過的一些關於促銷計算單元的頭疼問題。買了一堆商品,到底哪幾個應該做爲一組計算條件和優惠,在促銷疊加的場景這一點顯得更爲複雜。因此咱們引入做用域來定義這個計算單元的範圍。例如常規的限時搶促銷,每一個SKU有本身的價格,那麼SKU就是這個促銷的計算單元,也就是促銷的做用域;例如第二件5折,可能會按SPU來作,你買一個紅的一個藍的,仍是能享受促銷,那麼SPU成爲了這個促銷的計算單元;諸如此類,現有及將來可擴展的還有店鋪、品類、品牌等等。簡言之,這個做用域成爲促銷計算引擎進行計算單元分組的依據。因而模型又變成了這樣:
舉個例子,咱們要在11月11日11:00-12:00針對IT技術類圖書進行滿200元減100元促銷,購買過此類圖書的客戶每本書每人限購一冊。那麼這個活動的基礎信息包括時間(11月11日11:00-12:00)、主題(程序猿光棍節福利);維度包括商品品類(IT技術)、用戶範圍(購買過此類圖書的客戶);工具是滿額減促銷、以金額滿200元爲條件、減100元爲優惠,此外還有限購策略爲限購1本,做用域爲參與活動的全部商品;
可能這裏會引起困擾,基礎信息的時間爲什麼不能算作時間維度?維度也定義了一些限制條件,那和促銷工具模型裏的條件有什麼區別?時間之因此不納入維度,是基於前面對活動的定義,時間範圍是必須的,而維度是可選的;促銷模型中的條件只對於促銷工具備效和有意義,而維度則有更普遍的普適性,例如平臺、渠道、地區、用戶、商品等,與工具是什麼並沒有關係。
基礎模型定型以後,咱們開始着手解耦方面的設計:
首先是系統交互解耦,將直讀DB和存儲冗餘促銷數據的系統修改成調用服務及監聽MQ;而後是邏輯回收,包括將促銷校驗與促銷計算提取爲交易服務,將原先由購物車、交易系統自行處理的促銷邏輯回收;從業務上,將促銷工具的屬性進行提取,諸如類型枚舉、促銷標籤、限購策略、庫存策略等,以期外圍系統儘可能少的關注促銷類型,經過促銷ID拿到所需信息直接使用;將來則關注於業務層面的梳理與整合,逐步回收適用於活動模型的其餘「類促銷」業務。
系統解耦後,促銷系統須要提供各系統所須要的服務,必須具有更強大的數據處理能力和更好的性能表現。應用架構實現上,從前端頁面到後端邏輯,儘可能避免有邏輯與促銷類型直接綁定,所有以插件化方式與促銷模型對接,徹底根據促銷類型的配置進行組裝。針對不一樣維度、條件、優惠、促銷屬性,定製頁面模板及業務邏輯,使得新增一種促銷類型(在已有維度、條件、優惠下)僅需配置便可完成。
促銷系統的查詢服務須要同時爲多個系統提供數據,對TPS要求很高,同時促銷的時效性又要求很高的實時性。咱們採用的方式是在數據庫前加Redis緩存,提升響應速度,同時監聽MQ,根據事件清理相應的緩存數據。
這種設計方案也有一些可能的坑,例如Redis緩存雖然減輕了DB壓力,但對於計算密集型應用並未減輕應用服務器壓力,IO沒有節省還增長了序列化的開銷;事件驅動清理緩存在讀寫分離場景下,有可能比主從同步更快,形成緩存數據錯誤。這也是具體應用中須要注意的地方。
促銷系統重構上線後,使多渠道(終端)、多區域化營銷成爲簡單易行的配置操做,顯著提升了當當運營能力,噹噹雙十一呈現出更多的想象空間。
交易系統是客戶購物流程中最重要的環節,主要任務是完成購物車中商品信息獲取、拆單、促銷計算、配貨計算、運費計算、非現金支付的使用以及生成訂單等操做,聚合各方面業務邏輯,計算很是複雜,並且響應速度影響購買轉化率,一旦出現故障,直接影響營業收入,可謂電商最爲敏感的核心繫統,決定對其進行重構須要極大的魄力。
噹噹原有交易系統採用.NET技術框架,運行多年,很好的支撐了購買流程,可是弊端逐漸顯露。首先是技術體系屬於微軟系,每一年要花費大量成本購買服務;其次是隨着業務需求的不斷疊加,其結構及可維護性逐年降低,尤爲是衆多小版本結算的存在,使得功能擴展異常艱難。
基於以上因素,交易系統團隊在2014年末啓動重構項目,2015年10月底新老版本完成切換。這次重構耗費約1500人天,重構代碼17萬行,所有切換至Java開源技術架構,爲公司節約大量成本,並進行了架構優化,總體性能平均提高25%。
交易系統業務主流程圖以下:
交易系統重構引入了許多業界成熟的技術實現方案,主要有如下幾點:
集中化配置方式,一點配置,全部實例可見,更易於管理,並且配置修改後,經過熱加載方式,馬上生效,快速便捷。而原有交易系統修改配置後,必須重啓系統才能生效。
用戶請求一次交易結算頁面,會調用各類後端服務,而因爲邏輯的複雜性,每次服務調用都會調用訂單計算大流程,致使頁面刷新緩慢。新交易系統將大流程計算結果進行緩存,在一次頁面請求範圍內,後續調用直接用緩存結果,極大提升了頁面的刷新速度。
因爲歷史緣由,交易系統存在不少版本的結算邏輯。最經常使用的是統一結算,還有一些特殊類型的結算,如秒殺、一鍵下單、補發貨等等,邏輯與統一結算稍有不一樣,統稱爲小版本結算。因小版本結算與統一結算大部分邏輯相同,所以新交易系統將兩者合到了一塊兒,共享基礎邏輯,而不一樣的邏輯則單獨處理,極大提升了可維護性。
藉助了Nginx在運行狀態下能夠reload配置,而基本不影響對外提供服務的能力。每一個Nginx負載兩臺應用服務器,灰度發佈時,將Nginx配置更改成只負載一臺應用服務器,便可對另外一臺進行部署。用戶請求不會導向正在部署中的服務器,從而不影響用戶下單。
(點擊放大圖像)
交易系統重構後,儘管進行了大量的測試,仍不能放心部署上線。由於交易系統的計算都和金錢有關,必須慎之又慎,咱們提出了線上並行比對方案,根據老交易系統比對新交易,保證其邏輯正確。原理以下:
1) 用戶請求到達老交易系統
2) 根據條件將部分請求數據複製,發送至調用mock服務的新交易系統
3) 新老交易同時計算,結果存入各自的數據庫,但只有老交易結果對用戶公開
4) 對新老計算結果進行比對
這樣,既實現了比對目的,又不會影響線上環境。
比對以後,新交易系統也不能當即全面上線,那樣可能有巨大風險。咱們開發了分流功能,按照用戶id來分流,正式分流前,先使用測試白名單中的用戶進行預驗證。預驗證經過後,再按比例由低至高逐步切換。
基於前面所講的灰度發佈技術,新交易系統很容易作到按需伸縮。正常狀況下,每一個Nginx負載兩臺應用服務器。雙十一須要擴容時,將待擴服務器ip地址加入Nginx配置,從新reload,該Nginx就可負載更多臺應用服務器了。
交易系統上線後爲備戰雙十一,確保萬無一失,利用老交易系統還未下線的條件進行了線上壓測。爲達到最準確的測試效果,且不影響正常系統運行,進行了如下的準備:
1. 測試環境、數據與生產環境一致
在準備測試環境方面,爲了保證測試結果更接近真實結果,本次測試使用線上環境,經過大量測試帳號對線上的真實促銷商品進行測試,這樣也對新交易系統所依賴的各系統服務作了檢驗。
2. 線上業務運行保障
測試階段線上的請求切到老交易系統,壓測請求發送到新交易系統,使測試和生產業務進行分離,保證了各自服務器資源的獨立性。在應用服務器層面使測試過程不會影響到線上正常交易。
3. 攔截訂單回收庫存
因爲使用線上環境測試,須要對測試訂單進行攔截,避免進入生產流程,並回收佔用的庫存,使商品不會耗盡庫存,採用的方法是在自動審單系統中將測試帳戶加入黑名單,測試訂單提交後會被攔截,而後取消訂單釋放庫存。爲防止測試過程佔用了商品的所有庫存而影響線上銷售,測試商品池基數很大,而且過濾掉了庫存數量較少的商品,在執行測試過程當中控制每一個商品的使用次數,保證可銷售庫存佔用在安全範圍內。
4. 惡意用戶策略控制
由於在交易下單過程當中包含惡意用戶斷定的策略,會對用戶進行隔離,禁止連續大量下單,線上壓測時根據實際狀況短期內調整了安全級別,保證訂單成功率。
通過多輪線上壓測,新交易系統的高可用性獲得驗證,獲得了實際性能指標,並根據雙十一流量估算進行了擴容部署,將以嶄新的面貌爲廣大客戶提供穩定可靠便捷的網購服務。