共计 3319 个字符,预计需要花费 9 分钟才能阅读完成。
2021 年 9 月 8 日,字节跳动发表正式开源 CloudWeGo。CloudWeGo 是一套字节跳动外部微服务中间件汇合,具备 高性能、强扩展性和稳定性 的特点,专一于解决微服务通信与治理的难题,满足不同业务在不同场景的诉求。2022 年 6 月 21 日,Hertz 正式开源。
日前,CloudWeGo 团队正式开源字节跳动最大的 HTTP 框架 Hertz。Hertz 在公布之后失去了大量用户的关注,开源四个月以来,Hertz 曾经播种了 2K+ star。有很多用户本人进行了测试,感激社区对咱们的关注和反对。
本文旨在分享开发者在压测 Hertz 时须要理解的场景和技术问题。这些倡议有助于用户更好地联合实在 HTTP 场景对 Hertz 进行调优,使之更贴合业务须要、施展最佳性能。用户也能够参考官网提供的压测我的项目 hertz-benchmark 理解更多细节。
hertz-benchmark: https://github.com/cloudwego/…
01 微服务 HTTP 场景的特点
Hertz 诞生于字节跳动大规模微服务架构实际,面向的场景天然是微服务场景,因而上面会先介绍微服务 HTTP 场景的特点,不便开发者深刻了解 Hertz 在其中的设计思考。
- HTTP 通信模型
微服务间的通信通常以 Ping-Pong 模型为主,除了惯例的吞吐性能指标外,每次 HTTP 的 均匀时延 也是开发者须要思考的点。吞吐达到瓶颈时能够通过减少机器疾速解决,但对用户应用体验有显著影响的时延却没有那么容易升高。在微服务场景下,一次调用往往须要多个微服务合作实现,即便每个节点提早很低,最终汇聚到链路上的时延也会被放大,因而微服务场景下时延指标是开发者更应该关注的点。Hertz 在保障吞吐的前提下,也针对时延做了肯定优化。
- 长短连贯应用
因为 TCP 连贯首次建设时须要三次握手,如果每个申请都建设新连贯,这部分的开销是十分大的。因而对于时延敏感型服务,尽量应用长连贯实现申请。在 HTTP 1.1 中,长连贯也是默认的选项。然而没有银弹,维持连贯也须要耗费资源,长连贯的程度扩大能力也不如短连贯。因而,在某些场景下并不适宜应用长连贯,比方定时拉取配置的场景,在这个场景下,建连时延对配置影响并不大,且当配置核心负载过高时,心愿可能不便的进行程度扩容,这时短连贯可能是一个更好的抉择。
- 包体积大小
一个服务的包大小取决于理论的业务场景。HTTP 场景的数据能够放在 query、path、header、body 等中央,不同地位对解析造成的影响也不一样。HTTP 的 header 是标识符协定,在没有找到特定的标识符之前,框架并不知道 header 还有多少,因而框架须要收到全副的 header 后才可能解析实现,对框架的内存模型不很敌对。Hertz 也针对 header 解析做了非凡的优化,调配足够的 buffer 空间给 header,缩小 header 解决时跨包拷贝的开销。
同时在字节跳动外部线上服务的统计中,发现大部分包在 1K 以内(然而太小的包没有实际意义,比方固定返回 “hello world”),同时大包场景上不封顶,各个包大小均有波及,所以 Hertz 在最罕用的 128k 以内的包的性能(吞吐和时延)进行了重点优化。
- 并发数量
每个实例的上游可能会有很多个,不会只承受某个实例的申请;而且,HTTP 1 的连贯不可能多路复用,每条连贯上只能同时解决一个申请。因而 Server 须要承受多个连贯同时解决。不同服务的连贯使用率也不同,比方压测服务的连贯使用率很高,一个申请实现后马上就会进行下一个申请;有的服务连贯使用率很低,尽管是长连贯,然而只应用一次。这两者应用的连贯模型并不相同,前者应应用 goroutine per connection 的模型缩小上下文的切换,后者应应用协程池缩小过多 goroutine 的调度开销。Hertz 也同时反对这两种场景,用户能够依据本人的业务场景抉择适合的配置。
02 针对 HTTP 场景进行压测
应用贴近本人的场景
Github 上的压测我的项目有很多,网络上也有很多性能测试报告,然而这些我的项目和测试不肯定贴合本人。举个极其一点的例子,在实在场景中你会写一个我的项目无论 Client 发什么 Server 都只回 hello world
吗?很遗憾,很多的压测我的项目就是这么做的。
在进行压测前,应思考本人真正的应用场景,比方:
- 长短连贯的应用:应用长连贯还是短连贯更合乎本人的场景。
- 连贯使用率的估算:如果应用长连贯,且连贯使用率很高(大部分场景),则应用默认配置即可;如果连贯使用率很低,能够增加配置:
server.WithIdleTimeout(0)
,将 goroutine per connection 的模型批改为协程池模型,并进行比照测试。 - 数据地位及大小的确定:下面提到不同地位(如 query、header、body 等)及大小的数据对框架可能造成影响,如果所有框架的性能都比拟个别,能够思考换一个数据传输地位。
- 并发数的确定:有的服务属于轻业务重框架,这个时候框架的并发可能会很高;有的服务属于重业务轻框架,这个时候框架的并发可能会很低。
如果只是想看一下框架的性能,能够应用惯例的场景:长连贯、较高连贯使用率、1k body、100 并发 等。hertz-benchmark 仓库默认的压测配置也是如此。同时 hertz-benchmark 仓库也开发给用户 header、body、并发数的配置,用户能够不便的批改这些配置实现贴合本人的压测。
确定压测对象
掂量一个 RPC 框架的性能须要从两个视角别离去思考:Client 视角与 Server 视角。在大规模的业务架构中,上游 Client 不见得应用的也是上游的框架,而开发者调用的上游服务也同样如此,如果再思考到 Service Mesh 的状况就更简单了。
一些压测我的项目通常会把 Client 和 Server 过程混部进行压测,而后得出 整个框架 的性能数据,这其实和线上理论运行状况很可能是不符的。
如果要压测 Server,应该给 Client 尽可能多的资源,把 Server 压到极限,反之亦然。如果 Client 和 Server 都只给了 4 核 CPU 进行压测,会导致开发者无奈判断最终得进去的性能数据是哪个视角下的,更无奈给线上服务做理论的参考。
应用独占 CPU
尽管线上利用通常是多个过程共享 CPU,但在压测场景下,Client 与 Server 过程都处于极其忙碌的情况,此时共享 CPU 会导致大量上下文切换,从而使得数据不足可参考性,且容易产生前后很大稳定。
所以咱们倡议是将 Client 与 Server 过程隔离在不同 CPU 或者不同独占机器上进行。如果还想要进一步防止其余过程产生影响,能够再加上 nice -n -20 命令调低压测过程的调度优先级。
另外如果条件容许,相比云平台虚拟机,应用实在物理机会使得测试后果更加谨严与具备可复现性。
03 性能数据
参考在满足上述要求的前提下,咱们基于以后最新版本对多个框架进行了压测比照,压测代码在 hertz-benchmark 仓库。在充沛压满 Server 的指标下,Hertz 的 P99 提早在所有压测框架中最低,吞吐也是属于第一梯队,且在继续优化中。
CPU: AMD EPYC 7Y83 64-Core Processor 2.7GHz
- 运行限定 server 4-CPUs,client 16-CPUS
- OS:Debian GNU/Linux 10 (buster)
- Go 1.19
- hertz v0.3.2,fasthttp v1.40.0,gin v1.8.1,fiber v2.38.1
四个框架的吞吐和时延比拟
三个框架的吞吐和时延比拟
04 结语
Hertz 作为一个超大规模企业级的微服务 HTTP 框架,其在设计之初就更偏向于解决大规模微服务场景下的各种问题。在推广过程中也遇到了各种各样的服务,踩了各种各样的坑,也是基于这些服务和遇到的问题写了本文。欢送宽广开发者基于本文提供的测试指南,针对本人的理论场景抉择适合的工具。更多问题,请在 GitHub 上提 Issue 交换。
我的项目地址
GitHub:https://github.com/cloudwego
官网:www.cloudwego.io
CSG 三期:https://mp.weixin.qq.com/s/vw…