Node部署和運維工作量降低80%,騰訊NOW直播是怎麼做到的?

  • 2019 年 11 月 14 日
  • 筆記

上一篇文章,分享了《NGW,前端新技術賽場:Serverless SSR 技術內幕》,本篇文章,將分享騰訊NOW直播在Serverless技術的探索實踐。

一、背景簡介

首先解釋一下幾個名詞:

  • NGW(Node Gateway,Node 前端接入層):IVWEB 團隊開發的內部前端業務接入層方案,目前處於騰訊內部開源狀態。
  • BFF (Backend For Frontend) ,通常指服務於前端的後端。
  • SFF (Severless For Frontend) , BFF 架構的升華,落地到 Serverless 中。

目前,NOW 直播團隊正在逐步接入 NGW,完成 BFF 向 SFF 架構的演進。

從前後端分離到 BFF,前端的能力不斷擴大,逐漸涉獵到後端和運維,對前端人員的技術能力要求也越來越高。NOW 直播 IVWEB 團隊從提升研發效率的角度,在調研了騰訊雲Serverless之後,團隊決定接入雲函數SCF產品,對 BFF 架構結合 Serverless 進行了新的嘗試。

在 SFF 架構下,Node 服務落地到 Serverless,最大的收益者是前端開發人員:

  • 前端同學不再需要關注伺服器的申請/維護/擴容;
  • 無需關心生產環境的搭建;
  • 真正做到專註業務邏輯的開發;
  • 自動擴容,零運維;
  • 接入工作量降低了 80%。

此前,團隊已經通過開發 Nest 系統的聚合服務(Node 服務的可視化管理)完成了 BFF 架構的演進。NGW 作為新項目,響應騰訊自研上雲的號召,拋開歷史包袱,全面擁抱上雲,並且有幸成為公司內首個和騰訊雲 SCF 大規模合作的前端項目,結合 SCF 實現了同構直出和 Node 服務的無服務化,做到自動部署和更新。在這裡感謝騰訊雲Serverless團隊和QQ團隊的大力支援。

二、從一個故事說起

阿特是個特別認真的人,但也有漢子柔情的一面,他攢了很久的假期,準備在情人節和小美來一場說走就走的旅行。不巧,就在情人節前一天,新上線的項目被產品挑戰了,說「首屏速度不夠快」。

作為高級工程師的阿特,有 100 種可以讓頁面提升首屏的方法;他馬上用團隊的同構直出框架,半天就擼出來了一個直出服務,部署完之後就可以和心愛的小美去旅行了。

阿特打開運維繫統,看了一下業務機的承載,需要擴容才能滿足需求。為了不影響線上業務,阿特選了新申請一批機器。半天過去了,新機器終於下來了,這時距離下班時間還有 5 分鐘。為了小美的旅行,今天無論如何都要上線。

面對新下來的機器,阿特一把梭裝好了所有基礎組件,配置和部署好直出服務,現在只需要將原來的靜態請求接入到直出服務就可以了;但事情並沒有這麼簡單,現網的域名竟然要經過好幾層接入機才能到直出服務。

憑藉著高級工程師的一雙能手,阿特一步步地終於將業務成功上線了。他鬆了一口氣,看了一下時間,沉默了許久。現在是北京時間 2 月 14 日上午 9:55,距離飛機起飛時間還有 5 分鐘,阿特終究還是錯過了和小美的旅行。

故事雖然聽起來比較誇張,但反映的事實卻無比真實:

  • 業務不斷增多,服務混布導致新老業務的變更越來越複雜,全部獨立部署則會造成資源浪費;
  • 運維繫統魚龍混雜概念繁多,不是老司機很難理清楚,對小白不友好;
  • 業務模組多、機器多、配置多,變更全靠配置系統下發;
  • 前後端共用接入機,轉發邏輯複雜。

