1. 程式人生 > >騰訊QQ日請求12億的運營平臺到底有多diao(三聲)?

騰訊QQ日請求12億的運營平臺到底有多diao(三聲)?

作者簡介:徐漢彬

騰訊 SNG增值產品部高階工程師
QQ會員體系合作線技術團隊負責人。曾就職於阿里巴巴、小滿科技。QQ會員活動運營平臺的初始開發,在五年的時間裡,將該平臺從日請求百萬級升至十億量級(日請求4-12億),成為騰訊流量支撐規模最大的Web系統之一,負責該平臺的架構設計和研發建設,在Web系統架構方面擁有比較豐富的實踐和積累。

前言

作者目前在SNG增值產品部工作,主要負責QQ會員會員特權和AMS系統的相關工作。作者之前有AMS系統相關的文章《日請求從百萬到八億的技術歷程》

本文的內容主要分為三個部分:

第一個是業務系統鏈路的梳理和流量評估;

第二是關於AMS系統高可用架構設計實踐;

第三是QQ春節紅包當天實踐經驗和總結;

1、業務系統鏈路的梳理和流量評估

1.1 什麼是運營活動

運營活動

AMS是一個活動運營平臺,什麼是活動?

活動就上圖體現的四個頁面,這些都叫活動。這時候可能有同學說,“樓主,我讀書多你不用騙我,這上面東西很簡單,這裡會不會一點技術含量都沒有?”

是的,如果本文的東西只是這上面幾個頁面的話,肯定是沒有什麼技術含量。但是如果將他們放到比較大的流量規模下,15萬每秒,就會變成具有挑戰的問題

1.2 AMS系統介紹

簡單介紹一下 AMS,其實是QQ會員的活動運營平臺,這個平臺的日請求量大概是4到12億,背後涉及的儲存和服務超過了120個,高峰期的請求量是15萬每秒。

這個系統也支撐了騰訊公司相關的業務,我們連續兩年參加了QQ春節紅包的活動。在今年除夕夜晚上,你可能正在跟家裡人吃著飯看著電視,而這時候我則在公司值班,一直值班到大年初一的凌晨三四點,所以做這個系統也不那麼容易。

1.3 QQ春節紅包活動面臨的挑戰

紅包挑戰

關於這個活動會面臨哪些挑戰呢?主要有三個方面的挑戰。

  • 第一,流量規模到底有多大?我們怎麼預估?流量是10萬20萬還是多少?怎麼預估流量規模,這是個難題。
  • 第二,假設你把流量規模已經預估出來,對於一個比較複雜的系統,裡面有存在大量的系統與系統之間的呼叫,整個會有很複雜的系統架構鏈,這個架構鏈哪怕你評估出流量規模,但是要想對架構鏈進行合適的擴容也是難點,有時候我們會無從下手。
  • 第三,哪怕前面兩個問題都解決了,我怎樣保證活動的當天不出問題呢?今天的分享就圍繞著這三個問題為核心一步一步展開,也跟大家做一個探討。

1.4 業務系統的架構梳理

第一個問題是關於如何評估流量鏈路的問題,第一步就需要把我們的系統架構給畫出來,我現在畫的是簡化圖,先將使用者跟每個子系統的關係,但這是業務層面的,具體到 server 和儲存。紅包挑戰

上面這個圖主要分為兩個部分,一部分是請求領取頁面,後面是比較複雜的動態系統。畫出這個東西是為了下面一步,就是以具體功能的節點,把使用者涉及的所有鏈路一個一個梳理並且畫出來。

比如以查詢遊戲角色的資訊相關的東西為鏈路,使用者首先是領到一個紅包,點選領取紅包到領取頁,在頁面可能會是點選一個按鈕,然後傳送請求,請求先到我們的 STGW(也就是反向代理),然後到 WEB server,再到 Cmem,再到 IDIP 以及背後的龐大的鏈路。

通過這種方式可以把每個功能點進行拆解和梳理,當我們得到這個圖以後,如果只擴容 web server,不擴容後面的每個鏈路每個環節,擴容是不成立的。

