一、前言
隨著商城業務渠道不斷擴充套件,促銷玩法不斷增多,原商城v2.0架構已經無法滿足不斷增加的活動玩法,需要進行促銷系統的獨立建設,與商城解耦,提供純粹的商城營銷活動玩法支撐能力。
我們將分系列來介紹vivo商城促銷系統建設的過程中遇到的問題和解決方案,分享架構設計經驗。
二、系統框架
2.1 業務梳理
在介紹業務架構前我們先簡單瞭解下vivo商城促銷系統業務能力建設歷程,對現促銷能力進行梳理回顧。在商城v2.0中促銷功能存在以下問題:
1. 促銷模型不夠抽象,維護混亂,沒有獨立的活動庫存;
2. 混亂的活動共融互斥關係管理,缺乏統一的促銷計價能力。
商城核心交易鏈路中商詳頁、購物車、下單這三塊關於計價邏輯是分開獨立維護的,沒有統一,如下圖所示。顯然隨著促銷優惠的增加或者玩法的變動,商城側業務重複開發量會顯著加大。
(圖2-1. 促銷計價統一前)
3. 促銷效能無法滿足活動量級,往往會影響商城主站的效能。
因與商城系統耦合,無法提供針對性的效能優化,造成系統無法支撐越來越頻繁的大流量場景下大促活動。
基於這些痛點問題,我們一期完成促銷系統的獨立,與商城解耦,搭建出促銷系統核心能力:
優惠活動管理
對所有優惠活動抽象出統一的優惠模型和配置管理介面,提供活動編輯、修改、查詢及資料統計等功能。並獨立出統一的活動庫存管理,便於活動資源的統一把控。
促銷計價
基於高度靈活、抽象化的計價引擎能力,通過定義分層計價的促銷計價模型,制定統一的優惠疊加規則與計價流程,實現vivo商城促銷計價能力的建設。推動完成vivo商城所有核心鏈路接入促銷計價,實現全鏈路優惠價格計算的統一,如下圖:
(圖2-2. 促銷計價統一後)
隨著一期促銷系統核心能力的完成,極大的滿足了業務需要,各類優惠玩法隨之增多。但伴隨而來的就是各種運營痛點:
-
維護的促銷活動無法提前點檢,檢查活動效果是否符合預期;
-
隨著優惠玩法的增多,一個商品所能享受的優惠越來越多,配置也越來越複雜,極易配置錯誤造成線上事故;
為此我們開始促銷系統二期的能力建設,著重解決以上運營痛點:
-
提供時光穿越功能,實現使用者能夠“穿越”至未來某個時間點,從而實現促銷活動的提前點檢;
-
提供價格監控功能,結合「商城營銷價格能力矩陣」規劃的能力,通過事前/事中/事後多維度監控措施,來“降低出錯概率,出錯能及時止損”。
2.2 促銷與優惠券
促銷的主要目的就是向使用者傳遞商品的各種優惠資訊,提供優惠利益,吸引使用者購買,從而起到促活拉新、提高銷量的目的。從這種角度來看,優惠券也屬於促銷的一部分。
但因一些原因vivo商城促銷系統獨立過程中,並沒有與促銷系統放一塊:
-
首先,優惠券系統在商城v2.0時就已獨立,已經對接很多上游業務,已經是成熟的中臺系統;
-
再者,就是優惠券也有相較與其它促銷優惠的業務特殊性,如有發券、領券能力。
在考慮設計改造成本就未將優惠券包括在促銷系統能力範疇,但優惠券畢竟也是商品價格優惠的一部分,因此促銷計價需要依賴優惠券系統提供券優惠的能力。
2.3 業務架構&流程
至此我們也就梳理出整個促銷系統的大概能力矩陣,整體架構設計如下:
(圖2-3. 促銷系統架構)
而隨著促銷系統獨立,整個商城購物流程與促銷系統的關係如下:
(圖2-4. 最新商城購物流程)
三、技術挑戰
作為中颱能力系統,促銷系統面臨的技術挑戰包括以下幾方面:
-
面對複雜多變的促銷玩法、優惠疊加規則,如何讓系統具備可擴充套件性,滿足日益多變的優惠需求,提升開發與運營效率。
-
面對新品釋出、雙11大為客戶等大流量場景,如何滿足高併發場景下的高效能要求。
-
面對來自上游業務方的不可信呼叫,以及下游依賴方的不可靠服務等複雜系統環境,如何提升系統整體的穩定性,保障系統的高可用。
我們結合自身業務特點,梳理出一些技術解決方案。
3.1 可擴充套件性
擴充套件性提升主要體現在兩塊:
-
優惠模型的定義,對所有優惠活動抽象出統一的優惠模型和配置管理介面;
-
促銷計價引擎的建立,計價模型的統一。
相關的詳細設計內容,會有後續文章進行說明。
3.2 高併發/高效能
快取
快取幾乎就是解決效能問題的“銀彈”,在促銷系統中也大量使用快取進行效能提升,包括使用redis快取與本地快取。而使用快取就需要關注資料一致性問題,redis快取還好解決,但本地快取不就好處理了。因此本地快取的使用要看業務場景,儘量是資料不經常變更且業務上能接受一定不一致的場景。
批量化
促銷系統的業務場景屬於典型的讀多寫少場景,而讀的過程中對效能影響最大的就是IO操作,包括db、redis以及第三方遠端呼叫。而對這些IO操作進行批量化改造,以空間換時間,減少IO互動次數也是效能優化的一大方案。
精簡化/非同步化
簡化功能實現,將非核心任務進行非同步化改造。如活動編輯後的快取處理、資源預佔後的訊息同步、拼團狀態流轉的訊息通知等等。
冷熱分離
對於讀多寫少場景對效能影響最大的除了IO操作,還有就是資料量,在促銷系統中也存在一些使用者態資料,如優惠資源預佔記錄、使用者拼團資訊等。這些資料都具備時間屬性,存在熱尾效應,大部分情況下需要的都是最近的資料。針對這類場景對資料進行冷熱分離是最佳選擇。
3.3 系統穩定性
限流降級
基於公司的限流元件,對非核心的服務功能進行流量限制與服務降級,高併發場景下全力保障整體系統的核心服務
冪等性
所有介面均具備冪等性,避免業務方的網路超時重試造成的系統異常
熔斷
使用Hystrix元件對外部系統的呼叫新增熔斷保護,防止外部系統的故障造成整個促銷系統的服務崩潰
監控和告警
通過配置日誌平臺的錯誤日誌報警、呼叫鏈的服務分析告警,再加上公司各中介軟體和基礎元件的監控告警功能,讓我們能夠第一時間發現系統異常
四、踩過的坑
4.1 Redis SCAN命令使用
在Redis快取資料清除的處理過程中,存在部分快取key是通過模糊匹配的方式進行查詢並清除操作,底層依賴Redis SCAN命令。
SCAN命令是一個基於遊標的迭代器,每次被呼叫之後都會向使用者返回一個新的遊標, 使用者在下次迭代時需要使用這個新遊標作為 SCAN 命令的遊標引數, 以此來延續之前的迭代過程。
對於使用KEYS命令,SCAN命令並不是一次性返回所有匹配結果,減少命令操作對Redis系統的阻塞風險。但並不是說SCAN命令就可以隨便用,其實在大資料量場景下SCAN存在與KEYS命令一樣的風險問題,極易造成Redis負載升高,響應變慢,進而影響整個系統的穩定性。
(圖4-1 Redis負載升高)
(圖4-2 Redis響應出現尖刺)
而解決方案就是:
-
優化Redis key設計,減少不必要的快取key;
-
移除SCAN命令使用,通過精確匹配查詢進行清除操作。
4.2 熱點key問題
在促銷系統中普遍使用redis快取進行效能提升,快取資料很多都是SKU商品維度。在新品釋出、特定型別手機大促等業務場景下極容易產生熱點Key問題。
熱點Key具有聚集效應,會導致Redis叢集內節點負載出現不均衡,進而造成整個系統不穩定。該問題是普通的機器擴容無法解決的。如下圖某次線上摸排壓測時redis負載情況:
常用的解決方案有兩種:
-
雜湊方案:對Redis Key進行雜湊,平均分散到RedisCluster Nodes中,解決熱點Key的聚集效應。
-
多級快取方案:對熱點Key增加使用本地快取,最大限度加速訪問效能,降低Redis節點負載。
我們是採用多級快取方案,參照優秀的開源熱點快取框架,定製化擴充套件出一整套熱點解決方案,支援熱點探測 、本地快取 、叢集廣播以及熱點預熱功能,做到準實時熱點探測並將熱點Key通知例項叢集進行本地快取,極大限度避免大量重複呼叫衝擊分散式快取,提升系統執行效率。
五、總結
本篇屬於vivo商城促銷系統概覽介紹篇,簡單回顧了vivo商城促銷系統業務能力建設歷程及系統架構,並分享遇到的技術問題與解決方案。後續我們會對促銷系統的核心功能模組(優惠活動管理、促銷計價、價格監控和時光穿越)的設計實踐進行逐個分享,敬請期待。
作者:vivo網際網路官方商城開發團