構架穩定與可擴充套件的優惠券系統

2021-08-15 18:12:12 字數 2386 閱讀 2083

我們這裡主要考慮這兩個方面的擴充套件:

業務擴充套件

變更或新增業務邏輯時, 盡量對已有的核心模組影響最小,保證系統整體的穩定性.

效能擴充套件

保證系統是可以水平擴充套件的, 從而具有應對更高的負載能力.

乙個系統的穩定性,除了需要由健壯的**來保證外, 架構上的拆分,也會有相當大的影響.

比如:我們將易變的模組(需求變化頻繁)和穩定的模組糅合在一起部署的話, 易變模組的變化造成整個系統頻繁的部署,就會對整個系統帶來極大的風險.

所以擴充套件性在系統設計之初就需要著重考慮.

拋開具體業務的架構都是耍流氓, 那我們先從功能和效能需求上對要做的優惠券系統有個整體上的認識, 來看看哪些需求是易變的,哪些需求是穩定的.

優惠券活動管理

運營人員根據**檔期和財務計畫, 制定優惠券活動的方案,包括:

發券方式: 使用者主動領取還是被動接收

發券內容: 發券的種類, 發券數量, 是否多種券組合發放.

**方式: 見下文

使用限制: 見下文

優惠券發券

從瞬時單次發券的使用者數量來看, 發券活動分為:

對單使用者發券:

使用者大促**領券,新使用者註冊領券,訂單完成後返券以及對投訴使用者補償券時會採用這種領券活動.

對多使用者發券:

**方式

從券的**方式來看, 優惠券種類一般有:

立減: 

優惠金額固定的優惠券, 比如滴滴的現金券.

折扣: 

優惠金額跟訂單金額成比例的優惠券, 比如滴滴的折扣券.

其他**

不同的優惠券**方式, 會對應不同的優惠金額計算邏輯.

使用限制

從使用者使用角度看, 優惠券還會有多種使用限制:

限地域比如只能在上海使用該優惠券

其他限制

限制邏輯保證了優惠券**花的錢,都用到了提公升對應維度的運營資料上.

需求總結:

穩定的需求:

根據功能與效能需求,我們對優惠券系統模組做以下劃分:

優惠券活動平台

提供運營人員管理優惠後台, 給使用者**領券的功能.其子模組屬於易變的模組, 所以用子系統單獨部署的方式對系統整體穩定性更高.子系統包括:

優惠券資料統計平台

通過讀取線上優惠券資料的備份,進行資料包表生成的平台, 提供運營資料分析是使用, 後續不再做介紹.

領券子系統都依賴於優惠券發券平台的單使用者發券介面,屬於優惠券上層業務子系統. 將上層業務子系統跟發券核心系統分離,可以在保證發券系統穩定性的前提下, 通過提供單使用者發券api, 來更靈活的實現多種發券活動業務,比如我們可以輕鬆的構建乙個領券子系統: 兌換碼, 來實現使用者線下掃碼兌換優惠券的功能.

使用券池預生成優惠券

如何保證優惠券不超發?

運營人員建立優惠券活動時, 會設定本次活動可發優惠券數量.對於使用者主動領券的活動,當該活動的優惠券被領完後,使用者無法再次領取改活動的優惠券. 要保證優惠券不超發,有兩種方案:

通過全域性計數器的方式,保證併發下發券的數量變更的原子性.

通過先預生成優惠券存放到佇列來實現.使用者領券時從佇列pop取出優惠券,再和使用者進行繫結完成發券操作.當佇列pop不到優惠券時,就代表優惠券發完了.

如何解決優惠券唯一碼的生成問題?

優惠券會有乙個根據指定規則生成的全域性唯一碼作為交換id, 在優惠券各個子系統中傳遞.比如:

xxyyzz-20171016-001234567

xxyyzz字首代表業務碼

中間20171016為時間

字尾001234567代表當前碼的生成數量

如果我們在使用者主動領券時才生成唯一碼, 會存在多節點,多執行緒併發的問題,導致序號重複生成.一般需要加鎖處理,會降低系統的效能.解決這個問題,我們可以使用預生成的方式,在單節點單執行緒中生成唯一碼,再存入redis佇列中提供後續pop使用,從而避免加鎖帶來的效能下降.

結合以上兩個問題, 我們採用redis佇列作為存放預生成的優惠券的券池.可以極大的提公升系統的效能和穩定性.

如何應對大量的發券的請求

當優惠券活動開始時, 使用者的領券操作會修改資料.當使用者在結算頁使用優惠券時,查詢完優惠券後,會馬上使用優惠券. 所以整個流程優惠券資料的讀寫比操作接近1:1. 

常規的快取策略為:

這種快取策略雖然簡單,但實際應用中快取命中率非常低.因為大多數場景都是使用者領完券後立即使用.

另外使用者的發券操作會涉及到寫資料庫,大量的寫請求會造成資料庫的瓶頸. 要提高系統效能.就必須使用寫快取, 即:

整個過程如圖所示:

可擴充套件的 MySQL

可擴充套件性說明當需要增加資源以執行更多工作時系統能獲得划算的等同提公升的能力。可擴充套件性就是能過夠通過增加資源提公升容量 工作效率 的能力。表明了當需要增加資源以執行更過工作時系統能夠划算地提供等同提公升 equal bang for the buck 的能力。另一種說法是,可擴充套件性是當增加...

Lisp 可擴充套件的語言

不久前,如果你問lisp是用來做什麼的,許多人將回答 做人工智慧的 事實上,lisp和ai的關係僅僅是乙個歷史的巧合。john mcarthy發明了lisp,他也提出了了 人工智慧 的概念。他的學生和同事都用lisp來寫程式,然後lisp就被稱為一門ai語言。這條線在20世紀80年代ai 時期一直延...

可擴充套件的數列排序

include include 問題描述 從鍵盤輸入任意個整數,以0作為結束標誌。對這個整數序列進行排序並輸出排序後的結果。問題分析 題目要求從鍵盤輸入任意個整數,因此在資料的組織上就不能使用陣列了。因為陣列的記憶體分配是在編譯時完成的,即在編寫 時就指定陣列的大小。從鍵盤輸入任意個整數,就是說要分...