1.5 業務功能鏈路拆解

鏈路拆解

有一個觀點是隻要有錢購買足夠的機器,可以把對機器的方式對接下來,但是這個觀點是不準確的。如果不能把每個架構做充分梳理和擴容的話,涉及到狀態有關的服務是無法進行擴容的。

1.6 活動流量規模預估

怎麼評估系統在那天的真實流量規模呢?

規模預估

第一點就是推廣量,你的流量怎麼來,有些流量是我給 web 上廣告,有些是通過 APP 流量數,這裡可以得到數量,就是流量來源,然後拿到每個環節的轉化率,一百個人看到這個廣告,有多少人會點?

假設是20%,每個環節的轉化率怎麼來?一個是經驗,你以前在這邊上流量廣告的轉換率是多少。如果沒有各個環節轉化率的資料可以通過演習,你的活動當天可能是超大規模的,但是你可以先一部分灰度,把流量先轉出來。

一百個使用者有二十個人會點選領取頁面,領取頁面一個頁面涉及到了單UV的概念,一個使用者到頁面可能會發起三四個靜態資源請求,同時還會發出三到四個的動態相關資源的請求,這裡面就要把產生的行為形成一個倍數,再把評估出來的容量估值為3倍。

以一個例子來展示:假設有一個使用者領到的遊戲紅包是一百個人每秒的,但是這一百人當中只有60人點選進來,點選頁面的人又只有30個人是真的會去點領取按鈕,就用鏈路算出了UV值,到這個位置是需要做轉換的,因為單UV的總數,可能是四個請求,假設是四個,那應該是120每秒,這120每秒意味著背後所有鏈路必須都能支撐120每秒,所以整個後面的環節都應該是120每秒。

通過前面的幾個從推廣曝光的數量,最後推算出預估值的 QBS 壓力是多少。根據多年的擴容公式,估值為3倍是比較合理的,我們需要把幾個對應的環節180乘以3倍也就是360的擴容。

1.7 AMS系統擴容評估

AMS擴容評估

同樣的方式,我們在流量層面也進行了相關擴容方面的探測和預估,但在真實場景中梳理業務需要多少流量呢?

需要9.6萬每秒,差不多是10萬每秒。連數字都知道了,不就是把每個環節擴容到10萬每秒,問題就解決了?聽起來是這樣,但是大家都知道,理想是美好的,現實往往殘酷,真的每個系統都能擴容到10萬每秒嗎?

我們遇到了一些難題,發現在整個鏈路中,像 web server,很輕鬆可以到14萬每秒,但是有些地方是沒辦法的,包含第三方不可控的,假設我跟外部公司有通訊結合,或者跨了部門或跨了BG,有些系統就是難以擴容的,這時候我們在擴容上就遇到了難題。

比如像銀行發賬或者對賬的介面,你說今天搞活動要擴容20倍,這個是不大科學的。我們就會遇到數量評估出來了,擴容卻遇到問題,那怎麼辦呢?

那就是第二個話題,既然預估了數目又沒法擴容,就涉及到高可用架構設計實踐。

2、AMS高可用架構設計實踐

2.1 基於春節紅包活動鏈路的架構改造

怎麼從架構層面解決問題,從直觀的思路一般是分為三個方面。

架構改造

  • 第一是非同步化
    如果遇到了真的沒法擴容的介面或者外公司不可控的,對方也不可能配合你來擴容的介面,只能是非同步化,就是我的生產端可以快速生產,但是通過生產的方式使得介面支援10萬每秒,但是消費那邊就用非同步介面讓它慢慢消費。
  • 第二是快取模式
    就是所謂的空間換時間,今年就遇到查這個使用者是不是王者榮耀的使用者,那邊是來不及做好幾萬每秒的查詢支援,那怎麼辦?說出來比較笨,就是把一兩個億的王者榮耀的名單打到記憶體快取裡,這樣有使用者來,我判斷就不再走遊戲介面,而是查我們的系統。
  • 第三是服務降級
    適應於對你的主邏輯不相影響的模組,比如實時上報,反正這種任務不是重要的,是不是可以放棄呢?或者是邏輯上進行的放棄。沒有辦法進行10萬每秒的鏈路我們進行了改變,我們進行擴容,有些沒法支援又非必要的進行跳過。整個鏈路從原來的方式拆成兩條,上面的鏈路是可以做到支撐10萬每秒,下面是不行的,但是通過這種方式使得鏈路能夠繼續往前走。我是從可用性的架構方面來解決有些環節和東西沒辦法擴容的問題。

