電商搶購秒殺系統的設計及應用場景分析

格色情調1984發表於2016-10-08

                    請尊重個人勞動成果,轉載註明出處,謝謝!https://my.oschina.net/yonghan/blog/473790

概述

       所謂知已知彼,百戰不殆,在開始詳細介紹實戰中的搶購秒殺系統時,我們瞭解一些搶購秒殺系統系統面臨的尷尬與難點。另外需要說明一點,下面的內容都是在工作中慢慢總結得來,我們團隊也是慢慢摸著石頭過河,甚至最初的的架構設計並非是搶購秒殺系統。

評估系統處理能力

         理論基礎:LNMP的併發考慮與資源分配

       雖然有基礎去評估我們應用系統的處理能力,但是電商購買的業務流程挺複雜,從登入,商品詳情,購物車,填寫收貨地址,選擇支付方式,建立訂單,完成支付,以及隱含的定時服務,限購策略,庫存操作,排隊機制等一系列的業務邏輯,每個請求的處理時間都不一樣。那麼根據木桶原理,一隻水桶能將多少水取決於它最短的那塊木板,分析整個業務流程中最耗系統資源的請求,以此為標準為評估系統處理能力。

場景

       我們是一個做特賣秒殺搶購的電商平臺,我們的商品異常火爆且價格低廉價,這就給網路黃牛帶了巨大的利潤空間。為了讓真正的平臺使用者受益,改善使用者體驗,提高使用者留存率,我們在產品業務、技術實現上嘗試了很多方法,都沒有完美解決黃牛刷單的問題。

目標

       話說回來,讓黃牛買不到商品,不是單純技術能夠解決的問題。我們要解決的問題是,由於黃牛大規模的請求登入介面、商品詳情頁介面、下單介面導致在搶購開始前後的流量峰值直接翻了上千倍,最終導致服務不可用。在不增加硬體成本的情況下,解決短時間內大流量導致的服務不可用。

產品特徵

       以H5應用為主站主要流量入口,支援QQ、微信、微博等平臺使用者登入購買,嵌入到某流行的資訊客戶端。另外,也有單獨的特賣安卓客戶端、IOS客戶端。

刷單特徵

  賬號

       黃牛每次搶購活動註冊新使用者,由於平臺流量大部分來自某新聞客戶端,客戶端的賬號體系為弱賬號體系,可以繫結手機號也可以解除繫結,每次重新繫結都會生成新的使用者ID。同時平臺也允許非手機號註冊的使用者下單購買商品,使用者的收貨地址的聯絡電話可以和註冊賬號的手機號不一致。另一方面,黃牛在淘寶花錢可以購買大量的平臺新註冊賬號,真是術業有專攻。

  IP庫

在雲服務盛行的網際網路時代,黃牛以很低的成本可以獲得上萬的IP及主機,IP分佈在全球各地。

  頻次

黃牛刷單時訪問頻次不是很高,在擁有大量賬號、IP的情況下,訪問頻次低也可以搶購到商品。

  破解原生App

黃牛的技術很強,將混淆加密後的原生客戶端破解,將其中的加密演算法重寫,升級搶購軟體。

  CC攻擊

       黃牛為了避免預約使用者將商品提前搶光,聯合全國的黃牛同時高頻次的訪問網站資料介面,導致網站由於大流量下不堪重負,從而服務不可用,在預約提前購買時間過去(黃牛的目的是堵住預約使用者購買),全網使用者均可購買時,慢慢的減少流量,任意下單購買商品。

產品與技術措施

產品業務角度

預約購買

全網使用者提前預約,具有預約購買資格的使用者可享受提前入場下單購買。預約需要繫結手機號,輸入驗證碼(簡訊和圖片)。

搶購排隊

為了應對短時間內的大流量請求,採用排隊購買機制,使用者提交購買請求後立即返回,等待後端處理結果。

引流

在預知大流量不可控時,將H5主站流量引到原生的客戶端APP內進行搶購。

技術防守角度

驗證碼

       在搶購開始時,下單購買某商品必須輸入驗證碼。在一定時間內,對於訪問庫存為0的使用者請求,超過一定頻次後要求輸入驗證碼。打碼雲服務很多,理論上字元驗證碼均可識別,甚至人工打碼,但是提高了刷單成本。