我們發現,即使完成了 BFF 架構的演進,但難免會存在服務混布,而且仍需關注複雜的運維,效率的瓶頸始終在運維上。有沒有一種方法可以既能使服務獨立部署,並且能有效降低運維成本呢?

答案:Serverless。

三、NGW 的架構

NGW(Node Gateway,Node 前端接入層)是介於 STGW 和真實業務的中間層,用戶的請求會通過 統一網關先進入到 NGW 層,再由 NGW 來分發請求到對應業務上。

這裡的業務可以是:

  • 靜態頁面
  • BFF 架構下的 Node 服務
  • SFF 架構下的 Serverless 直出或 Node 服務

咦,這不是 Nginx 做的工作嗎?——Nginx 雖然強大,但缺點是無法做到強邏輯的分發,也不容易進行擴展,而且每次更改配置之後都需要重啟服務,查看日誌也很困難。

NGW 使用 TypeScript + Node 開發,對前端同學更友好,能更方便地進行功能的迭代和擴展,轉發邏輯可以動態下發,無需重啟服務。

整個 NGW 方案主要分為三個模組:

  • NGW 分發層:主要專註於業務的分發;
  • NGW-Service 層:負責周邊服務,如配置管理、Serverless 服務的部署和更新,日誌旁路等;
  • NGW Platform:管理平台,用於配置管理與日誌管理等。

四、容器化

作為 9102 年的新項目,響應自研上雲的號召,NGW 的全部服務均使用 Orange-CI(自研內部 CI 工具) + TKE 騰訊雲容器服務 進行構建和部署,並利用容器編排對 Docker 鏡像的構建部署進行了優化。(優化後構建鏡像時間縮短為 20秒,大小縮小至 10M 以內)

NGW 分發層作為業務分發的基礎服務,性能和穩定性非常重要,有了 Orange-CI 和 STKE 的加持,大大提高了服務部署的敏捷程度,並且在高並發場景下也能做到靈活自動擴容,再也不用提前評估業務量。

TKE 單機滿負載運行資源佔用(8 核 16G,數據來源 TKE):

高並發場景壓測下自動擴容至 8 個實例,峰值接近 8000 TPS(數據來源於 WeTest 壓測大師):

為什麼峰值只壓到 8000 TPS 呢?主要是因為峰值已經達到下層靜態伺服器的最大承載了,導致轉發效率變慢,並不代表 8000 TPS就是 NGW 層的最大承載(逃)。在 STKE 資源充足的前提下,NGW 是可以無限擴容的,無需擔心高負載導致伺服器宕機。

五、配置下發

Nginx 每次更改轉發配置,都需要重啟 Nginx 服務。

NGW 開發了 NGW-Service 層,結合管理平台對配置進行動態管理,配置更改後通過雲 Redis 下發到 NGW 分發層中。配置熱重載,平滑過渡。

配置下發流程:

目前已完成分發邏輯的動態下發,後續將陸續支援操作記錄和版本管理。

六、Serverless 無服務

在 NGW 分發層的基礎上,結合騰訊雲 SCF,就能更方便靈活地對現有 Node 服務進行 BFF 到 SFF 的演進。

  • NGW-Service 負責 Serverless 服務的管理,如部署、更新等;
  • NGW 分發層進行業務的轉發。

架構:

目前 NGW 已經支援同構 SSR 的 Serverless 化方案,並且已接入多個項目在線上通過驗證,成功率接近 99.99%(數據來自內部打點統計系統)。

NGW 目前處於騰訊內部開源狀態,待方案完善脫敏後將會逐步進行外部開源。

關於 Serverless 化方案的實現技術細節,後續將會有專門的文章來介紹,本文先不贅述了。

七、插件體系

前文說到 Nginx 雖然強大,但缺點是不容易進行擴展。NGW 的分發功能擴展是怎麼實現的呢?

除了 Koa 中間件,NGW 還引入了插件的概念來對專用分發邏輯進行模組化:

  • Koa 中間件:用於處理統一邏輯;
  • 插件:與單次分發過程的生命周期強關聯,用於處理專用邏輯。

