成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

字節跳動大規模企業級 HTTP 框架 Hertz 設計實踐

精選
開發
日前,字節跳動技術社區 ByteTech 舉辦的第七期字節跳動技術沙龍圓滿落幕,本期沙龍以《字節高性能開源微服務框架:CloudWeGo》為主題。在沙龍中,字節跳動字節跳動基礎架構服務框架資深研發工程師 高文舉,跟大家分享了《大規模企業級 HTTP 框架的設計和實踐》,本文根據分享整理而成。
日前,字節跳動技術社區 ByteTech 舉辦的第七期字節跳動技術沙龍圓滿落幕,本期沙龍以《字節高性能開源微服務框架:CloudWeGo》為主題。在沙龍中,字節跳動字節跳動基礎架構服務框架資深研發工程師 高文舉,跟大家分享了《大規模企業級 HTTP 框架的設計和實踐》,本文根據分享整理而成。

本文將從以下五個方面介紹 CloudWeGo 大規模企業級 HTTP 框架 Hertz:

  1. 字節跳動內部 Go HTTP 框架的變遷;
  2. 企業級 HTTP 框架的設計考量和落地思路;
  3. Hertz 的核心特點;
  4. 未來規劃和挑戰;
  5. 總結。

1. 字節跳動內部 Go HTTP 框架的變遷

在正式開始介紹第一部分的內容之前,先給大家展示一組關鍵詞。2020 年初 Hertz 立項,2020 年 10 月,Hertz 發布第一個可用版本。2022 年 6 月,Hertz 正式開源。 截至目前,Hertz 在字節內部已經支撐超過 1.4 萬個業務服務,日峰值 QPS 超過 5000 萬。

Hertz 不僅支撐業務服務,同時還會橫向支撐字節內部的各種基礎組件,包括但不限于字節跳動服務網格控制面、公司級別壓測平臺以及 FaaS,還包括各種業務網關等等。Hertz 的高性能和極強的穩定性可以支撐業務復雜多變的場景。在公司內部 Hertz 接替了大量基于 Gin 框架開發的存量服務,大幅度降低了業務資源使用成本以及服務延時,助力公司層面的降本增效。

圖片

下面我們可以從 Hertz 出現的背景以及 Hertz 的設計目標和思路體會到,Hertz 的出現絕不是偶然。

1.1 基于 Gin 封裝

眾所周知,字節內部使用 Golang 比較早,在大約 2014 年左右,公司就已經開始嘗試做一些 Golang 業務的轉型。2016 年,我們基于已開源的 Golang HTTP 框架 Gin 框架,封裝了 Ginex,這是 Ginex 剛開始出現的時期。

同時,2016 年還是一個開荒的時代,這個時期框架伴隨著業務快速野蠻地生長,我們的口號是“大力出奇跡”,把優先解決業務需求作為第一要務。Ginex 的迭代方式是業務和框架側在同一個倉庫里面共同維護和迭代。

圖片

1.2 問題顯現

2017 - 2019 年期間,也就是 Ginex 發布之后,問題逐漸顯現。主要有以下幾點:

迭代受開源項目限制

Ginex 是一個基于 Gin 的開源封裝,所以它本身在迭代方面是受到一些限制的。一旦有針對公司級的需求開發,以及 Bugfix 等等,我們都需要和開源框架 Gin 做聯合開發和維護,這個周期不能完全由我們自己控制。

代碼混亂膨脹、維護困難

由于我們和業務同學共同開發和維護 Ginex 框架,因此我們對于控制整個框架的走向沒有完全的自主權,從而導致了整體代碼混亂膨脹,到后期我們發現越來越難維護。

無法滿足性能敏感業務需求

另外,我們能用 Gin 做的性能優化非常少,因為 Gin 的底層是基于 Golang 的一個原生庫,所以如果我們要做優化,需要在原生庫的基礎上做很多改造,這個其實是非常困難的。

無法滿足不同場景的功能需求

我們內部逐漸出現了一些新的場景,因此會有對 HTTP Client 的需求,支持 Websocket、支持 HTTP/2 以及支持 HTTP/3 等等需求,而在原生的 Ginex 上還是很難擴展的這些功能需求。

圖片

1.3 魔改開源框架