IP禁止策略

       通過nginx的lua擴充套件,在單位時間內同使用者相同IP請求同一URL進行計數,在nginx層面進行限流。IP級別下,控制不好,誤殺太多或者起不了作用。

fastcgi請求計數

      設定PHP可併發處理請求的最大值,nginx交給PHP的請求都進行計數+1,fastcgi完成後進行-1。由於nginx+php-fpm高併發情況下,做到原子的計數很難。

佇列

      引入訊息佇列和長連線服務,使用者請求排隊購買,後端進行流量控制,發放資格號,通過長連線通知使用者的處理結果。

靜態化

      將商品詳情頁靜態化,靜態頁面的請求直接由CDN返回。

建立黃牛賬號庫

       經過幾次大規模的搶購後,黃牛賬號有限,將積累的黃牛賬號入庫,在下次搶購時,載入記憶體,降低購買優先順序或者直接拒絕請求。

增加伺服器

         從原有的幾臺伺服器,擴容到幾十臺伺服器,每個服務都部署負載均衡、高可用。如多級快取、nginx與php-fpm分離、長連線伺服器叢集等等。

可伸縮架構

       搶購開始前準備上百倍的伺服器數量,所有的服務均可橫向擴充套件,提高處理能力。

上面交待了挺多的做搶購平臺的一些場景、特徵、措施,涉及的產品和技術的面廣,我認為最重要的是解決網站服務不可用或者當機的問題,我們在nginx層面做了很多努力與嘗試,另外nginx在防CC攻擊方面有一些成熟的方案,下面詳述,下一階段研究nginx原始碼。

nginx請求限制模組

ngx_http_limit_conn_module

限制連線數模組

通常用來限制同一IP地址的可併發連線數

指令說明:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

需要注意的是$binary_remote_addr而不是$remote_addr,$remote_addr的長度為7到15個位元組,它的會話資訊的長度為32或64 bytes,$binary_remote_addr的長度為4位元組,會話資訊的長度為32位元組,這樣設定1M的一個zone時,用$binary_remote_addr方式,該zone將會存放32000個會話。

ngx_http_limit_req_module

限制請求數模組

通常用來限制同一IP地址單位時間可完成的請求數,限制的方法是採用漏桶演算法(Leaky Bucket),每秒處理固定請求數量,推遲過多請求,超過桶的閥值,請求直接終止返回503。

指令說明:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

基於nginx的Tengine分支ngx_http_limit_req_module

nginx類似,不過支援多個變數,並且支援多個limit_req_zone及forbid_action的設定。

指令說明:http://tengine.taobao.org/document_cn/http_limit_req_cn.html

基於nginx的Senginx分支的ngx_http_limit_req_module

指令說明:http://www.senginx.org/cn/index.php/%E5%9F%BA%E4%BA%8E%E6%9D%A1%E4%BB%B6%E7%9A%84%E9%99%90%E9%80%9F%E5%8A%9F%E8%83%BD

稱之為基於條件的限速功能,在Tenginer的limit_req模組基礎上,增加condition引數,在條件為真時執行限制動作。

基於nginx的Senginx分支的ngx_http_ip_behavior

指令說明:http://www.senginx.org/cn/index.php/%E8%AE%BF%E9%97%AE%E8%A1%8C%E4%B8%BA%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9D%97

稱之為行為識別模組,訪問行為識別模組的作用是對使用者訪問網站的行為進行監控

基於nginx的Senginx分支的ngx_http_robot_mitigation

指令說明:http://www.senginx.org/cn/index.php/Robot_Mitigation%E6%A8%A1%E5%9D%97

稱之為HTTP機器人緩解,Robot Mitigation模組採用了一種基於“挑戰”的驗證方法,即向客戶端傳送特定的、瀏覽器能解析的應答,如果客戶端是真實的瀏覽器,則會重新觸發請求, 並帶有一個特定的Cookie值,Robot Mitigation模組會依據此Cookie的資訊來決定是否放行此請求。

最後

基於上述的場景、特徵、nginx限制模組的調研和分析,我們完全可以通過靈活的nginx配置來解決CC攻擊威脅。使用了Senginx,靈活運用基於條件的限速功能,行為識別模組,機器人緩解模組。今天先聊到這兒,後續會總結出本文提到的很多技術細節。

相關文章