一次簡單的微信秒殺活動

基本任務

中秋節的前一天,SAE突然接到一個電話,有這麼一個客戶,他們專門給銀行、基金公司提供營銷服務,這回他們服務的是一個“金主”,準備做一個在中秋節當天通過微信發送現金紅包的活動,活動本身就是一個HTML5頁面,裏面的邏輯不難,也就不到1000行代碼,大體是:

if ( 該用戶沒有參與過活動 & 餘額有錢) {
    跳轉到遊戲頁面
    begin game
    生成中獎信息
    扣款
    調用微信紅包API
    end game
}
else {
    提示“已經參與過了”,並顯示中獎信息
}

那麼問題來了

就這麼一個簡單的業務,卻困擾了這個客戶長達兩年,連續兩年的中秋抽獎都沒有成功過,每次都以宕機=》刷不出頁面結束,作爲營銷公司,他們也受到了他們的客戶的質疑。那麼前兩年的抽獎活動怎麼做的呢?

第一年:用自己的服務器,12核/16G內存一臺,裏面跑着LAMP(Apache+MySQL+PHP),結果CPU跑滿,不得不停重啓

第二年:用了某雲的雲服務器,16核心/32G內存,IO優化實例一個,裏面跑着LAMP(同上),結果負載巨高,響應巨慢

很不幸,兩次活動都不成功,所以客戶找到了SAE。。。

分析問題

得到需求後,因爲離最終上線只有一天,SAE立即派出技術團隊到了位於北京西直門的這家上市營銷公司瞭解情況,經過溝通,我們來分析一下這個案例:

  • 1,此次活動的領域基本集中在朋友圈傳播,目的是增加粉絲,並不是轉發量,所以沒有動用大號轉發,加上抽的是實際現金(他們的客戶要求必須現金不玩假抽獎劵,果然金主啊^_^),很快會抽完,持續時間不長,所以總體量不大

  • 2,錢是通過微信接口預充進去的,最麻煩的支付扣款是調用微信接口,用戶看到的就是一個標準的紅包頁面,所以免去了事務支付的重邏輯

  • 3,訪問的終端用戶是銀行的全國用戶,HTML5遊戲裏面含大量靜態元素,原程序沒有使用CDN做資源加速

  • 4,原有邏輯大量依賴MySQL數據庫,且表結構存在不合理,也沒有適當的使用cache,更沒有使用讀寫分離,導致瞬間數據庫壓力過大

  • 5,業務上沒有峯值預案,也沒有降級邏輯

  • 6,只使用雲主機,不具備自動擴容能力,客戶也沒有scale out的實施經驗

解決

考慮到這些原因,同時考慮到離實際活動發佈還有不到12個小時,不可能對原有邏輯進行大改,所以只能放棄5(降級邏輯)

那麼,我們所做的工作有:

1,將業務放到SAE上,因爲SAE實現了基於HTTP Request的container,可以隨着請求的增多而自動擴容,整個過程用戶無感知也無需關心,換句話說從1000PV到10億PV用戶無需做任何變動即可完成,這樣首先解決Apache+PHP的運行負載問題

2,單單完成1是不夠的,因爲涉及到數據庫還是單點,所以我們協助用戶修改數據操作爲讀寫分離,根據這個業務場景,用戶的錢可以有一些誤差,不是嚴格要求發放XX萬元整(因爲剩餘的錢微信會退回商家),於是,諸如餘額是否有錢的操作不必嚴格使用tranaction保證,可以直接從從庫判斷

3,增加cache層,首先設置HTTP過期header和啓用CDN,從多個層面增加cache效果,在SAE上啓用CDN非常簡單,參考http://www.sinacloud.com/doc/sae/php/cdn.html,只要將資源地址改成CDN域名即可;使用memcache服務作爲數據cache層,所有數據均從cache讀取,對於需要事務的數據,使用memcache::add操作間接實現,另外說一句,SAE上memcache不像目前的所謂的“微服務”,需要用戶自己創建,而是SAE官方自帶的“池化”服務,每個用戶自動可以使用多達4T的內存cache。

4,變數據庫批量併發寫爲有限併發異步寫,創建了一個TaskQueue,將所有的數據庫寫操作放入併發度爲16的Queue,通過該Queue異步update數據庫。同時,SAE爲企業用戶提供了最高50000 IOPS的DB實例。

5,因爲時間關係,未完成的邏輯有:變簡單寫操作從MySQL轉到KVDB(NoSQL數據庫);增加業務降級開關,緊急情況下操作HTML5客戶端隨機數,控制到達服務端的用戶數量

在完成這些修改後,應用戶的強烈要求,SAE還將這家營銷公司的賬號企業等級臨時從高級型調整成最高等級(合作伙伴級)一天,來準備應對中秋的秒殺活動。至此,我們已經堅信這次秒殺可以支持瞬間10萬併發,這個指標已經超過用戶設計的十倍,當然,客戶還是將信將疑,那麼結果呢?

結果

客戶的活動準時在2015年9月27日上午10點整開始:
這裏寫圖片描述

如上圖所述,中秋槍紅包活動發佈後,最高時達到了7萬次請求/秒,在紅包空了以後,請求迅速下降。同時,從用戶日誌看,沒有錯誤日誌產生,也沒有502、504等超時現象,根據客戶反饋,該次活動非常成功,他們的客戶的現金紅包大約在30秒內被搶光。之後,我們查閱了當時memcache集羣和MySQL集羣的狀態,所有服務參數顯示正常,證明這次秒殺行爲從技術上完全滿足。

總結

其實,從互聯網的業務看,這次活動也不算太大,畢竟客戶追求的並不是轉發量而是粉絲數,另外他們的客戶的紅包金額也不是巨大,所以這次業務的峯值量離我們的預估還有一定距離,但從這次秒殺行爲還有一些經驗需要總結的:

1,不要迷信雲服務,IaaS幾乎不能幫用戶解決完全自動的擴容問題,SAE也只能幫用戶解決無狀態的服務擴容,但像強業務邏輯的數據擴容還是有賴於用戶自己解決,比如如果用戶還是把所有的庫、表操作放到一個單點執行,即使放到SAE上,也還是會出現瓶頸。

2,充分利用cache,cache不僅僅是利用redis或者memcache,而應該是從客戶端、到代理層、到Runtime層、到數據庫的各級cache,同時利用cache的過期時間,合理控制cache的實效性弊端

3,變一切同步操作爲異步操作,尤其是寫數據庫的重操作,可以使用諸如TaskQueue服務來將邏輯異步化,讓整個用戶體驗不存在阻塞邏輯

最後,還要在業務邏輯上實現可降級可控制,這點雖然因爲時間關係未能在實際代碼上有所體現,但是在實際大型業務確是最重要的。

當然,這裏講的秒殺還不包括支付系統的,從這點來說,這個案例要比淘寶、天貓等簡單成千上萬倍,我們也歡迎對秒殺技術有興趣的小夥伴一起參與討論,一起提高。

原文地址:
http://www.jianshu.com/p/e19457aed65d?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章