逐漸地,某些業務線開始做初步的嘗試,他們會對另外的一些開源框架進行魔改。比較典型的例子是有一些業務線嘗試基于 Fasthttp 進行魔改,Fasthttp 是一款主打高性能的開源框架,基于它進行魔改可以短期內幫助業務解決問題。這種魔改現象帶來的問題是,框架魔改是一些業務線自發的行為,各個業務線可能會基于自身業務特性進行各自維護,從而導致維護成本上升非常嚴重。

到這里我們仿佛陷入了 Ginex 的怪圈。如前段時間爆火的電視劇《開端》一樣,我們仿佛是從一輛開往學院南路的 45 路公交車上醒來,發現自己要前往公司進行下一代 Ginex 框架的維護工作。

大家也可以思考一下,如果是你來應對這樣的場景,你會怎么做呢?

圖片

1.4 小結

第一章節的內容總結如下:

早期基于開源框架封裝

基于早期開源的 Golang HTTP 框架,實現了 Ginex 的封裝。

隨著實踐發展,問題逐漸出現

框架混亂膨脹,框架的維護越來越困難,業務的新需求無法得到很好地滿足。

為了解決問題出現基于另外的開源框架魔改的萌芽

我們需要思考如何跳出魔改的怪圈,把字節內部的企業級框架做得更好。

另外,還有一個遺留問題,就是應該如何跳出這個魔改的怪圈呢?這個問題第二章節會為大家進行解答。

2. 企業級 HTTP 框架的設計考量和落地思路

2.1 跳出怪圈

為了跳出魔改的怪圈,我們決定從以下三個方面開始著手。

自主研發

既然 Ginex 是因為基于開源框架 Gin,沒法做一些靈活的控制,那我們就改為完全自主研發框架。自主研發框架的代碼全鏈路自主可控,也可以避免引入任何三方不可控因素,這樣我們能夠對自己的框架有一個比較完備的掌控力。

質量控制

下圖列舉了一些常規的質量控制手段。我要著重強調的是模糊測試,模糊測試在字節內部是廣泛應用于 Hertz 框架的穩定性測試中。它的核心點在于通過一系列的模擬服務,嘗試模擬出線上用戶在使用我們的框架時,實際遇到的一些場景和使用方式。然后通過一些隨機的算法,生成盡可能復雜、覆蓋各種 Case 的場景,這可以讓我們檢測出一些潛在的問題。這套測試也在 Hertz 早期的質量建設中,幫助我們將一些問題防患于未然。

嚴格準入

既然 Ginex 的問題是大家都在向里面寫入內容,那么我們可以控制入口,建立一套完備的需求開發以及 Review 的閉環,控制迭代的整體流程,從而控制代碼準入。同時我們配備統一的需求管理以及嚴格的發版準入規范,做一個標準的公司級別的框架。

圖片

舉一個比較形象的例子,如果我們把下一代框架比作一個人——“框架人”,自主研發表示這個“框架人”首先會擁有對自己身體的主導權,他不會受到來自于環境或者他人的影響;質量控制表示“框架人”能夠定期體檢,提早發現一些潛在的疾病,將其扼殺于搖籃;嚴格準入表示“框架人”有科學的飲食攝入和自律的生活習慣。可想而知,如果我們能夠做到以上三點,我們的“框架人”就能夠擁有一個健康的體魄。

2.2 痛點梳理

明確了應該如何跳出怪圈之后,我們還應該明確知道這個框架要具備哪些功能和特性,也就是首先應該聚焦到框架的核心痛點上。“框架人”不能只有健康的體魄,還應該擁有有趣的思想和靈魂。一個成熟的框架不僅僅要應對來自業務側的需求,如功能需求、性能需求和易用穩定等,還要考慮框架自身的發展,而這一點恰恰是我們在 Ginex 的迭代過程中忽略的。

如下圖右側金字塔所示,最上層是高效支撐,毋庸置疑框架的存在肯定是為了支撐我們的業務需求。中間層是一個質量保證的紅線框架,框架需要保證它自身的質量,只有以高質量完成的框架才能有自信承擔字節內部的 5000 萬 QPS,以及各種各樣的使用場景。金字塔的最底層是長期、可持續性發展, 這也是作為未來想要保持持續迭代的框架最重要的一點。

圖片

2.3 框架科學發展觀

基于上一部分,我們可以進一步梳理出框架的需求痛點。痛點主要有兩個方面:

  • 多樣的需求:支撐支撐各個業務線及基礎設施 (橫向擴展性)。
  • 靈活的結構:貫穿HTTP生命周期的掌控力 (縱向模塊化)。

