用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量

AI科技大本營發表於2020-01-26
用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量
整理 | 夕顏
出品 | AI科技大本營(ID:rgznai100)
 
11 月 20 日,百度的萬億流量轉發引擎 BFE 登上了 GitHub Trending Top 3,今日 Star 已突破 270。事實上,這個曾經抗住 2019 年春晚搶紅包的轉發引擎早已於 2019 年夏在 GitHub 上開源,今天突然再次引發關注,那我們不妨來回顧一下這個專案。
       用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量       
首先奉上 GitHub 開源地址:https://github.com/baidu/bfe,Apache 2.0 許可。

整合四大功能,開源四大能力


BFE(Baidu Front End,百度統一前端)是百度的統一七層流量轉發平臺。BFE平臺目前已覆蓋百度大部分產品,每日轉發請求接近 1 萬億,峰值 QPS 超過 1000萬。在 2019 年百度春晚紅包活動中,BFE 平臺在超大使用者壓力、數次流量波峰下平穩執行,保證了春晚紅包活動的順利進行。
 
       用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量      
 
從曝光的資料來看,作為綜合的流量轉發平臺,BFE 平臺的主要服務包括四大塊,分別是:
  • 流量接入和轉發:支援HTTP、HTTPS、HTTP/2、QUIC等多種協議,並支援強大的應用層路由能力
  • 流量全域性排程:支援由外網流量排程和內網流量排程共同構成的全域性流量排程系統
  • 安全和防攻擊:支援黑名單封禁、精細限流和應用層防火牆(WAF)等多種防攻擊能力
  • 實時資料分析:支援分鐘級的超高維度時序報表
       用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量      
 
作為 BFE 平臺的核心元件,BFE 轉發引擎從 2012 年開始研發,並於 2014 年使用 Go 語言完成重構。
 
BFE目前已開源並支援以下重要能力:

1、主流網路協議接入
  • 支援HTTP/HTTPS/SPDY/HTTP2/WebSocket等
  • 支援TLS/HTTP/ WebSocket反向代理模式
2、可擴充套件外掛框架
  • 通過可擴充套件外掛框架,快速定製開發擴充套件模組,滿足業務定製化需求
  • 內建重寫、重定向、流量修改、封禁等豐富外掛
3、基於請求內容的分流
  • 基於領域專有語言的分流規則,滿足複雜業務場景定製化流量轉發
  • 支援完備的分流條件原語集,包括基於請求內容(URI/Header/Cookie等)以及請求上下文(IP、協議、標籤、時間等)的條件原語。
4、靈活的負載均衡策略
  • 支援叢集級別負載均衡及例項級別負載均衡,實現多可用區容災及過載保護
  • 內建加權輪詢、加權最小連線數策略,基於IP或請求內容識別使用者實現會話保持


基於Go語言,具有六大優勢


採用 Go 語言重構 BFE,是百度團隊在經過與 C、Python 與 Go 的對比之後做出的選擇。與前兩者相比,Go 具有的特點如下:
  • 效能和 C 接近
  • 併發性
    • Go routine:遮蔽底層的機制,可以充分利用 CPU 資源
    • 多執行緒模式:容易思考
  • 開發效率
    • 描述能力與 Python 接近
    • 較豐富的庫(系統庫,第三方庫)
  • 大型程式的組織
    • package
    • 資料訪問的限制(首字母大小寫的區別)
  • 可測試能力
    • 內建的單側和覆蓋檢查工具,易於做 TDD
    • go test
  • 錯誤檢查能力
    • 嚴格的編譯階段檢查:強型別,檔案包含,...
    • Panic,便於定位問題
  • 上線和運維
    • 可編譯為獨立可執行程式
 
