“日前,字节跳动技术社区 ByteTech 举办的第七期字节跳动技术沙龙圆满落幕,本期沙龙以《字节高性能开源微服务框架:CloudWeGo》为主题。在沙龙中,字节跳动字节跳动基础架构服务框架资深研发工程师 高文举,跟大家分享了《大规模企业级 HTTP 框架的设计和实践》,本文根据分享整理而成。
本文将从以下五个方面介绍 CloudWeGo 大规模企业级 HTTP 框架 Hertz:
在正式开始介绍第一部分的内容之前,先给大家展示一组关键词。2020 年初 Hertz 立项,2020 年 10 月,Hertz 发布第一个可用版本。2022 年 6 月,Hertz 正式开源。 截至目前,Hertz 在字节内部已经支撑超过 1.4 万个业务服务,日峰值 QPS 超过 5000 万。
Hertz 不仅支撑业务服务,同时还会横向支撑字节内部的各种基础组件,包括但不限于字节跳动服务网格控制面、公司级别压测平台以及 FaaS,还包括各种业务网关等等。Hertz 的高性能和极强的稳定性可以支撑业务复杂多变的场景。在公司内部 Hertz 接替了大量基于 Gin 框架开发的存量服务,大幅度降低了业务资源使用成本以及服务延时,助力公司层面的降本增效。
下面我们可以从 Hertz 出现的背景以及 Hertz 的设计目标和思路体会到,Hertz 的出现绝不是偶然。
众所周知,字节内部使用 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 是一款主打高性能的开源框架,基于它进行魔改可以短期内帮助业务解决问题。这种魔改现象带来的问题是,框架魔改是一些业务线自发的行为,各个业务线可能会基于自身业务特性进行各自维护,从而导致维护成本上升非常严重。
到这里我们仿佛陷入了 Ginex 的怪圈。如前段时间爆火的电视剧《开端》一样,我们仿佛是从一辆开往学院南路的 45 路公交车上醒来,发现自己要前往公司进行下一代 Ginex 框架的维护工作。
大家也可以思考一下,如果是你来应对这样的场景,你会怎么做呢?
第一章节的内容总结如下:
基于早期开源的 Golang HTTP 框架,实现了 Ginex 的封装。
框架混乱膨胀,框架的维护越来越困难,业务的新需求无法得到很好地满足。
我们需要思考如何跳出魔改的怪圈,把字节内部的企业级框架做得更好。
另外,还有一个遗留问题,就是应该如何跳出这个魔改的怪圈呢?这个问题第二章节会为大家进行解答。
为了跳出魔改的怪圈,我们决定从以下三个方面开始着手。
既然 Ginex 是因为基于开源框架 Gin,没法做一些灵活的控制,那我们就改为完全自主研发框架。自主研发框架的代码全链路自主可控,也可以避免引入任何三方不可控因素,这样我们能够对自己的框架有一个比较完备的掌控力。
下图列举了一些常规的质量控制手段。我要着重强调的是模糊测试,模糊测试在字节内部是广泛应用于 Hertz 框架的稳定性测试中。它的核心点在于通过一系列的模拟服务,尝试模拟出线上用户在使用我们的框架时,实际遇到的一些场景和使用方式。然后通过一些随机的算法,生成尽可能复杂、覆盖各种 Case 的场景,这可以让我们检测出一些潜在的问题。这套测试也在 Hertz 早期的质量建设中,帮助我们将一些问题防患于未然。
既然 Ginex 的问题是大家都在向里面写入内容,那么我们可以控制入口,建立一套完备的需求开发以及 Review 的闭环,控制迭代的整体流程,从而控制代码准入。同时我们配备统一的需求管理以及严格的发版准入规范,做一个标准的公司级别的框架。
举一个比较形象的例子,如果我们把下一代框架比作一个人——“框架人”,自主研发表示这个“框架人”首先会拥有对自己身体的主导权,他不会受到来自于环境或者他人的影响;质量控制表示“框架人”能够定期体检,提早发现一些潜在的疾病,将其扼杀于摇篮;严格准入表示“框架人”有科学的饮食摄入和自律的生活习惯。可想而知,如果我们能够做到以上三点,我们的“框架人”就能够拥有一个健康的体魄。
明确了应该如何跳出怪圈之后,我们还应该明确知道这个框架要具备哪些功能和特性,也就是首先应该聚焦到框架的核心痛点上。“框架人”不能只有健康的体魄,还应该拥有有趣的思想和灵魂。一个成熟的框架不仅仅要应对来自业务侧的需求,如功能需求、性能需求和易用稳定等,还要考虑框架自身的发展,而这一点恰恰是我们在 Ginex 的迭代过程中忽略的。
如下图右侧金字塔所示,最上层是高效支撑,毋庸置疑框架的存在肯定是为了支撑我们的业务需求。中间层是一个质量保证的红线框架,框架需要保证它自身的质量,只有以高质量完成的框架才能有自信承担字节内部的 5000 万 QPS,以及各种各样的使用场景。金字塔的最底层是长期、可持续性发展, 这也是作为未来想要保持持续迭代的框架最重要的一点。
基于上一部分,我们可以进一步梳理出框架的需求痛点。痛点主要有两个方面:
多样的需求:支撑支撑各个业务线及基础设施 (横向扩展性)。
灵活的结构:贯穿HTTP生命周期的掌控力 (纵向模块化)。
在此基础上进一步抽象出框架的科学发展观:
聚类需求:面向通用能力展开设计。
跳出局部:针对一些复杂问题,在更大范围内寻求最优解。
后续我会针对这个科学发展观进一步阐述 Hertz 究竟是如何实现的。
第二章节的内容总结如下:
引入“框架人”的概念,帮助大家理解框架的自研、质量控制和严格准入。
为“框架人”注入有趣的灵魂,框架需要应对来自业务侧的多样化需求,还要保证自己的可持续性发展。
需求聚类,跳出局部。
Hertz 框架是如何实现第二章节中提到的框架痛点和科学发展观的呢?本章节将具体进行介绍。
首先介绍 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 的架构设计理念就是 “简洁有序,保证让所有开发者轻松理解,在开发的过程中持续贯彻” 。
那么基于 Hertz 的架构设计,应该如何展开易用性和可扩展性呢?下图是 Hertz 架构主要四个层级的抽象。
应用层提供了一些通用能力,包括绑定请求、响应渲染、 服务发现 /注册/ 负载均衡以及服务治理等等。其中,洋葱模型中间件的核心目的是让业务开发同学基于这个中间件快速地给业务逻辑进行扩展,扩展方式是可以在业务逻辑处理前和处理后分别插桩埋点做相应处理。一些比较有代表性的应用,包括日志打点、前置的安全检测,都是通过洋葱模型中间件进行处理的。
路由层也是非常通用的,主要提供静态路由、参数路由、为路由配置优先级以及路由修复的能力,如果我们的路由层没办法满足用户需求,它还能支撑用户做自定义路由的扩展。但实际应用中这些路由能力完全能够满足绝大多数用户的需求。
Hertz 同时提供 HTTP/1.1 和 HTTP/2,HTTP/3 也是我们在建设中的能力,我们还会提供 Websocket 等 HTTP 相关的多协议支持,以及支持完全由业务决定的自定义协议层扩展。
目前我们已经内置了两个高性能的传输层实现。一个是基于 CloudWeGo 开源的高性能网络库 Netpoll 的传输层扩展,另一个是支持基于标准库的传输层扩展。此外,我们也同样能支持在传输层上进行自定义传输层协议扩展。
下图每一层中标红的能力都能够体现出,我们能够在框架的任何一个分层上支撑用户做最大程度的自由定制,这样可以最大程度地满足企业级内部用户和潜在用户的业务需求。如果同学们想要深入了解 Hertz,可以参考 CloudWeGo 官网的 Hertz 部分,上述所有内容均有具体描述。
官网:https://www.cloudwego.io/zh/docs/hertz/
在性能方面,Hertz 又是如何在自主可控的范围内做高性能探索的呢?
熟悉 Hertz 代码的同学会发现,我们的 HTTP/1.1 协议借鉴了一些 Fasthttp 的优化思路和手段。HTTP/1.1 协议中的 Header 为不定长数据段,往往需要解析到最后一行,才能够确定是否完成解析。同时,为了减少系统调用次数,提升整体解析效率,涉及 IO 操作时,我们通常引入带 buffer 的 IO 数据结构。如下图所示,它的核心点是最下层的 buffer,buffer 是一个类似于一块完整的内存空间,我们可以将 IO 读到的数据放进这个空间做暂存。
这样做出现的问题是,原生的 bufio.Reader 长度是固定的,请求的 Header 大小超出 buffer 长度后,.Peek()
方法直接报错 (ErrBufferFul)
,无法完成既定语义功能。
对于上述问题,其实有一些可能的解决方法:
直接利用 bufio.Reader 的局限当做 Feature,通过 buffer 大小作为 Header 大小的限制。如果超出这个大小,Header 直接解析报错,这也是 Fasthttp 的做法。但实际上超出 buffer 长度后报错会导致我们没办法处理这部分请求,从而导致框架功能受限。
header 解析带状态,暂存中间数据,通过在上层堆叠额外复杂度的方式突破 bufio 本身的限制。但是暂存中间态会涉及到一些内存的拷贝,必然会导致性能受限。
字节内部的使用场景非常多,我们不仅要支持各种业务线的开发,还要支持一些横向的基础组件。不同的业务,不同的场景,数据规模各异。如何成为通用且高效地解决 bufio.Reader 的问题成为 Hertz 面临的内部重要挑战。我们既然已经站在 Fasthttp 这个“巨人”的肩膀上了,能否往前再走一步呢?
答案是肯定的。基于内部的使用场景,同时结合 Netpoll 的优势,我们设计出了自适应 linked buffer,并且用它替代掉了原生的 bufio.Reader。从下图可以看到,我们的 buffer 不再是一个固定长度的 buffer,而是一条链,这条链上的每一个 buffer 大小能够根据线上真实请求进行动态扩缩容调整,同时搭配 Netpoll 中基于 LT 触发的模型做数据预拷贝。从实施效果上来看,这个自适应调整能够让我们的业务方完全无感地支撑任何他们的业务特性。也是因为我们能够将 buffer 进行动态扩缩容调整,从而能够保证在协议层最大程度做到零拷贝协议解析, 这能够带来整体解析上的性能提升,时延也会更低。
因为目前在字节内部 HTTP/1.1 还是一个比较主流的协议,所以我们基于 HTTP/1.1 做了很多尝试。
首先是协议层探索。我们正在尝试基于 Header Passer 的 重构,把解析 Header 的流程做得更高效。我们还尝试了做一些传输层预解析,将一些比较固化的逻辑下沉到传输层做加速。
其次是传输层探索。这包括使用 writev 整合发送 Header & Body 达到减少系统调用次数的目的,以及通过新增接口整合 .Peek() + .Skip()
语义, 在内部提供一个更高效的实现。
下图是 Benchmark 的开源数据。左侧第一张图是在同等的机器环境上,Hertz 和横向的框架 Gin、Fasthttp 极限 QPS 比较情况,蓝线是 Hertz 处于较高极限 QPS 的状态。第二张图是 TP99 时延状态,第三张图是 TP999 时延状态,可以看到 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
第三章节的内容总结如下:
解构 HTTP 框架,分层解耦。
提供了更丰富 API 和足够灵活的拓展能力,在每一层抽象中都提供了一个足够灵活的扩展能力应对可能的需求。
自适应 buffer,零拷贝解析,未来将会进行更多的高性能探索。
我认为 Hertz 未来的发展规划主要围绕以下几个方面:首先,打造泛 HTTP 框架。我们的最终目标是希望 Hertz 能够解决在 HTTP 领域内的所有问题;其次,助力 CloudWeGo , 希望 Hertz 能够助力 CloudWeGo 打造一个企业级云原生微服务矩阵;最后希望 Hertz 能够持续服务更多的用户。
本次分享的主要内容总结如下:
字节跳动内部 Go HTTP 框架的变迁:从基于开源封装,到开启自研之路;
企业级 HTTP 框架的设计考量和落地思路:破圈、需求提炼、框架科学发展观;
Hertz 核心特点:分层抽象、易用可扩展、自主可控的性能探索;
Hertz 未来的规划和挑战:框架持续打磨、助力 CloudWeGo、服务更多用户。
最后欢迎对 Hertz 感兴趣的同学积极参与到 CloudWeGo 社区中,我们一起完善 Hertz,共同建设 CloudWeGo!
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/GD384TxZ-tTQDNT4LcH5Fg
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。