在此基礎上進一步抽象出框架的科學發展觀:

  • 聚類需求:面向通用能力展開設計。
  • 跳出局部:針對一些復雜問題,在更大范圍內尋求最優解。

圖片

后續我會針對這個科學發展觀進一步闡述 Hertz 究竟是如何實現的。

2.4 小結

第二章節的內容總結如下:

跳出怪圈

引入“框架人”的概念,幫助大家理解框架的自研、質量控制和嚴格準入。

痛點梳理

為“框架人”注入有趣的靈魂,框架需要應對來自業務側的多樣化需求,還要保證自己的可持續性發展。

框架科學發展觀

需求聚類,跳出局部。

3. Hertz 的核心特點

Hertz 框架是如何實現第二章節中提到的框架痛點和科學發展觀的呢?本章節將具體進行介紹。

3.1 分層抽象

首先介紹 Hertz 框架的架構設計。下圖是一個請求從建立、連接到完成的全過程。左側是 客戶端 ,右側是服務端,在我們發起鏈接建立請求之后,鏈接建立完成;之后客戶端發起請求到服務端,服務端進行路由處理,然后將路由導向業務邏輯處理;業務邏輯處理完畢后,服務端返回這個請求,完成一次 HTTP 請求的調用。

那么在這個過程中我們的框架到底做了哪些事情呢?從圖中不難發現,首先框架進行了鏈接處理,其次是協議處理,之后基于路由做了邏輯分發,即路由處理,最后做了業務邏輯處理。我們把框架做成一個結構之后會發現,這個結構包含的就是這四部分。

圖片

基于這個邏輯,我們可以看一下 Hertz 的整體架構圖。如下圖所示,從下往上看紅線框圈住的部分,可以發現這就是上文提到的請求建立的全過程。各層的能力及作用如下:

  • 傳輸層 Transport:抽象網絡接口;
  • 協議層 Protocol:解析請求,渲染響應編碼;
  • 路由層 Route:基于URL進行邏輯分發;
  • 應用層 Application:業務直接交互,出現大量 API。

我們可以看到圖中除了中間部分包含的四層,左右兩側各有兩列。右側是通用層 Common,主要負責提供通用能力、常用的日志接口、鏈路追蹤以及一些配置處理相關的能力等。左側是 Hertz 的代碼生成工具 Hz,又稱腳手架工具,它可以幫助我們在內部基于 IDL 快速地生成項目骨架,以加速業務迭代。

Hertz 的分層設計是能夠和代碼組織結構一一映射的。下圖是 Hertz 倉庫里面的代碼組織結構,可以看到根目錄下的 cmd 包里面存放著 Hz 工具,在 pkg 包下存放著上述主要四層以及通用層 Common。因此同學們看到架構設計圖之后,可以直接在 Github 學習 Hertz 的代碼。

Hertz: https://github.com/cloudwego/hertz

圖片

總體來說,Hertz 的架構設計理念就是 “簡潔有序,保證讓所有開發者輕松理解,在開發的過程中持續貫徹” 。

3.2 易用可擴展

那么基于 Hertz 的架構設計,應該如何展開易用性和可擴展性呢?下圖是 Hertz 架構主要四個層級的抽象。

應用層

應用層提供了一些通用能力,包括綁定請求、響應渲染、 服務發現 /注冊/ 負載均衡以及服務治理等等。其中,洋蔥模型中間件的核心目的是讓業務開發同學基于這個中間件快速地給業務邏輯進行擴展,擴展方式是可以在業務邏輯處理前和處理后分別插樁埋點做相應處理。一些比較有代表性的應用,包括日志打點、前置的安全檢測,都是通過洋蔥模型中間件進行處理的。

路由層

路由層也是非常通用的,主要提供靜態路由、參數路由、為路由配置優先級以及路由修復的能力,如果我們的路由層沒辦法滿足用戶需求,它還能支撐用戶做自定義路由的擴展。但實際應用中這些路由能力完全能夠滿足絕大多數用戶的需求。

協議層

Hertz 同時提供 HTTP/1.1 和 HTTP/2,HTTP/3 也是我們在建設中的能力,我們還會提供 Websocket 等 HTTP 相關的多協議支持,以及支持完全由業務決定的自定義協議層擴展。

傳輸層

目前我們已經內置了兩個高性能的傳輸層實現。一個是基于 CloudWeGo 開源的高性能網絡庫 Netpoll 的傳輸層擴展,另一個是支持基于標準庫的傳輸層擴展。此外,我們也同樣能支持在傳輸層上進行自定義傳輸層協議擴展。