2.2 擴容評估的主要要素

擴容評估

接下來就遇到擴容評估的相關要素,這些要素不只是上面幾個點,你要細分的話有好幾個細的點,但是主要評估的點是鏈路的 QPS,還有一些儲存,包括磁碟大小、記憶體大小是否足夠,以及頻寬,頻寬問題靜態檔案和動態的請求都是需要合適計算一下的。

這裡面另外一點就是靜態資源怎麼解決,其實一個使用者在進入頁面,靜態請求量是很大的,如果進入到一個頁面,同時拉起好幾個圖片,它的拉取是很大的,雖然UV是兩三萬QPS,但是往往要乘以七八個甚至更多的倍數。

所以這種情況下這種流量,哪怕你用的是部署CDN,就是地理式儲存,這種對服務都是有壓力的,尤其是對頻寬,有些頻寬可能由於不足而導致請求響應更加緩慢。

那我們怎麼解決?解決方案是用離線包的機制,我們會先把靜態資源都準備好,當你的手機 QQ 在 WIFI 情況下會主動提前把春節紅包要用到的圖片給提前拉下來,放到你的內建瀏覽器。

等到真正參加活動的時候,靜態檔案幾乎都是用你本地的,相當於你根本沒有發起網路請求。也有一小部分使用者從來沒有在 WIFI 情況下觸發拉取邏輯,但是這種使用者是少數,所以絕大部分都是通過本地拉取的方式。

2.3 高可用架構建設的關鍵要點

現在每個環節的流量知道怎麼做了,也把擴容完成了,但是完成擴容只是理論上沒有問題,要想真正保證他們沒有問題,還需要關注挺多點,這裡面有幾個要點。

 高可用架構

  • 過載保護
    第一個要點是過載保護,不管流量到了真實的那天究竟有多大,有一個是保證系統不能掛掉,掛掉就是最大的失誤,我可以容忍拒絕一部分請求,但是不能容忍系統無法提供服務。
  • 柔性可用
    第二是柔性可用,更多是跟業務側緊密聯絡的,我在這個活動有一個邏輯,判斷他是新使用者,給他一個好一點的獎勵包,老使用者給普通禮包,這種邏輯在裡面就可以做柔性可用,假設這個介面掛了,判斷不出了,乾脆全部把他當新使用者用,這裡面要包括業務和產品來做,把出問題的介面相容起來。
  • 容災建設
    還有容災建設,分為兩個部分,一部分是業務主幹邏輯上的容災,另一部分是指天災人禍式的容災,在部署層面的就是輕重問題,把輕重做隔離。
  • 監控體系 && 資料對賬
    最後兩點是最容易被忽略的,就是監控體系和資料對賬。

2.4 過載保護

首先是過載保護,每個環節層層建立控制開關和流量控制。

  • 推廣層
    第一個是推廣層,如果系統出問題了,本來是8萬每秒的廣告就卡掉一半,實在不行就停了,讓系統有喘息時間。這個開關往往到了真的沒辦法的情況下,才是建議用的。
  • 前端層
    第二個流量保護是有意識的將使用者請求延長,本來你一點選就請求後臺server,點選以後我給它隨機等待兩秒的時間,或者兩分之內不能請求,這種功能對於錯峰是很有幫助的,如果不進行使用者等待時間,尖峰是很尖的。
  • CGI層
    還有一層是CGI層的保護,當他處理不過來可以過濾一部分請求,第二是可以做流量控制,保護後端介面。
  • 後端服務層
    後端外部第三方的介面QPS就是一千每秒,給兩千的話肯定就壓跨了,你不如做一個控制。