插件的實現基於 Tapable,通過生命周期鉤子來對分發過程進行邏輯干預。

生命周期鉤子:

// 分為同步和非同步鉤子兩種,以同步鉤子為例interface ApplicationSyncHooks {   // 收到請求   didReceiveReq: AsyncSeriesHook<[Application, ProxyConfig]>;   // 即將轉發代理請求   willSendProxyReq: AsyncSeriesHook<[Application, ProxyConfig]>;   // 代理請求成功   proxyReqSucc: AsyncSeriesHook<[Application, TswAjaxResult]>;   // 代理請求失敗   proxyReqFail: AsyncParallelHook<[Application, TswAjaxResult]>;   // 接收到代理請求響應   didReceiveProxyRes: AsyncParallelHook<[Application, IncomingMessage]>;   // 即將返回代理層響應結果   willReturnRes: AsyncSeriesHook<[Application, IncomingMessage]>;   // 返迴響應完成   didReturnRes: AsyncSeriesHook<[Application, TswAjaxResult]>;}

利用插件,可以在基礎的分發邏輯上進行一些專用的邏輯處理,比如灰度轉發、白名單等。以灰度插件為例,可以在分發配置中添加插件:

{   "origin": "/ngw/index.html",   "proxyPass": "http://the-path-where-you-want-to-go.com",   // 添加灰度插件,Application 會在分發前進行插件實例化,並將 args 傳入構造函數中   "plugins": [{       "name": "AlphaPlugin", "args": ["plan-A"]   }]}

插件邏輯處理:

// 以下為簡化程式碼...  class AlphaPlugin extends AbstractPlugin {   public name = 'AlphaPlugin';   public config: AlphaPluginConfig;   public constructor(args: AlphaPluginConfig) {       super();       this.config = args; // 接收配置中的 args 參數   }   public apply(application: Application) {       application.syncHooks.didReceiveReq.tapPromise(this.name, this.didReceiveReq.bind(this));   }   public async didReceiveReq(application: Application, proxyConfig: ProxyConfig) {       const alphaConfig = getAlphaConfig(this.config[0]); // 獲取灰度邏輯,入參是配置的 "plan-A"       proxyConfig.proxyPass = alphaConfig.url; // 修改分發的地址   }}

這樣一來,就可以通過灰度插件實現對現網業務進行灰度上線或 ABTest,比如現網投放的 A 頁面,通過 NGW 可以動態分發到 B 或 C 等頁面。

八、日誌查看

NGW 基於 TSW,得益於 TSW 的染色體系,可以輕鬆地查看實時染色日誌,秒殺 Nginx。後續也會將 SCF 中的日誌收歸到 NGW-Platform 中。

九、現狀

Serverless SSR

目前 NGW + Serverless SSR 已經應用到 NOW 直播、手 Q 附近、瀏覽器直播和手 Q 群送禮等多個項目中。實際業務開發中,Node 業務的部署和運維工作量降低了 80% 以上。

以前的業務上線路徑:

申請機器 -> 申請 CL5 -> 織雲包下發部署服務 -> 更改 Nginx 配置

接入 NGW + Serverless SSR 只需要兩步,後續接入團隊腳手架後,連這兩部都可以省掉了,工作量 down down down:

  • 更改 oci 配置,將 CI 製品推送到 SCF
  • NGW-Platform 添加分發配置

穩定性

NGW 目前的分發成功率穩定在 3 個 9 以上,單元測試覆蓋率已超過 85%。

十、接下來的計劃

  • 和騰訊雲 SCF 展開深度合作,提升性能;
  • React Chunked 流式渲染方案,結合 SCF 進一步提升首屏速度;
  • 接入 Aegis 前端監控體系,實現前端全息日誌;

---------下方更多精彩----------

NGW,前端新技術賽場:Serverless SSR 技術內幕

Tags: