從 0 到 1000 萬:嗶哩嗶哩直播架構演進史
本期作者
趙海林
B 端技術中心資深開發工程師
01 前言
嗶哩嗶哩直播成立於 2014 年,經過 8 年時間的發展已經從最初的業務試水成長爲公司重要的業務板塊之一。技術架構也從一個單體服務演進爲由數百個微服務組成的複雜系統。本文將回顧 8 年來嗶哩嗶哩直播架構演進中一步步的變化,帶你瞭解它是如何從 0 開始逐漸成爲能夠承載千萬在線的微服務系統。
02 從 0 到 1
和大多數網站一樣直播也是始於一套 LAMP 架構,即 Linux + Apache + MySQL + PHP 。前端、服務端、定時任務所有功能都集中在一個叫做 "live-app-web" 的項目中。
直播系統架構
一個典型直播後臺架構由三部分組成:業務系統用於直播各種業務功能邏輯實現、推拉流系統用於主播推流和用戶拉流觀看、長連接系統用於在直播中的各類實時業務數據推送觸達。而 live-app-web 即承擔了 application server 的角色。
live-app-web 的應用架構
在 live-app-web 中既有通過 PHP 模板引擎 Smarty 渲染的頁面,也有 JS 寫的前端頁面,還有常駐後臺的 PHP 消息隊列處理程序(通過 Redis List 實現的生產 - 消費模型),這些功能被分別放在各自的代碼目錄中,分別由前後端開發人員進行代碼開發,並最終部署到一臺臺物理機上。
live-app-web 最初的項目結構
雖然現在看起來這套架構非常簡陋,但在最初的 2 年裏我們在 live-app-web 實現了每個直播平臺所必備的各類業務系統,而這些系統也在後續的演進中也在不斷髮展壯大成爲一個個重要且獨立的業務系統。
live-app-web
像任何一個高速發展的業務一樣,live-app-web 的代碼量也在急速增長,從 2015 年中的 5W 行 PHP 代碼到年末的 8W 行,再到 2016 年中已經累計到了 13W 行。我們在這期間做了一定的前後端分離改造,將前端部分拆成一個個單獨的前端應用,如直播首頁、直播房間頁、直播個人中心頁等。但隨着業務增長和人員擴充單體應用帶來的問題也越來越多,並行項目帶來的合併衝突、發佈排隊、某個子模塊問題導致整站掛等問題日漸突出,而這些問題也終於在一個重要事件上集中爆發了。
2016 年某一時刻的 git 狀態
03 局座來了
不瞭解局座 B 站直播梗的同學可以先通過這個鏈接瞭解一下事件背景:如何看待張召忠將軍 7 月 13 日的 b 站直播?[1],一句話總結就是:局座來了直播掛了,睿總在知乎公開道歉。
當時的直播幾乎受到全網的羣嘲,微博、知乎各類吐槽的聲音鋪天蓋地。回頭來看一方面是對觀看人數的預估不足,另一方面受到單體服務架構的制約,監控告警、資源彈性、限流降級、故障隔離等手段都非常缺乏。痛定思痛之後直播開啓了微服務化的歷程。
04 微服務化
如何做微服務?這是擺在當時團隊的一大難題,由於當時團隊成員主要是 PHP 背景,同時業務也在快速迭代,切換語言從 0 開始顯然是不現實的。而當時正好有一款在國內很火的 PHP 高性能服務框架 Swoole,通過進程常駐的方式顯著提升了 PHP 服務的運行性能。經過一定的技術調研之後團隊決定以 Swoole 爲基礎構建直播的微服務框架,並定義了以下原則:
-
按業務領域進行微服務拆分
-
每個微服務擁有自己獨立的數據庫、緩存
-
每個微服務僅能訪問自己的數據庫、緩存,服務間只能通過 RPC 訪問
-
微服務負責人對自己的負責業務的服務穩定性負責
服務框架:我們基於 Swoole 開發了我們自己的微服務框架,這套微服務框架實現服務進程管理、平滑重啓、ORM、Cache、Logging 等,業務只需要按照模板實現 controller 和對應 service 代碼即可,能夠比較快速地上手開發。
通信協議:微服務間通信我們採用了基於 TCP 上自行封裝的 RPC 協議並稱之爲 liverpc ,這個 RPC 協議非常簡單直觀,通過固定長度 Header 頭 + 變長 JSON Body 實現,服務間以 TCP 短連接進行服務調用。
服務發現:引入微服務後還需要解決的一個問題是如何做服務發現?結合當時的背景我們選擇了 zookeeper 作爲服務發現組件,同時爲了隔離服務註冊、發現、健康檢查的複雜性,我們專門開發了一個叫做 Apollo 的業務伴生程序用於服務配置拉取、服務註冊、服務節點發現,業務框架通過文件監聽的方式感知配置變化進行熱加載。
配置管理:同樣地我們採用了 zookeeper 來保存每個服務的配置文件,並通過 Apollo 進行配置拉取和變更監控。
消息隊列:我們搭建專門的 kafka 機器作爲消息隊列,由於 PHP 直接跟 Kafka 交互較爲複雜,我們搭建了專門的投遞代理服務 publisher 和消息回調通知服務 notify。
統一網關:另一方面針對缺乏統一限流、降級能力的問題,我們單獨開發了一個網關服務 live-api ,並且要求所有外部的訪問都需要經過 live-api 轉發到對應的業務服務。在這一層統一網關上我們實現了 流量轉發、URL 重寫、超時控制、限流、緩存、降級等能力。live-api 也是基於 swoole 實現的,不同的地方在於我們是通過 swoole 提供的純異步 client 實現,在性能上有一定保證。
至此一整套微服務系統的雛形已經顯現出來。
在這一套微服務系統上我們逐漸將 live-app-web 各自業務域的邏輯重構到對應的服務中。同時我們和 DBA 一起協作完成了直播的數據庫在線拆分,將原來集中在一個庫的業務表拆分到一個個獨立的數據庫中,實現了高速路上換輪子,也徹底解除了存儲層混用的風險。
2017 年 12 月局座再次來到 B 站開直播,帶來了比去年多得多的流量,但這一次我們穩了。
05 容器化
一直以來直播服務均採用物理機部署的方式,這種方式存在明顯的缺陷:需要爲每個服務分配獨立的端口避免端口衝突、部署目錄需要隔離、存在資源競爭、單個服務容量無法準確評估等等。而隨着 B 站業務規模的擴大,公司的基建團隊也提供了更爲穩定的容器平臺,在充分調研後我們啓動了服務 Docker 化改造並在很短的時間內完成了全部服務的容器化部署。
在 Docker 化部署中面臨的一個問題是:如何選擇 CPU 調度方式 ?
我們知道在 Docker 中通常有兩個方式 :1、CFS (完全公平調度)即通過按比例的 CPU 時間分片進行調度,這種資源分配方式比較靈活,也可以通過資源超配來提升整體的資源使用率;2、CPUSET(綁核)這種方式通過設置 CPU 親和性將 POD 綁定到指定的一個或多個 CPU,實現資源上的獨佔。
我們在將 PHP 服務遷移 Docker 時發現 CFS 模式下接口超時非常嚴重,已經達到了無法接受的程度,因此所有的 PHP 服務均採用了 CPUSET 的方式部署,同時 PHP 服務的工作進程數也通過壓測的方式得到最佳配置,爲分配的 CPU 數量的 3~4 倍表現最佳。
在 CPUSET 模式下同樣存在的突發流量的困擾,這類突發流量在 Prometheus 的監控圖表中難以發現,因爲監控數據通常是以 30s 週期採集擬合生成監控曲線。但在請求日誌上我們可以清晰地看到一條條秒級的請求突刺存在,而這些請求量遠遠超過了我們爲服務配置的 CPUSET 數量,而要滿足這種突發流量而調高配額顯然也是不現實的,因爲這會造成極大的資源浪費。
針對這種場景我們將應用資源池分成了兩個分組:固定資源池和彈性資源池,固定資源池中的服務採用 CPUSET 固定分配好資源量,而彈性資源池採用多個服務混部的方式,單個服務不限制其資源使用量。並通過網關對突發流量進行分流,將突發流量引入到彈性資源池,以此來解決突發流量帶來的容量瓶頸。
網關服務 live-api 會實時統計每個接口的 QPS:當 QPS 小於 X 時流量全部轉發到固定資源池分組,當 QPS > X 時超出閾值的請求會被轉發到彈性資源池。同時我們實現了請求打標功能,在彈性資源池內的請求會優先請求同在彈性資源池的服務。我們也可以通過觀察彈性資源池的的利用率來判斷固定資源池服務是否需要擴容,最終的目的是通過少量的混部彈性資源池來解決個別服務頻繁的突發流量報錯。
關於 CFS 超時的問題後來在阿里雲公開的文章中有了更詳細的闡述,並通過 CPU Burst 技術將 CFS 調度導致的超時問題大大緩解,CPU Burst 的核心是將我們常用的令牌桶限流算法引入到了 Linux 內核 CPU 調度上,當 CPU 使用率低於設定的配額時可以累計未使用的配額,並在後續的調度中允許使用累計的這部分配額來應對突出流量。隨後內核團隊通過內核升級、優化等方式解決了 cgoup 泄露、調度不均衡、超時等問題。同時在內核上通過調度算法優化,利用 CPU Burst、Group Identity 、SMT expeller 等技術實現了在離線業務混部互不影響、全站資源合池等重大技術特性,資源容量和利用率得到極大提升。業務應用也不再通過 CPUSET 這種相對固定的資源分配方式,而是在 CFS 調度模式下通過 VPA、HPA 這樣的彈性資源管理策略,動態、按需地獲得所需要的運行資源。
06 Golang 真香
2018 年是 Golang 大火的一年,毛老師作爲 Golang 佈道師在嗶哩嗶哩主站推進 Golang 服務化演進非常成功,並通過 Golang 開發出了一系列的微服務框架和中間件,如 Kratos(Go 微服務框架)、Discovery(服務發現)、Overload (緩存代理)等,相當一部分項目也同時在 github 上進行了開源。
彼時的直播正面臨着下一步技術演進的抉擇,因爲基於 swoole 構建的 PHP 微服務體系已經不能支撐更大的流量了,其主要問題集中在 :
-
PHP 的多進程同步模型極易因爲單個下游異常而導致整個服務掛掉,因爲下游響應變慢 PHP Worker 不能及時釋放,新的請求來了之後只能排隊等待空閒 Worker,這樣的級聯等待進而導致系統的雪崩。
-
實現 RPC 併發調用較爲困難,在一些業務複雜的場景由於只能串行調用下游接口,導致最終對外的接口耗時非常高。
-
PHP 服務擴容帶來了數據庫、緩存連接數的壓力,當時還沒有成熟的數據庫代理,而是每個 PHP Worker 都會直連數據庫,這直接導致了連接數的爆炸,進一步限制了 PHP 服務的擴容能力。
而 Golang 的協程模型正好可以解決這些問題,毛老師在主站 Golang 服務化演進基本完成的情況下親自來到直播指導 Golang 服務化演進。
對於這次 Golang 服務化演進,我們將服務劃分爲了三種類型:
-
業務網關(interface):業務網關按業務場景進行劃分,如 App、Web 網關,在網關內完成對應場景的 API 接入,對下游業務服務的數據聚合、App 版本差異處理、功能模塊降級等。
-
業務服務(service):業務服務按業務領域劃分,如房間服務、禮物服務,不同的業務服務完成各自的業務邏輯。
-
業務任務(job):業務 JOB 是依附於業務服務的,通常是用於定時任務處理、異步隊列消費等場景。
其中特別要提到業務網關的設計,在直播首頁、房間頁的場景中,由於業務邏輯複雜客戶端通常需要調用十個甚至數十個接口,部分接口還存在時序依賴。不僅客戶端代碼實現複雜,還導致了客戶端頁面展現的延遲。因此在新的 Golang 網關實現中我們把單一場景的展示數據統一聚合到一個接口中,即打開一個頁面只需要調用 1~2 的接口即可完成頁面功能渲染。隨後我們還在業務網關實現了熱點數據主動緩存、下游服務異常的自動降級等特性。
經過幾個服務的試點後發現基於 Golang 的服務無論在接口耗時還是穩定性上均遠超 PHP 服務,特別是網關需要聚合 10 幾個下游的數據時,通過協程的併發處理接口平均耗時不到原來 PHP 服務的一半。在此後的一段時間越來越多的 Golang 服務創建,更多的 API 也通過 Golang 網關對外提供到 嗶哩嗶哩 Web、PC、Android、iOS 等各種設備中。
07 live-app-web 的終結
2019 年直播最早的服務 live-app-web 終於完成了它的使命,所有線上功能全部完成重構遷移,實現了 live-app-web 服務整體下線。截止下線時 live-app-web 已累計了 19W 行代碼、上百位 contributers,感謝他們!
08 新網關的誕生
回到 Goalng 微服務演進過程中,我們並沒有讓曾經的 live-api 網關承接 Golang 業務網關的流量,一方面是因爲當時 swoole 沒有成熟的異步 http client,另一方面則是基於 PHP 的純異步網關也逐漸顯露出性能瓶頸。而問題在 2019 年也逐漸暴露出來了:
-
Golang 業務網關限流需要業務在各自服務內分別接入、配置修改後需要重啓生效。某個緊急情況下甚至發現部分服務未接入限流組件。
-
live-api 在更大的業務流量下表現不佳,已經成爲一個瓶頸,而存量 PHP 服務在相當長一段時間還需要持續迭代和提供服務。
對新網關的需求應運而生,在調研了 Kong、Tyk、Envoy 等多個開源網關,我們決定採用 Envoy 作爲數據面,自研 Golang 服務作爲控制面的方式來實現新網關。Envoy 在 service mesh 領域幾乎是 No.1 的存在,其非常適合作爲流量轉發服務。我們將新網關命名爲 Ekango。
爲了進一步移除 live-api,我們將原有基於 TCP 的 liverpc 協議升級支持了 HTTP 調用,這樣就可以將請求從 Ekango 直接轉發到對應的 PHP 服務,同時也極大地便利了研發的開發、調試成本。
在 Ekango 網關中我們實現了分佈式限流、接口條件 Rewrite、接口降級、統一鑑權、接口風控、多活可用區降級等特性,並提供單機 15W+ QPS 的服務能力。
同時我們基於 Ekango 的設計開發經驗,基於 Envoy 實現了 service mesh 應用:Yuumi。Yuumi 是解決 PHP、JS 等語言訪問 Golang 開發的 GRPC 服務問題的解決方案,因爲長期以來微服務建設圍繞 Golang 生態展開,對於其他語言的支持卻略顯薄弱。對於直播而言我們希望 PHP 服務也一樣能享受到 Golang 生態同等的服務治理能力,並且能夠方便地調用 GRPC 服務。
Yuumi 的實現解決了這一問題,通過 service mesh 的方式 PHP/JS 進程以 HTTP 協議訪問本地的 sidecar 進程,由 sidecar 再將請求轉發到對應的 HTTP 或 GRPC 服務,並且業務服務無需關心服務節點發現、節點錯誤重試、節點負載均衡等等微服務治理問題。
Ekango 幫助直播支持了數個百萬級、千萬級的大型活動均有穩定的性能表現。但他也存在一些缺陷,如部署配置複雜、C++ 代碼難以二次開發,特別是流量治理和管控能力缺乏可視化的控制面,只有少數幾個開發者才能正確配置。我們在之前的文章中有介紹過微服務團隊開發了 B 站統一的網關,其在支持常規的流量治理能力外,還提供了全流程可視化的接入方式和管控面、API 元數據管理、全鏈路灰度發佈等高級特性。因此在充分評估之後直播也將網關流量全量遷移到統一網關上,由統一網關對全站的入口流量進行流量管控和治理。統一網關同時也作爲 Kratos 開源項目之一在 Github 上同步更新。
至此直播的架構演進基本告一段落,在此之後我們進行了消息隊列和定時任務的角色拆分、分佈式任務調度的引入徹底解決服務單點部署問題。同時積極推動業務多活落地以解決更大範圍的可用性問題,服務好直播業務的快速發展。在架構演進過程中我們也碰到了一些典型問題,在這裏也對這些問題的處理作一定的總結,希望能啓發你的思考。
09 關於熱 Key
熱點問題無處不在,搶購、秒殺、抽獎、一次大型活動、突發事件都會形成一個個熱點,而最直接的影響就是產生熱數據,進而導致單節點被打掛、服務雪崩等可怕結果。對於直播業務而言,最容易產生熱 Key 的就是那些熱門房間,即我們稱之爲高在線房間。隨着直播架構的迭代,我們對於熱 Key 的處理方式也在發生變化,但都圍繞着多級緩存、分而治之的思路進行,同時也需要考慮數據一致性、時效性,不能盲目地通過加緩存的方式來解決熱 Key。
9.1 PHP 服務的高在線熱點緩存
在 PHP 微服務時代我們通過一個集中的 monitor-service 收集來自 CDN 和 彈幕長連接數據,獲得當前在線人數較高的房間,並將這些房間信息推送到消息隊列中。由關心熱門房間的服務 job 消費到這些熱門房間信息,將各自業務可能涉及的熱點數據主動推送到緩存中。而服務進程內也會有一個定時器監聽這些熱門緩存 Key,並定時將這些數據直接拉到 PHP 進程的內存當中。這樣熱門房間的業務數據就會直接命中內存緩存。
9.2 Golang 服務的高在線熱點緩存
在 Golang 服務建設中我們簡化了熱門房間檢測邏輯,直接提供了一個熱門房間 SDK,業務服務可以直接通過 SDK 判斷特定的 room_id / uid 是否屬於熱點,而由 SDK 內部定時拉取熱門房間列表信息。業務再通過定時器將熱點房間數據直接緩存到內存中。
這樣的好處是:
-
熱門的判斷閾值可以由各個業務服務自行控制,如 A 服務認爲 1W 在線屬於熱門,需要進行預熱處理;B 服務認爲超過 5W 在線的屬於熱門數據才需要預熱處理。這樣對於非熱門的數據提供較高的數據時效性和一致性、對於熱門的數據通過犧牲一定的一致性來實現更高的可用性。
-
熱門的處理可模擬、可演練,通常在預期的大型活動中我們會提前將活動房間在後臺標記爲熱門房間,再通過壓測來驗證熱門房間處理邏輯是否生效、性能是否符合預期。
9.3 熱點數據主動探測
隨着直播在 B 站主站業務的融入,我們發現熱點並非僅來自於熱門直播房間這一種場景,熱門稿件、熱門評論同樣會對部分直播服務造成熱 Key 問題。因此我們設計了一個更通用的熱點檢測和處理 SDK 。
業務在接收到用戶請求後調用計數 API,SDK 異步通過滑動窗口 + LFU + 優先隊列計算 Top-K,定時向業務回調統計到的熱點數據 ID ,業務基於這些熱點 ID 將數據源預加載到內存。這樣對於熱點的統計和判斷完全取決於業務自身的 QPS 情況,而無需依賴外部數據。最終我們實現了熱點數據的秒級感知和數據預熱緩存能力。
9.4 代理層的內存緩存
Redis 在 6.0 中實現了客戶端緩存機制來解決熱點數據問題。我們的中間件團隊也在內部的緩存代理上實現了客戶端數據緩存,通過中間件管理後臺我們可以配置正則表達式匹配一類的緩存 Key,符合規則的緩存 Key 會在代理層進行數據緩存,對該 Key 的下一次訪問會直接命中本地緩存,不再需要訪問緩存服務器,直到本地緩存失效。
代理層緩存特別適合於已經發現熱 Key 的緊急處理流程中,直接將發現的熱 Key 設置爲本地緩存可以極大緩解熱 Key 風險。但其並不適合作爲一種通用熱 Key 處理方案進行提前配置,特別是針對一類 Key 的正則匹配這會影響這類 Key 的數據一致性。
9.5 Proxyless Redis Client 集成熱點緩存
熱點探測 SDK 需要業務主動接入,代理層的緩存方案過於簡單。在發生多次熱 Key 觸發告警後,我們與基礎架構同學交流探索出了以 Redis Client 內嵌熱點緩存 SDK 的方式來實現業務的透明接入。在該方案中基礎架構同學借鑑了 HeavyKeeper 算法重新設計了熱點探測 SDK。HeavyKeeper 用於在流式數據中以較小的內存開銷獲得非常精確的 TopK 計算結果,統計出的 TopK 即是我們想要知道的熱 Key。業務透明接入和緩存配置動態更新這兩個特性的結合成了熱 Key 的殺手級解決方案。
9.6 熱點寫數據的處理
在直播場景中除了讀熱點,還存在寫熱點的場景。通常是由於大量用戶向同一個主播贈送禮物、發送彈幕等行爲產生的寫操作,進而對單條記錄產生大量併發寫場景。進一步分析這些併發寫的場景我們發現通常是針對單條記錄數值的增 / 減操作,如經驗值、積分、點贊數等,而這類場景天然是可以支持聚合的。因此我們開發了一個聚合寫入 SDK,其可以採用內存聚合或 Redis 聚合的方式,將業務對數據的變更操作按設定的週期進行聚合寫入,比如 + 1、+2、-1 這樣三個操作可以直接聚合成 +2 一個操作。實現這個 SDK 需要考慮聚合窗口大小、下游 DB 壓力、服務異常重啓的數據一致性保證等。
10 關於請求放大
房間服務是直播流量最大也是最核心的服務之一,日常 QPS 維持在 20W+。在運營房間服務中我們發現了以下幾種場景的請求放大:
10.1 請求超出需要的數據
在分析房間服務高 QPS 調用來源方時我們發現部分業務僅需要房間信息中的一部分數據卻請求了整個房間信息,比如某些業務方僅需要判斷用戶是否擁有直播間卻調用了完整的房間信息接口,本來一個字段能解決的問題接口返回了數十個字段,造成不必要的帶寬消耗和接口耗時。我們參考 FieldMask( 關於 FieldMask 可參考 Netflix API 設計實踐: 使用 FieldMask)的設計將房間信息拆分成不同的的模塊,如播放相關、直播卡片展示相關等模塊。業務方可根據場景需要組裝 API 調用獲取對應模塊的數據實現按需請求。
10.2 重複的請求
直播間承載了直播近 80% 的業務功能,用戶在進入房間時會請求進房接口。在這個接口中網關會聚合多個下游的數據後統一返回給用戶,我們發現這個場景存在重複請求房間信息的情況。
上圖所示除了 room-gateway 會請求房間信息外,gift-panel、dm-service 也會分別再請求一次房間信息,直接導致了房間服務的請求放大。這樣的下游服務越來越多後,用戶一次進房將對房間服務產生 10 倍以上的流量放大。而這種流量放大顯然是沒有必要的。解決方案也很直接將 dm-service、gift-panel 依賴的房間信息通過接口直接傳遞給對應服務。調用時序調整爲先調用房間服務獲取房間信息,再併發調用業務服務獲取業務模塊數據,最後組裝成業務需要的數據返回。
10.3 業務服務的請求放大
直播間承載了數十種業務功能,用戶的一次進房會分別向這數十個下游服務進行請求。對每個下游都要求按照進房 QPS 進行備量,即承擔至少 2W+ 的 QPS。這對於一些小衆的服務是難以承受的,從數據上看對下游的 99% 請求都是查空的無效請求。爲了降低接入房間場景業務的負載、減少資源浪費,我們在房間服務上實現了一個 TAG 機制,業務服務將數據 TAG 同步到房間服務,網關、客戶端 在請求房間信息後根據 TAG 標識狀態決定是否請求對應的業務服務,這樣就避免了大量業務需要承擔用戶進房級別的 QPS。
11 關於活動保障
一次大型活動的技術保障是一場技術盛宴,也是對所有研發同學的一次大考。直播技術在歷年的活動保障中沉澱了一系列的工具和方法論。圍繞場景梳理分析、服務容量預估、全鏈路壓測、降級預案、現場保障等方面有一系列標準化方案、工具和平臺支持。
11.1 場景梳理
場景梳理的目的是瞭解一場直播活動中涉及了哪些業務功能、服務和接口,以此針對涉及的業務模塊開展後續的保障工作。通常活動直播間所使用的功能是普通直播間的子集,這就需要直播間內的功能都需要有控制開關,這裏的控制開關一定是需要在終端實現的,即開關關閉後客戶端不會對這一功能服務產生任何請求壓力。場景梳理需要基於用戶的真實操作路徑進行請求錄製,可以通過代理抓包的方式進行自動化的場景錄製,再通過錄制請求對應的 Trace 鏈路快速生成場景依賴關係圖,這個關係圖就明確了該場景下涉及的服務、資源等信息。
11.2 容量評估
容量評估用於確定活動所需要的資源,以進行採購備量和提前擴容。容量評估一定是基於歷史數據和活動預估進行推算,其中針對不同的業務有不同的增長係數。
11.3 服務壓測
服務壓測通常是對線上服務真實容量進行摸底,一般在服務擴容前和服務擴容後都會進行壓測以驗證服務容量是否滿足活動需求。特別地針對數據寫的場景需要通過全鏈路壓測的手段實現壓測數據和真實數據的隔離,避免壓測產生的髒數據影響線上業務。
11.4 降級預案
無預案不保障,針對可能出現的技術風險都需要有對應的 SOP,且這些 SOP 都需要通過預演的方式驗證方案有效性。
11.5 現場保障
現場值班保障時通常會遇到信息爆炸、協作難度大的問題,特別是突發的系統告警容易產生驚羣效應。需要高效信息分發、實時協作,實現保障工作的有序流轉、不重不漏、快速執行。基於保障場景的特殊性我們研發了活動實時保障平臺。
在實時保障平臺中按照業務場景劃分不同的場景負責人和保障值班,所有的線上服務告警、指標異常都會以實時推送的方式展示在對應保障人員的值班頁面。針對常見的告警類型,如 CPU 過高、服務限流會直接關聯到 SOP 手冊,值班人員可以基於手冊指導完成處理預案。在保障結束後我們也可以基於實時保障平臺的數據記錄生成保障報告,覆盤保障過程中出現的問題、響應時效、執行結果和後續 TODO。
12 高光時刻
2021 的 《英雄聯盟》全球總決賽嗶哩嗶哩直播實現了單平臺超千萬人同時在線的記錄。整場比賽服務運行穩定、用戶觀看流暢,這是屬於直播的高光時刻。
13 未來展望
直播的技術架構仍在向前演進,持續圍繞服務穩定性和高可用建設在業務架構治理、多活和單元化方向不斷進化。期望在今年的 LOL S12 中在線人數再創新高。
如果你有想了解的細節或感興趣的話題,也歡迎留言討論。
參考資料:
[1] https://www.zhihu.com/question/48457286
[2] https://www.infoq.cn/article/y2semvajjgxj9mbg9p00
[3] https://www.redis.com.cn/topics/client-side-caching.html
[4] https://www.computer.org/csdl/journal/nt/2019/05/08809410/1cFUZDJL2OA
[5] https://github.com/go-kratos/gateway
[6] https://zhuanlan.zhihu.com/p/436382314
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/KKU_V5nRHuMeFjBXwbDReQ