所以這相當於是層層開關,全部準備就緒,活動當天隨時隨地開啟使用。這一句的結論是部分不可用,至少比徹底不可用強

2.5 輕重分離

關於輕重分離,核心點就像發貨請求,也就是核心請求,不希望被任何其他叢集所影響到。輕重的對比在具體業務場景裡面。

比如查詢使用者的XX資訊,這東西是比較輕的,哪怕查詢失敗或者有誤了,查詢頁面或者重試一下,對使用者是不會造成損失的,這種請求是要用專項資源保證的。

這是粗略的架構圖,但是我們的部署是這樣的,進行拆開,不會影響到背後發貨的流程。

2.6 柔性可用

柔性可用關鍵是隨時隨地準備放棄一些非關鍵的路徑,比如說上報或者不重要的操作,當然還包括一些業務層面的。在這方面的實現一般有兩個方面的方法。

  • 第一種是設定一個超短耗時時間,比如平時只要五六毫秒就可以完成請求,這時候我設定二十毫秒,哪怕你連線不上或者發包失敗,我最多隻能你20毫秒,這是我們常用的方式,對於非關鍵路徑不掛是好事,繼續為我們提供服務,掛掉了就忽略它。
  • 第二種做法是 UDP,日誌用得比較多,包括QQ錢包的卡也是走這個,UDP 更直白,我把包扔給你,也不等你的回包,這個包你掛掉了我也不管,通過這些做柔性開關,使得邏輯能夠按照業務預期繼續往下走。我們正常先查白名單,然後經過結果做業務邏輯,如果掛了直接跳過,這是我們的操作。

2.7 容災建設:關鍵路徑容災

容災的建設分為兩塊

容災

  • 日常災備
    我剛才提到非同步訊息佇列的服務,要加很多的假設,每個核心服務掛了怎麼辦,如果掛掉如何有另外的機制保障呢?如果掛掉的話,我們的做法是本地磁碟,把佇列以本地磁碟的方式寫下來,後面可以通過這個磁碟日誌補發。

    日誌本身是很重要的,日誌是要冗餘,因為它也可能會掛,所以我們冗餘了三個服務,一個磁碟 server 的服務,一個 kafka,還有公司自研的羅盤資料中心,任何一份資料出問題,可以拿這三個過來做核對。

    訊息佇列常規模式是存在記憶體裡面的,如果服務突然間被擴掉了,記憶體就會丟掉,所以我們的做法是每個請求很早就落地到磁盤裡,確保掛掉了重啟以後繼續往下走。

  • 天災型災備
    另外的容災建設就是天災型,什麼機房突然停電,網路故障,更多的是通過跟運維同學的緊密配合,進行相關的部署,這些部署是跨地方部署,跨閘道器部署,通過這些避免偶發事件影響服務。

    前面也講到了很多的預案,這些都要做成一鍵開關,如果大家參與過活動,真到那天真的沒辦法好好寫程式碼,改程式碼,往往當天是非常緊張,很多事情做的,所以你的所有預案不能只停留在把它寫出來,大概怎麼操作。而是要全部變成一鍵開關,某個地方一致性,非常簡便的變成手冊,遇到A情況就是A預案,B情況就B預案,每個情況點一個按鈕整合簡單操作就開起來,只有這樣大家才有反應時間。

2.8 監控與對賬

監控

首先監控是多維度的,比如說前端的返回碼的成功率,流量的波動、禮包的發貨量,分成不同的維度去監控整體數量,包括訊息佇列的堆積情況,每個環節的消耗情況,都要按不同維度監控起來,因為往往一個流量達到從來沒有遇過的流量時,可能就不正常了,一到這個流量可能就看不見了,如果只有一個監控維度,它掛了就不知道處於什麼狀態。

我們用什麼預案,這還涉及到決策,要基於當前有充分資料,有當前系統有充分了解情況下才能做出正確的決策,如果沒有足夠多的監控資料來輔助做預案啟動還是不啟動的話,相當於抓瞎,那是非常危險的。