由於基於Go語言,和業界普遍使用的Nginx開源軟體相比,BFE具有學習成本、開發成本和效能上等各方面的優勢,具體來說包括:

  • 研發效率高:Go語言的開發效率遠高於C語言(及Lua),在程式碼的可維護性方面也有巨大優勢。
  • 系統的安全和穩定性高:Go語言沒有C語言固有的緩衝區溢位隱患,規避了大量的穩定性和安全風險;另外對於異常可以捕捉,保證程式在快速迭代上線的情況下也不崩潰。

從長期趨勢看,基於更高階程式語言的軟體系統會逐步取得競爭的優勢。CPU等硬體資源的價格仍會快速下降,而開發人力成本、專案研發風險、系統穩定性/安全性方面會成為更重要的決策考慮。從這方面出發,主要基於C語言的Nginx會逐步衰落,而類似BFE這樣的基於更高階程式語言的軟體會逐步成為主流。
 
另外,BFE在設計中,還特別增加了企業級應用場景的考慮:
  • 轉發場景的直接支援:和Nginx這樣從Web Server轉型為Proxy的進化路徑不同,BFE直接為轉發場景設計,從轉發模型和轉發配置方面更滿足轉發場景的需求
  • 多租戶的支援:在雲端計算的場景下,多租戶複用是普遍的需求。在BFE的設計中,內建提供了多租戶的支援
  • 結構化的配置:BFE的配置設計,大量使用JSON這樣的結構化方式,便於和相關配置管理系統對接
  • 豐富的監控探針:作為一個工業級軟體,在BFE的設計中充分考慮了線上監控的需求,BFE程式通過HTTP方式向外暴露數千個內部狀態變數
       用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量      
 
接下來簡單介紹一下 BFE 的具體使用步驟和技術細節,但篇幅有限,關於專案更詳細的資訊,參見 https://github.com/baidu/bfe


建立並執行


前提

  • golang 1.12+
  • golang yacc
  • git


下載原始碼

  • BFE程式碼可以在以下 repo 中找到:
https://github.com/baidu/bfe
  • 克隆主要的BFE repo:
$ mkdir -p gocode/src/github.com/baidu$ cd gocode/src/github.com/baidu$ git clone https://github.com/baidu/bfe$ cd bfe

從原始碼建立

  • 在bfe(src / github.com / baidu / bfe)的源目錄中執行構建指令碼:
$ make
  • 執行測試:

$ make test
  • BFE二進位制檔案生成如下:

$ file output/bin/bfeoutput/bin/bfe: ELF 64-bit LSB executable ...

執行

  • 使用示例配置執行bfe:conf
$ cd output/bin/$ ./bfe -c ../conf -l ../log

功能性

叢集之間的請求路由


在BFE配置中,“產品”可以由多個群集組成。使用者可以定義如何在叢集之間路由請求。請求路由基於HTTP請求的內容。
 
規則配置

  • HTTP標頭中的欄位用於定義路由規則,以在群集級別分配流量,例如:
    • 主機,路徑,查詢,cookie,方法等
  • BFE提供了一個“條件”表示式來定義如何使用特殊標頭路由訊息。這是群集級別負載平衡中的路由規則。
  • 如果配置了多個規則,則BFE將按順序匹配這些規則。如果一條規則匹配,則匹配過程停止。

例子

  • 一個產品“demo”需要處理三種流量:靜態內容流量,“後”流量,其他流量,據此我們可以定義三個叢集:
    • 靜態演示:提供靜態內容
    • demo-post:發表留言
    • demo-main:服務其他流量
  • 在BFE配置中,可以新增以下路由規則:
    • 規則1:req_path_prefix_in(“ / static”,false)-> demo-static,這意味著路徑字首為“ / static”的訊息將被路由到叢集demo-static。
    • 規則2:req_method_in(“ POST”)&& req_path_prefix_in(“ / setting”,false)-> demo-post,這意味著使用方法“ POST”並以“ / setting”為字首的訊息將被路由到叢集“ demo-釋出”。
    • 規則3:預設-> demo-main,這意味著所有與上述規則不匹配的訊息都將傳送到叢集“ demo-main”。