下圖每一層中標紅的能力都能夠體現出,我們能夠在框架的任何一個分層上支撐用戶做最大程度的自由定制,這樣可以最大程度地滿足企業級內部用戶和潛在用戶的業務需求。如果同學們想要深入了解 Hertz,可以參考 CloudWeGo 官網的 Hertz 部分,上述所有內容均有具體描述。

官網:https://www.cloudwego.io/zh/docs/hertz/

圖片

3.3 性能探索

在性能方面,Hertz 又是如何在自主可控的范圍內做高性能探索的呢?

3.3.1 場景描述

熟悉 Hertz 代碼的同學會發現,我們的 HTTP/1.1 協議借鑒了一些 Fasthttp 的優化思路和手段。HTTP/1.1 協議中的 Header 為不定長數據段,往往需要解析到最后一行,才能夠確定是否完成解析。同時,為了減少系統調用次數,提升整體解析效率,涉及 IO 操作時,我們通常引入帶 buffer 的 IO 數據結構。如下圖所示,它的核心點是最下層的 buffer,buffer 是一個類似于一塊完整的內存空間,我們可以將 IO 讀到的數據放進這個空間做暫存。

圖片

3.3.2 bufio.Reader 的問題

這樣做出現的問題是,原生的 bufio.Reader 長度是固定的,請求的 Header 大小超出 buffer 長度后,.Peek()? 方法直接報錯 (ErrBufferFul),無法完成既定語義功能。

3.3.3 一些可能的解

對于上述問題,其實有一些可能的解決方法:

  • 直接利用 bufio.Reader 的局限當做 Feature,通過 buffer 大小作為 Header 大小的限制。如果超出這個大小,Header 直接解析報錯,這也是 Fasthttp 的做法。但實際上超出 buffer 長度后報錯會導致我們沒辦法處理這部分請求,從而導致框架功能受限。
  • header 解析帶狀態,暫存中間數據,通過在上層堆疊額外復雜度的方式突破 bufio 本身的限制。但是暫存中間態會涉及到一些內存的拷貝,必然會導致性能受限。

3.3.4 真實使用環境復雜多變

字節內部的使用場景非常多,我們不僅要支持各種業務線的開發,還要支持一些橫向的基礎組件。不同的業務,不同的場景,數據規模各異。如何成為通用且高效地解決 bufio.Reader 的問題成為 Hertz 面臨的內部重要挑戰。我們既然已經站在 Fasthttp 這個“巨人”的肩膀上了,能否往前再走一步呢?

答案是肯定的?;趦炔康氖褂脠鼍?,同時結合 Netpoll 的優勢,我們設計出了自適應 linked buffer,并且用它替代掉了原生的 bufio.Reader。從下圖可以看到,我們的 buffer 不再是一個固定長度的 buffer,而是一條鏈,這條鏈上的每一個 buffer 大小能夠根據線上真實請求進行動態擴縮容調整,同時搭配 Netpoll 中基于 LT 觸發的模型做數據預拷貝。從實施效果上來看,這個自適應調整能夠讓我們的業務方完全無感地支撐任何他們的業務特性。也是因為我們能夠將 buffer 進行動態擴縮容調整,從而能夠保證在協議層最大程度做到零拷貝協議解析, 這能夠帶來整體解析上的性能提升,時延也會更低。

圖片

3.3.5 針對 HTTP/1.1 進行中的優化

因為目前在字節內部 HTTP/1.1 還是一個比較主流的協議,所以我們基于 HTTP/1.1 做了很多嘗試。

首先是協議層探索。我們正在嘗試基于 Header Passer 的 重構,把解析 Header 的流程做得更高效。我們還嘗試了做一些傳輸層預解析,將一些比較固化的邏輯下沉到傳輸層做加速。

其次是傳輸層探索。這包括使用 writev 整合發送 Header & Body 達到減少系統調用次數的目的,以及通過新增接口整合 .Peek() + .Skip() 語義, 在內部提供一個更高效的實現。

3.3.6 Hertz Benchmark

下圖是 Benchmark 的開源數據。左側第一張圖是在同等的機器環境上,Hertz 和橫向的框架 Gin、Fasthttp 極限 QPS 比較情況,藍線是 Hertz 處于較高極限 QPS 的狀態。第二張圖是 TP99 時延狀態,第三張圖是 TP999 時延狀態,可以看到 Hertz 的整體時延是處于一個更低的水平上。