所以監控是比較多同學容易忽略的,怎麼樣讓資料彙總在一起,容易的看,根據資料做預案決策。另外就是自動對賬和補發指令碼,儘可能早的源頭記錄相關資料,在最終到賬的再記錄,因為這中間經歷了很多鏈路,是否有個鏈路考慮不全,導致部分使用者就發失敗了。

要知道我們的系統平時流量下很正常,但是極端的時候可能有意想不到的場景,甚至連日誌都來不及打出來,這時候對賬就很重要了,甚至包括一些很極端的你的信用出現重大問題的,一些關鍵模組掛掉了,影響了五六分鐘,這五六分鐘的資料仍然可以通過對賬指令碼進行補發,所以對賬也是非常重要的一環,他們相對來說也是容易被大家所忽略的一環。

2.9 運維體系支撐平臺-織雲系統

織雲系統

前面講了很多管理、擴容、部署,這些東西都是依託在SNG由運維同學提供的強大系統,我們通過很多的工具,通過運維的指示體系,運維同學提供了在標準化、智慧化非常高的平臺,這個平臺下能夠使得我前面所講的部署,什麼跨機房、快速部署、擴容的流程得以快速和迅速實施,並且在實施過程中使得系統能夠很順利的跑下來,這是那天做這些活動的基礎。

3、QQ春節紅包活動的實戰經驗和總結

3.1實戰狀況

業務鏈路架構梳理完了,我們還改了很多東西,使得架構理論上擴容到可以支撐的量級,這裡有個問題。活動當天到底有沒有出問題呢?認為我的系統出問題的舉手,看來大家對我的系統還是非常沒有信心的。我前面做了這麼多工作,你們就這樣對我嗎?當然有出問題,怎麼可能不出問題?不出問題還是不正常的。

實戰狀況

我們出了幾個問題,第一個是流量超預期,原本評估是9.6萬每秒,是為了省機器,擴容到14萬每秒,但是均值達到12.6萬每秒,峰值達到20萬每秒,機器撐不住了。

實時上報 server 掛掉了,儲存服務頻寬跑滿了,訊息佇列堆積非常嚴重,最高時候堆積達到了1200萬,1200萬請求進去以後,發貨特別慢,問題很多。真的到了那天晚上不出問題是不正常的,你找一個大型活動不出問題的案例給我分享一下,我也想好好學習。

系統的狀況是怎麼樣的呢?首先 web server 是高負載了,其中一個儲存的服務頻寬跑滿了,導致請求都出不來,實時上報掛掉了,資料堆積非常嚴重,大家說我們慌不慌?這系統簡直面目全非了,覺得我慌的同學還挺少。其實並不慌,因為我們準備了十幾二十個預案,本來就是應對如果出現A問題就用A預案,出現B問題就用B預案。

3.2 QQ春節除夕紅包:啟動預案

啟動預案

剛才指出的問題在不在預案裡面呢?基本都在。

  • 第一個,流量級別達到20萬每秒,這時候就把非關鍵的請求取樣,不讓它上報,沒有什麼關聯資訊,通過這種方式把流量還降了回去。
  • 第二個,實時server掛了,這個東西也對使用者來參加活動的流程沒有影響,這個地方我們也是被說得比較慘,就是產品看不到真實的發貨資料,比如10分鐘發了多少禮包,本來是通過實時server來看的,所以對產品的意見比較大。
  • 第三個,是Cmem頻寬跑滿問題,這個問題真沒法考慮,連預案都沒做,運維同學早就把萬兆網絡卡準備好了,我一直想著肯定有開發同學評估不到位,立馬預案上了就換掉了。
  • 第四個,是訊息堆積嚴重問題,雖然嚴重,但是我們早就考慮到萬一堆積到不可想象的數量,我們支援了長期儲存的方案,還故意擴了一些磁碟特別大的機器,得以不停的寫,甚至可以在裡面保留幾天都沒問題,對整體的業務效果是沒有大影響的。
  • 第五個,是我們確實發現在鏈路裡補貨失敗的,這個請求已經進來,應該給他發貨,但是某個鏈路裡又丟掉了,你不知道哪裡丟掉的。最後我們通過對賬補賬把他們給補了。