子叢集級別的負載平衡

  • 在子叢集級別,也可以配置負載平衡規則。規則定義了分配給每個子群集的流量權重。
  • 可以使用特殊的虛擬子群集“ BLACKHOLE”來丟棄流量。

例子

  • 考慮以下配置:
    • 兩個IDC:IDC1,IDC2
    • 兩個BFE叢集:BFE1,BFE2
    • 兩個後端子叢集:sub-cluster-1,sub-cluster-2
  • 在BFE群集(BFE1和BFE2)中:
    • BFE1:{sub-cluster-1:w11,sub-cluster-2:w12,Blackhole:w1B}
    • BFE2:{sub-cluster-1:w21,sub-cluster-2:w22,Blackhole:w2B}
  • 根據配置的權重,BFE將流量分配到後端子群集。
    • 例如,如果權重配置{w11,w12,w1B} = {45,45,10},則到子叢集的流量百分比是sub-cluster-1,sub-cluster-2和Blackhole分別是45%,45%和10 %。


例項級別的負載平衡

  • 通常,子群集由多個例項組成。在子群集中,WRR(加權輪詢)用於在例項之間分發訊息。
  • 例項可以根據其容量分配不同的權重。


例項的狀況檢查

BFE對每個後端例項進行執行狀況檢查。例項具有以下兩種狀態:
  • 正常狀態:例項正常處理訊息。
  • 正在檢查狀態:例項異常,無法處理訊息。BFE在這種狀態下會定期進行健康檢查。

狀態轉換:
  • 在以下情況下正常進行檢查:
    • 在連線或向例項傳送訊息時連續失敗超過閾值。
  • 在以下情況下檢查為正常:
    • BFE從後端例項收到正確的健康檢查請求響應。

訊息重試失敗
 
如果訊息路由失敗,則BFE支援分兩個級別重試訊息:
  • 在同一子群集內重新路由訊息。
  • 將訊息重新路由到其他子群集。

連線池
 
BFE與後端例項之間的TCP連線支援:
  • 短期連線:BFE使用新建立的TCP連線將每個請求訊息路由到後端伺服器。
  • 連線池:
    • BFE維護到例項的連線池。
    • 對傳入的請求:
      • 如果有可用的連線,請重新使用它。
      • 否則建立一個新的TCP連線。
    • 通過連線完成請求處理後:
      • 如果連線池的當前大小小於配置的數目,則將連線新增到該池中。
      • 否則,直接關閉連線。
會話粘性
 
BFE支援會話粘性基於請求訊息的以下標識:
  • 源IP
  • 請求標頭,Cookie等中的欄位

將會話保持在不同的路由級別:
  • 子群集級別:會話的訊息傳送到相同的子群集(此子群集中的例項可能不同)。
  • 例項級別:會話訊息傳送到同一例項。


監測


指標

BFE支援大量的內建指標,可以通過BFE例項的訪問監視器埠獲取這些指標。


配置


在BFE的配置檔案中,設定監視埠:
[伺服器]
monitorPort = <埠>


地址


訪問以下URL,從執行的BFE例項中獲取指標的完整列表:
http://<ip addr>:<port>/monitor


外掛


外掛模組

       用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量      
值得注意的是,在該專案的眾多 issue 下,有人提出關於 BFE 目前僅支援 Linux 的問題,專案貢獻者隨後做出迴應,表示將來會支援 Windows,大家可以期待一下。

(*本文為AI科技大本營整理文章,轉載信聯絡1092722531


精彩推薦



CSDN雲端計算TOP案例徵集開啟啦~~

你的“雲+X”方案夠先進嗎?夠高效嗎?能解決行業目前的問題並快速迭代嗎?想要更多人知道你的專案?請趕快掃碼提交方案,權益多多,請見下方海報啦!

用Go重構C語言系統,這個抗住春晚紅包的百度轉發引擎承接了萬億流量


推薦閱讀

相關文章