前言Hertz 是字节跳动服务框架团队研发的超大规模的企业级微服务 HTTP 框架,具有高易用性、易扩展、低时延等特点 。在经过了字节跳动内部一年多的使用和迭代,如今已在 CloudWeGo 正式开源 。目前,Hertz 已经成为了字节跳动内部最大的 HTTP 框架,线上接入的服务数量超过 1 万,峰值 QPS 超过 4 千万 。除了各个业务线的同学使用外,也服务于内部很多基础组件,如:函数计算平台 FaaS、压测平台、各类网关、Service Mesh 控制面等,均收到不错的使用反馈 。在如此大规模的场景下,Hertz 拥有极强的稳定性和性能,在内部实践中某些典型服务,如框架占比较高的服务、网关等服务,迁移 Hertz 后相比 Gin 框架,资源使用显著减少,CPU 使用率随流量大小降低 30%-60%,时延也有明显降低 。
Hertz 坚持内外维护一套代码,为开源使用提供了强有力的保障 。通过开源,Hertz 也将丰富云原生的 Golang 中间件体系,完善 CloudWeGo 生态矩阵,为更多开发者和企业搭建云原生化的大规模分布式系统,提供一种现代的、资源高效的的技术方案 。
本文将重点关注 Hertz 的架构设计与功能特性 。
项目缘起最初,字节跳动内部的 HTTP 框架是对 Gin 框架的封装,具备不错的易用性、生态完善等优点 。随着内部业务的不断发展,高性能、多场景的需求日渐强烈 。而 Gin 是对 Golang 原生 net/http 进行的二次开发,在按需扩展和性能优化上受到很大局限 。因此,为了满足业务需求,更好的服务各大业务线,2020 年初,字节跳动服务框架团队经过内部使用场景和外部主流开源 HTTP 框架 Fasthttp、Gin、Echo 的调研后,开始基于自研网络库 Netpoll 开发内部框架 Hertz,让 Hertz 在面对企业级需求时,有更好的性能及稳定性表现,也能够满足业务发展和应对不断演进的技术需求 。
架构设计【字节跳动开源 Go HTTP 框架 Hertz 设计实践】Hertz 设计之初调研了大量业界优秀的 HTTP 框架,同时参考了近年来内部实践中积累的经验 。为了保证框架整体上满足:1. 极致性能优化的可能性;2. 面对未来不可控需求的扩展能力,Hertz 采用了 4 层分层设计,保证各个层级功能内聚,同时通过层级之间的接口达到灵活扩展的目标 。整体架构图如图 1 所示 。
文章插图
图 1:Hertz 架构图
Hertz 从上到下分为:应用层、路由层、协议层和传输层,每一层各司其职,同时公共能力被统一抽象到公共层(common),做到跨层级复用 。另外,同主库一同发布的还有作为子模块的 Hz 脚手架,它能够协助使用者快速搭建出项目核心骨架以及提供实用的构建工具链 。
应用层应用层是和用户直接交互的一层,提供丰富易用的 API,主要包括 Server、Client 和一些其他通用抽象 。Server 提供了注册 HandlerFunc、Binding、Rendering 等能力;Client 提供了调用下游和服务发现等能力;以及抽象一个 HTTP 请求所必须涉及到的请求(Request)、响应(Response)、上下文(RequestContext)、中间件(Middleware)等等 。Hertz 的 Server 和 Client 都能够提供中间件这样的扩展能力 。
应用层中一个非常重要的抽象就是对 Server HandlerFunc 的抽象 。早期,Hertz 路由的处理函数 (HandlerFunc)中并没有接收标准的 context.Context,我们在大量的实践过程中发现,业务方通常需要一个标准的上下文在 RPC Client 或者日志、Tracing 等组件间传递,但由于请求上下文(RequestContext)生命周期局限于一次 HTTP 请求之内,而以上提到的场景往往存在异步的传递和处理,导致如果直接传递请求上下文,会导致出现一些数据不一致的问题 。为此我们做了诸多尝试,但是因为核心原因在于请求上下文(RequestContext)的生命周期无法优雅的按需延长,最终在各种设计权衡下,我们在路由的处理函数签名中增加一个标准的上下文入参,通过分离出生命周期长短各异的两个上下文的方式,从根本上解决各种因为上下文生命周期不一致导致的异常问题,即:
type HandlerFunc func(c context.Context, ctx *App.RequestContext)
路由层路由层负责根据 URI 匹配对应的处理函数 。起初,Hertz 的路由基于 httprouter 开发,但随着使用的用户越来越多,httprouter 渐渐不能够满足需求,主要体现在 httprouter 不能够同时注册静态路由和参数路由,即 /a/b,/:c/d 这两个路由不能够同时注册;甚至有一些更特殊的需求,如/a/b、/:c/b ,当匹配 /a/b 路由时,两个路由都能够匹配上 。
推荐阅读
- RustDesk - 免费开源的远程控制软件,流畅不限速,代替TeamViewer
- 抖音国际版起诉特朗普胜算几何-tiktok计划起诉特朗普政府-字节跳动将正式起诉特朗普政府
- 字节跳动将正式起诉特朗普政府-字节跳动起诉美国政府-字节跳动起诉美国政府有用吗
- 字节跳动将正式起诉特朗普政府-字节跳动为什么被美国制裁
- 字节跳动回应若不公正对待将起诉-字节跳动回应美国总统令
- 字节跳动回应:若不公正对待将起诉-若不公正对待诉诸美国法院
- 房颤和房扑哪个严重
- 字节否认微软求购TikTok全球业务-字节否认微软求购
- node-xlsx 简单几行代码处理导入导出 excel 数据,免费开源的 js 库
- 字节跳动将TikTok总部迁至伦敦-TikTok总部设在伦敦