通過前面的總結,我們的預案,準備的這十幾二十個預案,我們抱著這樣一個心態,如果這些預案一個都用不上,我們是很開心的,說明你的系統完全符合你的預期在線上跑了。

大家不要覺得這些預案很浪費時間,雖然真的很浪費時間,你總是假設我這個server掛了,假設儲存掛了,每當加一個假設就要做一個預案,這個預案還需要耗費一定的工作,運維同學也是很辛苦,開發同學也很辛苦,但是這十幾二十個預案真的出問題的時候,真的是救命的。

雖然我們希望這些預案一個都用不上,但是往往用上一兩個都是救命的,如果我沒有預案,遇到前面四個問題的話,我就真要被開除了。

3.3 QQ春節紅包活動的反思

總結一下這些問題:

首先流量超預期,是少估算了QQ錢包的流量;

其次是業務叢集隔離和分業務預估也做得不夠好,遊戲這邊不受到影響,QQ錢包高負載,影響的範圍不是紅包叢集了,整個都受到影響;

然後到擴容這邊,雖然我自己常常講三倍擴容原則,我們是9.6萬的預估值,理論上要擴到30萬每秒是比較安全的,但是我們為了省機器,最後只擴容到14.6萬每秒的量級;

最後發現超預期了,所以就出現高負載場景。

所以有些原則該遵守的大家還是要遵守,也是我自己抱僥倖心理,這點我需要檢討。

另外就是實時 server 掛了,涉及到監控和產品業務資料,也是當時比較好提前考慮和納入進來的。

最後是頻寬,被跑滿了,這也是我們梳理不到位,我關注一些靜態資源,假設平時是兩萬每秒的系統,看看對應的儲存大概的頻寬情況,再用層級算一下預估量就有大概值,這個問題如果有做詳細的梳理是可以梳理出來的,本來是可以做得更好的。

最下面這個圖是其中外網的入網流量量級,5.1G每秒,這對靜態的圖片量級並不大,但是這不是圖片,是前面前端的普通HTTP包頭,沒有任何圖片,這樣的請求達到5.1G,也從側面反映出我們當天的峰值還是比較高的。

3.4 大流量活動的高可用建設經驗總結

本文圍繞了三個主題進行了分享,現在做個總結。

高可用建設

首先是怎麼建設高可用的系統,在大流量的場景下,第一點是需要對系統架構進行梳理,首先你能夠把整個系統架構以圖的形式畫出來,畫得越細越好,每個環節每個子系統都畫到,基於這樣一個架構圖進行功能點的鏈路梳理,一個領取功能涉及哪幾個環節,有沒有重疊的,全部都計算出來。

因為任何流量壓力都有來源,要麼是上廣告,這個廣告的曝光是多少每秒,再加上你歷史得到的、演習得到的數字進行彙總和計算,這樣就可以得出流量的壓力。

還有 APP 可以算當天登入每秒的峰值,大家覺得 APP 可能難算曝光,APP 可以按登入人數算,最高人數比如是五千每秒,那就按五千UB來算,按這個值折算成你的廣告曝光帶來的流量。

所以通過這種方式當把流量預估出來以後,對架構進行擴容評估,但是擴容評估中肯定會遇到跟狀態相關或者第三方不可控的系統,這些系統也沒辦法直接完成平行擴容,就需要對它進行合適的改造,根據前面共同探討的幾個原則改造,改造完了以後就可以根據可用性的幾個原則,對它進行增強,過載保護等等六個原則進行增強。

最後一點非常重要,就是梳理你的緊急預案,可能你會得到好幾個緊急預案,進行梳理,做好表格,做好開關,讓當天晚上值班的同學把表格讀熟,出現什麼問題就用什麼預案。當我們做完以後,這個系統就可以真正去參加大流量的流量服務了。

文章來自微信公眾號:高效運維