圖片

3.3.7 字節跳動服務網格控制面從 Gin 遷移至 Hertz

CloudWeGo 公眾號曾發布關于字節跳動服務網格控制面的文章,講述字節跳動服務網格從 Gin 框架遷移到 Hertz 的落地實踐。下圖是他們代碼展示的真實收益,從 Gin 框架替換成為 Hertz 框架后,CPU 流量從大概快到 4K 降到大約只有 2.5K,Goroutine 數量從 6w 降到不足 100 個,Goroutine 穩定性得到極大地提升。同時替換成 Hertz 后,框架相關的開銷已經基本消失,服務網格在線上穩定承載了超過 13M QPS 的流量。

字節跳動服務網格基于 Hertz 框架的實踐:https://mp.weixin.qq.com/s/koi9q_57Vk59YYtO9cyAFA

圖片

3.4 小結

第三章節的內容總結如下:

分層抽象

解構 HTTP 框架,分層解耦。

易用可擴展

提供了更豐富 API 和足夠靈活的拓展能力,在每一層抽象中都提供了一個足夠靈活的擴展能力應對可能的需求。

自主可控的高性能探索

自適應 buffer,零拷貝解析,未來將會進行更多的高性能探索。

4. 未來規劃和挑戰

我認為 Hertz 未來的發展規劃主要圍繞以下幾個方面:首先,打造泛 HTTP 框架。我們的最終目標是希望 Hertz 能夠解決在 HTTP 領域內的所有問題;其次,助力 CloudWeGo , 希望 Hertz 能夠助力 CloudWeGo 打造一個企業級云原生微服務矩陣;最后希望 Hertz 能夠持續服務更多的用戶。

5. 總結

本次分享的主要內容總結如下:

  • 字節跳動內部 Go HTTP 框架的變遷:從基于開源封裝,到開啟自研之路;
  • 企業級 HTTP 框架的設計考量和落地思路:破圈、需求提煉、框架科學發展觀;
  • Hertz 核心特點:分層抽象、易用可擴展、自主可控的性能探索;
  • Hertz 未來的規劃和挑戰:框架持續打磨、助力 CloudWeGo、服務更多用戶。
責任編輯:未麗燕 來源: 字節跳動技術團隊
相關推薦

2022-06-22 06:49:39

Hertz開源HTTP 框架

2024-11-07 11:46:41

2021-09-06 11:15:05

數據治理字節跳動埋點

2023-01-03 16:54:27

字節跳動深度學習

2023-11-20 07:27:00

云原生Spark

2024-11-13 11:02:03

微服務框架項目

2024-11-08 13:04:08

項目Hertz接口

2022-11-24 09:01:26

HTTPHertz架構

2024-11-26 19:29:35

2022-11-24 10:01:10

架構分布式

2024-09-25 15:57:56

2015-05-26 09:41:45

china-pub

2021-04-22 13:38:21

前端開發技術

2023-03-29 07:49:05

企業級項目研發

2022-06-02 16:58:06

Ray機器學習字節

2018-05-31 15:58:03

Leangoo

2009-03-02 09:22:39

OSGiJ2EEEclipse

2012-11-12 09:38:12

云計算實踐私有云金蝶系統

2014-08-07 09:48:40

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩在线欧美 | 久久成人免费 | 久久精品国内 | 亚洲久久一区 | 国产69久久精品成人看动漫 | 中文字幕av免费 | 国产综合久久久 | 久久久久久久久久久91 | 国产精品资源在线观看 | 久久激情五月丁香伊人 | av色站| 国产精品福利久久久 | 久久久久久久国产精品视频 | 亚洲欧美国产视频 | 中文字幕成人网 | 日韩欧美在线不卡 | 亚洲高清在线免费观看 | 午夜影院在线视频 | 91在线视频 | 久久久久国色av免费观看性色 | 国产精品国产自产拍高清 | 美女国产精品 | 国产免费一区二区 | av电影手机在线看 | 欧美性大战久久久久久久蜜臀 | 久久久久成人精品免费播放动漫 | 欧美一级一 | 狠狠操狠狠操 | 欧美日韩在线播放 | 欧美一级二级三级视频 | 夜夜艹| 国产在线精品一区二区三区 | 在线视频一区二区 | 天天人人精品 | 色久五月 | 九九色综合 | 男女av| 久久久久免费 | 超碰97在线免费 | 欧美一区二区三区视频 | 国产午夜精品一区二区三区四区 |