日前,字节跳动技术社区 ByteTech 举办的第七期字节跳动技术沙龙圆满落幕,本期沙龙以《字节高性能开源微服务框架:CloudWeGo》为主题。在沙龙中,字节跳动字节跳动基础架构服务框架资深研发工程师高文举,跟大家分享了《大规模企业级 HTTP 框架的设计和实践》,本文根据分享整理而成。
本文将从以下五个方面介绍 CloudWeGo 大规模企业级 HTTP 框架 Hertz:
1. 字节跳动内部 Go HTTP 框架的变迁;
2. 企业级 HTTP 框架的设计考量和落地思路;
3. Hertz 的核心特点;
4. 未来规划和挑战;
5. 总结。
字节跳动内部 Go HTTP 框架的变迁
在正式开始介绍第一部分的内容之前,先给大家展示一组关键词。2020 年初 Hertz 立项,2020 年 10 月,Hertz 发布第一个可用版本。2022 年 6 月,Hertz 正式开源。截至目前,Hertz 在字节内部已经支撑超过 1.4 万个业务服务,日峰值 QPS 超过 5000 万。
Hertz 不仅支持业务服务,同时还会横向支持字节内部的各种基础组件,包括但不限于字节跳动服务网格控制面、公司级别压测平台以及 FaaS,还包括各种业务网关等等。Hertz 的高性能和极强的稳定性可以支撑业务复杂多变的场景。在公司内部 Hertz 接替了大量基于 Gin 框架开发的存量服务,大幅度降低了业务资源使用成本以及服务延时,助力公司层面的降本增效。
下面我们可以从 Hertz 出现的背景以及 Hertz 的设计目标和思路体会到,Hertz 的出现绝不是偶然。
基于 Gin 封装
众所周知,字节内部使用 Golang 比较早,在大约 2014 年左右,公司就已经开始尝试做一些 Golang 业务的转型。2016 年,我们基于已开源的 Golang HTTP 框架 Gin 框架,封装了 Ginex,这是 Ginex 刚开始出现的时期。
同时,2016 年还是一个开荒的时代,这个时期框架伴随着业务快速野蛮地生长,我们的口号是“大力出奇迹”,把优先解决业务需求作为第一要务。Ginex 的迭代方式是业务侧和框架侧在同一个仓库里面共同维护和迭代。
问题显现
2017 - 2019 年期间,也就是 Ginex 发布之后,问题逐渐显现。主要有以下几点:
-
迭代受开源项目限制
Ginex 是一个基于 Gin 的开源封装,所以它本身在迭代方面是受到一些限制的。一旦有针对公司级的需求开发,以及 Bugfix 等等,我们都需要和开源框架 Gin 做联合开发和维护,这个周期不能完全由我们自己控制。
-
代码混乱膨胀、维护困难
由于我们和业务同学共同开发和维护 Ginex 框架,因此我们对于控制整个框架的走向没有完全的自主权,从而导致了整体代码混乱膨胀,到后期我们发现越来越难维护。
-
无法满足性能敏感业务需求
另外,我们能用 Gin 做的性能优化非常少,因为 Gin 的底层是基于 Golang 的一个原生库,所以如果我们要做优化,需要在原生库的基础上做很多改造,这个其实是非常困难的。
-
无法满足不同场景的功能需求
我们内部逐渐出现了一些新的场景,因此会有对 HTTP Client 的需求,支持 Websocket、支持 HTTP/2 以及支持 HTTP/3 等等需求,而在原生的 Ginex 上还是很难扩展的这些功能需求。
魔改开源框架
逐渐地,某些业务线开始做初步的尝试,他们会对另外的一些开源框架进行魔改。比较典型的例子是有一些业务线尝试基于 Fasthttp 进行魔改,Fasthttp 是一款主打高性能的开源框架,基于它进行魔改可以短期内帮助业务解决问题。这种魔改现象带来的问题是,框架魔改是一些业务线自发的行为,各个业务线可能会基于