当前位置: 首页 > 科技观察

HTTP框架赫兹实战介绍:性能测试指南

时间:2023-03-14 17:19:28 科技观察

2021年9月8日,字节跳动宣布正式开源CloudWeGo。CloudWeGo是字节跳动内部微服务中间件的集合,具有高性能、强扩展性和稳定性等特点。专注于解决微服务通信和治理问题,满足不同业务在不同场景下的需求。2022年6月21日,赫兹将正式开源。Hertz链接:https://github.com/cloudwego/hertz,欢迎大家参与建设^_^日前,CloudWeGo团队正式开源了字节跳动最大的HTTP框架Hertz。赫兹自发布以来就受到了用户的广泛关注。开源四个月以来,Hertz获得了2k+star。有很多用户亲自测试过,感谢社区的关注和支持。本文旨在分享开发者在压测Hertz时需要了解的场景和技术问题。这些建议帮助用户更好地结合真实HTTP场景对Hertz进行调优,使其更贴合业务需求,发挥最佳性能。用户也可以参考官方压力测试项目hertz-benchmark[1]了解更多详情。一、微服务HTTP场景特点Hertz诞生于字节跳动大规模的微服务架构实践。面向的场景自然是微服务场景。因此,下面将首先介绍微服务HTTP场景的特点,让开发者在其中深入了解Hertz。设计思维。HTTP通信模型微服务之间的通信通常基于Ping-Pong模型。除了常规的吞吐量性能指标外,每个HTTP的平均延迟也是开发者需要考虑的一个点。当吞吐量达到瓶颈时,可以通过增加机器来快速解决,但是对用户体验影响很大的延迟却不是那么容易降低的。在微服务场景下,往往需要多个微服务协同完成单个调用。即使每个节点的延迟都很低,最终收敛到链路的延迟也会被放大。因此,微服务场景下的延迟指标是开发者更应该关注的一个点。在保证吞吐量的前提下,Hertz还针对延迟做了一些优化。使用长连接和短连接需要在第一次建立TCP连接时进行三次握手。如果每次请求都建立一个新的连接,这部分开销是非常大的。因此,对于延迟敏感的业务,尽量使用长连接来完成请求。在HTTP1.1中,长连接也是默认选项。但是没有灵丹妙药,维护连接需要消耗资源,而且长连接的水平扩展能力不如短连接。所以有些场景不适合使用长连接,比如定时拉取配置的场景。在这种场景下,连接建立延迟对配置的影响不大,而当配置中心负载过高时,希望能够方便的进行水平扩展,短连接可能是更好的选择。PackageSize服务的包大小取决于实际的业务场景。HTTP场景下的数据可以放在query、path、header、body等位置,不同的位置对解析有不同的影响。HTTP标头是一种标识符协议。在找到特定标识符之前,框架不知道有多少个标头。因此框架需要接收到所有的headers才能完成解析,这对框架的内存模型不是很友好。赫兹还对头部解析做了专门的优化,为头部分配足够的缓冲空间,减少头部处理过程中跨包复制的开销。同时,在字节跳动内部在线服务的统计中,发现大部分包都在1K以内(但是太小的包没有实际意义,比如固定返回“helloworld”),并且没有上限在大包场景,每个包的大小都有涉及,所以Hertz重点优化了128k以内最常用的包的性能(吞吐量和延迟)。并发性每个实例的上游可能有多个,不会接受只有一个实例的请求;而且,HTTP1连接不能被多路复用,每个连接同时只能处理一个请求。因此服务器需要接受多个连接同时处理。不同服务的连接利用率也不同。比如压测服务的连接使用率很高,一个请求完成后马上进行下一个请求;某些服务的连接利用率非常低。虽然是长连接,但是只用了一次。.两者使用的连接模型不同。前者应该使用goroutineperconnection模型来减少上下文切换,后者应该使用coroutinepool来减少过多goroutine的调度开销。Hertz也同时支持这两种场景,用户可以根据自己的业务场景选择合适的配置。2.HTTP场景的压力测试2.1贴近自己的使用场景Github上有很多压力测试项目,网上也有很多性能测试报告,但这些项目和测试不一定适合你。举个极端的例子,在真实的场景下,你会不会写一个项目,无论客户端向服务端发送什么,它都只会回复helloworld?不幸的是,许多压力测试项目都这样做。在进行压力测试之前,您应该考虑您的真实使用场景,例如:使用长连接和短连接:使用长连接还是短连接更适合您自己的场景。连接使用量预估:如果使用长连接且连接使用率高(大部分场景),可以使用默认配置;如果connection使用率很低,可以添加配置:server.WithIdleTimeout(0),将goroutineperconnection模型改为coroutinepool模型,进行对比测试。数据位置和大小的确定:如上所述,不同位置(如query、header、body等)和大小的数据可能会影响框架。如果所有框架的性能都比较一般,可以考虑改变数据传输位置。并发数的确定:有些业务轻业务重框架,此时框架的并发量可能很高;有些服务重业务轻框架,此时框架的并发可能很低。如果只是想看框架的性能,可以使用常规场景:长连接、高连接使用率、1kbody、100并发等。hertz-benchmark仓库默认的压测配置也是如此。同时还开发了hertz-benchmark仓库,供用户配置header、body、并发数。用户可以很方便地修改这些配置来完成自己的压力测试。2.1.1确定压测对象衡量一个HTTP框架的性能,需要从两个角度去思考:Client角度和Server角度。在大型业务架构中,上游客户端不一定使用下游框架,开发者调用的下游服务也是如此。当考虑服务网格时,情况变得更加复杂。在一些压测项目中,将client和server进程混合在一起进行压测,然后得到整个框架的性能数据,可能与线上实际运行不一致。如果你想对服务器进行压力测试,你应该给客户端尽可能多的资源来将服务器推到极限,反之亦然。如果客户端和服务端都只使用4核CPU进行压力测试,开发者将无法判断最终的性能数据是从哪个角度获取的,更无法为线上业务提供实际参考。2.1.2使用独占CPU虽然线上应用通常是多进程共享CPU,但在压测场景下,Client和Server进程都异常繁忙。这时候共享CPU会造成大量的上下文切换,导致数据不足。可以参考,前后容易出现较大波动。所以我们的建议是将Client和Server进程隔离在不同的CPU或者不同的独占机器上。如果想进一步避免其他进程的影响,可以添加nice-n-20命令调整高压测试进程的调度优先级。此外,如果条件允许,与云平台虚拟机相比,使用真实的物理机会将使测试结果更加严谨和可重现。3.性能数据参考在满足上述需求的前提下,我们基于最新版本对多个框架进行了压力测试对比。压测代码在hertz-benchmark仓库。在服务器满载的目标下,Hertz的P99延迟是所有压测框架中最低的,吞吐量也处于第一梯队,并在持续优化中。CPU:AMDEPYC7Y8364核处理器2.7GHz运行有限服务器4个CPU,客户端16个CPU操作系统:DebianGNU/Linux10(buster)Go1.19hertzv0.3.2、fasthttpv1.40.0、ginv1.8.1、fiberv2.38.1四种框架吞吐量和延迟对比三种框架吞吐量和延迟对比4.结论Hertz作为超大规模企业级微服务HTTP框架,一开始更倾向于解决大规模微服务其设计场景中的各种问题。在推广过程中,也遇到过各种服务,踩过各种坑。我根据这些服务和遇到的问题写了这篇文章。欢迎开发者根据本文提供的测试指南,选择适合自己实际场景的工具。更多问题,请在GitHub上提出Issue。相关链接【1】hertz-benchmark:https://github.com/cloudwego/hertz-benchmark