搶紅包、秒殺等營銷手段現在越來越流行了,而這種活動卻帶給it攻城獅們巨大的挑戰。搶紅包系統從前端看起來都是很簡單的,但實際上對應的後端系統卻非常複雜,因為瞬時高并發所帶來的問題将整個系統架構的複雜度提升了幾個數量級。
筆者所在的駐雲科技就參與了春晚支付寶老廟黃金新春搶紅包活動系統的建設和護航工作。在這裡跟大家做個分享,一起探讨如何利用雲計算技術來在短時間内建構強大且具備靈活擴充性的架構。
一、 架構需求調研
搶紅包系統的邏輯一般都比較簡單,使用者在一個頁面上點選,加上簡單的互動,将請求發送至服務端,由服務端接受請求并根據業務需求處理後傳回紅包結果給用戶端。那麼在需求調研階段就必須了解清楚幾個資訊:
1. 并發峰值的估算
知道了并發峰值,才好來評估帶寬、負載均衡、伺服器數量等。那麼怎麼來預估峰值?一般根據活動預計參與的人數和參與時段可以來做簡單估算。例如預計會有 1000萬人參加,共1個小時,那麼平均每秒并發就是 2800左右,由于一般在活動開始時壓力會比較大,系統最大峰值一般是平均值的5-10倍左右。當然具體的要看活動形式來估算。在本次春晚活動預估的每秒并發為10萬左右。
2. 活動參與形式及互動形式
活動形式的設計會直接影響到系統的架構設計,例如是在用戶端完成一系列互動後發送一次請求至服務端,還是每次互動都要連接配接服務端。互動都在用戶端完成實作比較簡單,對服務端壓力也最小,但是互動形式比較固定。
在今年的春晚紅包活動中,由于并發壓力較大,同時業務需求不複雜,是以互動基本都放在用戶端來完成。
大緻流程如下:使用者點選支付寶咻一咻,會随機出現老廟紅包界面,然後點選打開紅包則由服務端随機傳回一個不同額度的優惠券,然後使用者通過優惠券id進行實體店或者網店的消費。效果圖如下:
3. 活動資料需求
大部分活動在進行中或者結束後都需要統計活動情況資訊,例如每個時段的使用者數、通路量、業務量等等。是以在系統設計時就需要考慮到整個系統的通路情況和使用者行為資料以何種形式和方式儲存下來。資料庫、日志、緩存等手段都是常用的,但是在在高并發情況下,日志對性能的影響也都非常大。以寫日志檔案為例,單機數千并發頻繁的磁盤io會導緻嚴重的響應問題,很多類似系統都發生過看起來并不起眼的日志檔案是性能瓶頸的罪魁禍首。
二、 架構設計
正确的架構是系統成功的基石,那麼我們就要從業務層面來分析下搶紅包活動的系統架構有哪些典型特點?
恐怖的峰值并發,并發/tps/qps一般都是在數萬甚至數十萬。(雙11天貓的交易大約在10萬筆/秒);
時效性非常強, 活動一般都在固定的時間或者事件觸發,錯過了就沒有了;
穩定性要求高,隻許成功不許失敗。正是由于活動的時效性很強,比如春晚直播的那一兩分鐘,如果系統出現哪怕10秒的故障對整個活動的效果就會大打折扣;
性能要求高,不能慢。高并發時往往帶來的就是對請求的響應時間變長,但是在促銷情況下過長的延時使用者是無法忍受的;
系統壓力未知性,通路量,使用者量,并發量的不可預測。在活動前一般都會做一定的預測,但是不确定性非常大,可能由于某一個特殊事件,系統通路量就會遠遠超于預期。是以健壯的架構必須能夠承擔超額的通路量,并且要做到足夠彈性,當業務壓力增長時可以随時擴容。
了解了這些典型特點,架構設計就要正式開始了。
1. 基礎設施架構選型
整個系統選用阿裡雲作為基礎架構。那麼為什麼用雲而不是傳統的硬體或者虛拟化it架構來實作呢?并不是因為現在雲計算流行而選雲,而是因為隻有雲計算才能勝任,為什麼?
資源彈性,計算資源、網絡資源需要多少随時就可以擷取和擴充。
快速傳遞能力,整個項目從開發到上線隻有20天時間,不用雲估計很難完成。
成本,由于整個活動隻持續春節期間15天左右的時間,較低的綜合成本是必須考慮的。
基于這些因素考慮,我們來分别分析下具體架構:
2. 應用架構設計
采用典型的三層架構,接入層—負載均衡slb,應用層—虛拟機ecs,資料層-資料庫rds。
接入層使用負載均衡slb的原因很簡單,因為整個系統的并發會很大,不是幾台機器可以完成的,是以必須用slb将整個負載分擔至 幾十台機器上,同時也有兩個好處: 1. 可用性大幅提升,單個機器或者某一個可用區(機房)故障不會影響系統 2. 計算的擴充性,通路量大隻需要在slb後增加機器即可。并發量大時接入層很容易成為瓶頸,但是使用slb的好處是它本身就是一個叢集,并且在負載轉發上做好了高可用和優化,是以我們隻需要簡單的配置slb的端口轉發規則即可,其他的基本不需要考慮。
應用層,使用python開發,pypy+tornado+nginx作為後端服務。由于後端邏輯簡單,同時為了追求開發速度而選擇python,而使用pypy比原生的cpython速度要提升10倍以上,tornado的非阻塞異步io處理方式也可以輕松應對高并發,nginx作為靜态頁面的處理也是非常合适的。
資料層,由于紅包涉及到後續消費時的驗證,是以每個紅包必須有唯一id。那麼生成id和存放資料如果用關系型資料庫在壓力大時很容易把資料庫撐爆,那就要考慮到用緩存來處理,是以最後選用ocs(memcached)作為資料層。而資料的持久化則通過異步處理方式寫入關系型資料庫rds(mysql)(還有一個選擇是redis,具體就不再累述)。
3.雪崩效應和限流解決辦法
搶紅包、秒殺系統最怕的是雪崩效應,因為通路量的不可預知性。所謂雪崩效應是指單個裝置的故障而引起的系統全面癱瘓。 比如本來有20台機器,其中2台壞了理論上是沒有關系,但是因為通路量被配置設定到其他18個機器上,導緻這18台的壓力突然增加,進而引起更多機器的崩潰,而像雪崩一樣,一個地方一個地方淪陷,最終整個系統挂了。 應對雪崩,備援的資源是必須要考慮的,但是有局限性,因為:
不知道該備援多少。因為通路量是否會超過預期是不知道的;
無法做全面的備援,因為故障有可能在網絡,有可能在io,也有可能在資料庫,緩存等。因為這些原因隻靠備援是無法保證系統100%的穩定的,那麼限流手段就必須要使用了,所謂限流就是當系統通路流量壓力超出系統所能承受時應該作何響應,給使用者傳回排隊頁面或者讓客戶稍後重試,這種應答對背景系統基本無壓力,同時可以将并發錯峰。雖然有點“無賴”,但這是此類系統必不可少的故障應對機制。
在本例中,當背景相應不及時或者壓力過大時,會傳回給客戶一個請稍後再試的提示。
4. 網絡架構解讀
網絡架構層面,阿裡雲的帶寬是bgp的,是以網絡品質基本不用擔心。并且帶寬可以從 1mbps 至200mbps随時調整,并且可以通過增加多個slb的方式來進一步提高整體帶寬。同時因為紅包頁面是靜态的,為了進一步提升使用者體驗,減輕系統壓力,使用cdn進行緩存,cdn可以有效降低延遲,減小系統源站壓力。
5. 高可用的必要手段
高可用是保證系統穩定和健壯性的必要手段。從整個系統架構來審視高可用,在cdn層面一般都沒問題,即便是有問題也會回源,是以這裡不用考慮。 slb的高可用,阿裡雲slb本身已經是叢集機制提供了容錯,同時選了3個slb也會提高可用性。在虛拟機層面,要避免機器都在同一個可用區(機房),因為一半的機器可放在可用區a,另一半放在可用區b。緩存和資料庫層面,阿裡雲ocs、rds本身就提供master-slave的高可用機制,是以直接拿來用即可。通過這些我們也能看出來阿裡雲産品基本都自帶有高可用屬性,這在我們建構系統架構時節省了大量的成本和精力。
6. 彈性擴充要針對峰值自動調整
為什麼我們會強調彈性?因為業務彈性太大,也許遠遠不及預期的通路,但是也有可能遠遠超過預期。在網絡層,我們選擇按量付費,是以峰值就可以自動調整了。應用層的彈性,通過slb後增加機器實作,同時為了應對突發情況,可以使用ess來自動擴充,但是本例中未用。ocs也是可以線上更新,隻需要點下界面1分鐘即可完成更新,而傳統伺服器如果要擴容,不停機是很難的,并且也沒這麼快。當然,彈性在秒殺類系統中作為防禦性措施,而壓力測試就必須做充分。
說到這裡,大家可能以為架構已經差不多了,但是還少了兩個很重要的:安全和大資料處理。
7. 安全架構很重要
搶購類系統最容易被惡意攻擊,無論是滲透還是ddos攻擊,都會對系統和營銷活動造成很惡劣的影響。此次活動我們采用阿裡雲高防ip來應對ddos、cc攻擊,同時http采用https來提升安全性。一些基本的安全掃描也可以通過雲盾來完成,還是非常友善的。
8.大資料架構是利器
為什麼要考慮大資料?因為在傳統it模式下,基本不會紀錄每一個請求的日志,因為這些僅僅用于排錯,後續也不會進行分析,日志滿了就删掉。傳統it架構資料挖掘的成本太高,産生價值太低,是以大家都把日志丢棄了。那麼在本項目中我們把每一個使用者的請求都記錄下來,傳統方式我們會把日志紀錄到磁盤中,但是秒殺時每個機器都承擔成千上萬的并發,反應到io就是有很多磁盤io,普通磁盤肯定會拖累系統性能。
是以日志紀錄上我們選擇sls,有兩個好處:
幾十台機器的并發日志寫入性能沒問題;
日志統一管理查詢,便于後續問題排查和分析;
為進一步的資料分析準備。sls的資料可以直接轉移到 odps,是以後端我們用odps進行資料分析,我隻需要把資料丢進去計算就可以了。
事後也證明儲存日志是多麼重要,客戶也許一開始不需要,但後來想看活動效果,又想要,就可以很友善的完成統計。基本上所有這些因素都是在一個完善的架構中所需要考慮,那麼我們的架構設計就基本完成了。
三. 開發測試
1. 整個系統的代碼邏輯并不複雜,但是為了應對并發需要全面的考慮;
首先http頁面要盡可能小,節省網絡帶寬,提升并發。當然這種搶購必然要用移動裝置,是以移動裝置的适配也很重要,h5能夠帶來很大的便利性。同時頁面互動盡可能在本地完成,很多使用者會不停的點選,互動要盡可能少的和服務端通信,并且隻傳輸必要資訊,比如本項目中的機率數字、唯一id等資訊。
2. 性能壓力測試;
上線前最重要的就是壓力測試,因為預計并發在10萬tps以上,是以我們選用阿裡雲pts做壓測。pts的最大好處就是即開即用,需要多少壓力源也隻需要輸入參數即可,不用再去考慮去用loadrunner之類的軟體去搭建壓測環境。由于本次搶紅包邏輯比較簡單,是以壓測隻需要壓測搶紅包的url即可。
本例中使用了多個pts壓測叢集,最大并發10萬。在一開始的測試中發現,單機施壓機器大概500左右并發,10萬tps大概需要200台ecs。通過系統參數調優、ocs更新,增加slb數量至3個,qps總體提升至10萬。壓測目的基本達到,而從壓測準備到測試完成整個隻需要 1天半即完成。傳統it方式一兩天時間可能壓測環境還沒準備好。
四、運維護航
1. 7*24 監控
監控是做好系統運維的第一步:一般來說需要監控 服務端口,url,業務邏輯;
雲監控可以提供雲資源層面的監控。而應用層、業務邏輯等監控需要使用zabbix來進行全面的監控。
2. 應急方案
運維方面,最主要就做應急方案了。網絡瓶頸如何解決,通過按量付費的方式可以對帶寬不做上限限制。快速部署,通過鏡像+api的方式,可以瞬間增加幾十台機器。
3. 參數調優化
通過調整nginx及linux核心參數,使得單機并發從幾百提升至2500;
tcp conn,tcp_syncookies;
限流通過nginx參數 limit_req 的burst。
4. 上線及緩存預熱
大家都知道cdn在第一次通路時要回源的,第一次之後的通路才會走cdn,秒殺數年會有大量請求瞬間同時到cdn,這個時候cdn還沒有緩存,意味着大部分壓力都會回到源系統,很有可能直接把系統搞垮。怎麼應對,很簡單,進行預熱。 預熱也很簡單,用阿裡測或者17ce等線上測試平台多測幾次,這樣全國各地的cdn幾點都進行了緩存,當業務開啟正式客戶進來時直接就可以從cdn傳回。
5. 自動化部署
在系統運作或項目過程中,難免會遇到需求變更需要去修改代碼并部署的,使用ansible來對幾十台及其進行快速部署。
最終整個系統的架構如下:
具體來解讀下:
網絡層:ddos防護、域名解析、cdn加速;
接入層:主要是4層負載均衡slb,将通路請求分發至後端伺服器;
應用層:将虛拟機ecs分為兩個可用區a和b來提高系統整體可用性。ocs用于做資料緩存,mqs則通過消息隊列方式将一些資料異步寫入資料庫。而所有伺服器的日志都集中記錄入sls,為後續的資料分析做好準備,同時也友善日志的查找;
資料層:由于單個rds的性能有限,是以使用drds來組成一個rds mysql叢集,将系統壓力分擔至多個rds;
odps則用來做最終的資料分析,比如使用者量、通路量、使用者行為等;
運維監控:雲監控和zabbix結合來實作整個系統從雲資源到應用到業務的監控。ansible用于自動化部署;
最後再強調一下,整個系統從需求調研到開發,再到壓力測試和上線隻用了2周時間,在春晚活動中,整個系統表現非常穩定,很順利的扛過了峰值壓力。而在成本方面,這樣一個系統使用傳統it方式軟硬體投入100萬是至少的,而雲的按需付費模式在此項目中成本隻需要1/10還不到。這種時間緊、任務急、很複雜的項目在傳統it模式下幾乎是mission impossible,這也正是雲計算所帶給我們的力量。