gitalk
gitalk copied to clipboard
2021年Go生态圈rpc框架benchmark
https://colobu.com/2021/08/01/benchmark-of-rpc-frameworks/
kitex 这个 p99 真是惊人。。。。
之前我测过 easygo 的那个 netpoll, 在 4c 下固定 qps 压测(记得是1000还是2000),p99 比标准库好 上了 8c 就不太行了,p99 比标准库大得多,核心越多,表现越差
顺便鸟窝老师可以试试 https://utteranc.es/ gitalk 要的权限太多了。。
8核, 5000连接, 20万qps, p99.9延迟1.2s, 有问题吗? 我觉得没问题, 至少对业务来说. 实际上应用根本不会跑到这种情况. 正常应用哪会把机器cpu跑到100%, 跑到60%就很高了. 这种p99.9很高的情况, cpu不超90%应该都不会有这问题.
我猜主要还是cpu快跑满了, 他们自己定义的epoll协程拿不到cpu. 不像go runtime的poll, 在很多地方都插了代码, 专门的poller, gc, stw前后, 调度等都有, 拿出来的最大延时会低不少. 可能多个协程开reuseport+lockthread在这种极限情况会好一些.
切换到utteranc.es, 谢谢曹大 @cch123
@cch123 easygo 不够强,试试俺的 nbio 。不过连接数较少时吞吐量优势似乎不大,我主要在压 http/websocket 的,能保证更大连接数时的低内存占用、响应性能、稳定性,但连接数少的时候没有优势甚至响应略慢,可能我的异步 http/websocket parser 复杂度和实现的代码质量导致性能还不够好,在想办法优化,有点瓶颈了,对着pprof琢磨进一步节省的地方但也似乎空间比较小了,曹大要是有空有兴趣来瞅瞅帮我优化优化
啊哈哈,最近暂时不上班,没有好机器测试,你这个如果在 8c 16c 下小包大包都比标准库好,那确实很厉害
@cch123 easygo 不够强,试试俺的 nbio 。不过连接数较少时吞吐量优势似乎不大,我主要在压 http/websocket 的,能保证更大连接数时的低内存占用、响应性能、稳定性,但连接数少的时候没有优势甚至响应略慢,可能我的异步 http/websocket parser 复杂度和实现的代码质量导致性能还不够好,在想办法优化,有点瓶颈了,对着pprof琢磨进一步节省的地方但也似乎空间比较小了,曹大要是有空有兴趣来瞅瞅帮我优化优化
啊哈哈,最近暂时不上班,没有好机器测试,你这个如果在 8c 16c 下小包大包都比标准库好,那确实很厉害
我都还没跟标准库对比简单的吞吐量,只跟其他几个已知的poller网络库对比了下吞吐量,应该是不低于任何一个,比 easygo 能高一些 😂 8c 16c性能一般的原因是什么?
主要是我之前测 8c 感觉 poller 和标准库差得有点多, 一直有点疑惑,所以也希望看看别人的结果~
我是测的固定 qps,比如 1000 qps,8c,1KB response
@cch123 easygo 不够强,试试俺的 nbio 。不过连接数较少时吞吐量优势似乎不大,我主要在压 http/websocket 的,能保证更大连接数时的低内存占用、响应性能、稳定性,但连接数少的时候没有优势甚至响应略慢,可能我的异步 http/websocket parser 复杂度和实现的代码质量导致性能还不够好,在想办法优化,有点瓶颈了,对着pprof琢磨进一步节省的地方但也似乎空间比较小了,曹大要是有空有兴趣来瞅瞅帮我优化优化
啊哈哈,最近暂时不上班,没有好机器测试,你这个如果在 8c 16c 下小包大包都比标准库好,那确实很厉害
我都还没跟标准库对比简单的吞吐量,只跟其他几个已知的poller网络库对比了下吞吐量,应该是不低于任何一个,比 easygo 能高一些 😂 8c 16c性能一般的原因是什么?
主要是我之前测 8c 感觉 poller 和标准库差得有点多, 一直有点疑惑,所以也希望看看别人的结果~ 我是测的固定 qps,比如 1000 qps,8c,1KB response
我暂时手上也没机器,哪位有机器可以帮测测。。。 测试用例有没,我去瞄瞄
再投诉一次,都是年轻的80s,能不能换个朝气蓬勃的头像。。。😂
用例没啦,之前公司里的哈哈。。
参考你的arpc,写回response采用异步的方式。做了这一点点优化,性能提升不少。针对这个场景,这个优化还是很给力的
期待大佬能加一个大连接数的场景,比如 5w连接数(并发),看看自定义epoll是否具有优势。
@lesismal 我想这应该是测试环境的差异,你可以找个核数比较高的机器试试。
[[email protected] rpc_client]$ ./rpcx_xclient -c 100 -n 10000000 -s 127.0.0.1:8973 -pool 10
2021/08/03 13:09:57 rpcx_client.go:39: INFO : concurrency: 100
requests per client: 100000
2021/08/03 13:09:57 rpcx_client.go:47: INFO : Servers: 127.0.0.1:8973
2021/08/03 13:09:57 rpcx_client.go:58: INFO : message size: 581 bytes
2021/08/03 13:10:37 stats.go:15: INFO : took 39916 ms for 10000000 requests
2021/08/03 13:10:45 stats.go:36: INFO : sent requests : 10000000
2021/08/03 13:10:45 stats.go:37: INFO : received requests : 10000000
2021/08/03 13:10:45 stats.go:38: INFO : received requests_OK : 10000000
2021/08/03 13:10:45 stats.go:42: INFO : throughput (TPS) : 250526
[[email protected] rpc_client]$ ./arpc_client -c 100 -n 10000000 -s 127.0.0.1:8973 -pool 10
2021/08/03 13:11:20 arpc_client.go:42: INFO : concurrency: 100
requests per client: 100000
2021/08/03 13:11:20 arpc_client.go:50: INFO : message size: 581 bytes
2021/08/03 13:11:20.246 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.246 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.247 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.247 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.248 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.248 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.249 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.249 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.249 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:11:20.250 [INF] [ARPC CLI] 127.0.0.1:8973 Connected
2021/08/03 13:12:02 stats.go:15: INFO : took 41840 ms for 10000000 requests
2021/08/03 13:12:09 stats.go:36: INFO : sent requests : 10000000
2021/08/03 13:12:09 stats.go:37: INFO : received requests : 10000000
2021/08/03 13:12:09 stats.go:38: INFO : received requests_OK : 10000000
2021/08/03 13:12:09 stats.go:42: INFO : throughput (TPS) : 239005
2021/08/03 13:12:09 stats.go:45: INFO : mean: 416908 ns, median: 288505 ns, max: 25105919 ns, min: 26550 ns, p99.9: 6663952 ns
2021/08/03 13:12:09 stats.go:46: INFO : mean: 0 ms, median: 0 ms, max: 25 ms, min: 0 ms, p99.9: 6 ms
因为连接数比较少(10个),这种情况下使用异步写回效果不错,反正也就多10个goroutine,业务处理的goroutine可以尽早释放。当前文章的场景是少连接高并发的场景,巨多连接高并发的场景可能又是另外一个结果 @taoyuanyuan 。等我有一个干净机器后测试一下。
好的,我测试一下,多谢
好的,我测试一下,多谢
我有8c16t 机器, 只有32G内存, 有哪些测试代码? 我来跑下
我有8c16�t 机器, 只有32G内存, 有哪些测试代码? 我来跑下
@guonaihong 可以看这里的测试代码 https://github.com/rpcxio/rpcx-benchmark
首先感谢鸟窝大佬对Kitex的关注,给出了详细的测试数据,emmm,但这个压测结论对Kitex不太公平:
- 通信方式未对齐:rpcx使用连接多路复用,Kitex使用的是连接池,而连接池不修改配置参数,在高并发情况下退化为短连接,自然延迟会上升,而且高并发建立连接会导致backlog积压,进而导致请求失败 修正:Kitex配置连接多路复用,统一RPC通信方式
- Client->Server 同机测试且两端进程未绑定核,不符合实际场景,通常Client/Server需要分开来看,否则测试时两端会互相影响,Client消耗了较多CPU,导致Server在CPU消耗不一致情况下对比性能。 Kitex的测试数据是尽量打满Server端CPU(4c为主)关注其吞吐和延迟,核数较多时可以调整参数调优,当然在实际场景中两端性能都很重要,Kitex也会关注Client性能,后续补充Client性能数据。 建议1:两个机器分别作为Client/Server压测,若同机测试应通过taskset为两进程绑核 建议2:可以关注下个框架CPU消耗情况
- 编码/序列化:Kitex 虽然支持多协议,但是以Thrift为主的框架,有自己的Thrift代码生成工具,在Thrift上做了诸多优化,pb目前主要是支持未开始优化,也未使用gogo生成代码,rpcx应该使用的是gogo,从pb编码上,也是有一些差异。 这是Kitex的压测代码 kitex-benchmark,若有类似的测试未对齐的地方,希望鸟窝大佬指出~
kitex 这个 p99 真是惊人。。。。
之前我测过 easygo 的那个 netpoll, 在 4c 下固定 qps 压测(记得是1000还是2000),p99 比标准库好 上了 8c 就不太行了,p99 比标准库大得多,核心越多,表现越差
@cch123 后面已做回复,「连接池不修改配置参数,在高并发情况下退化为短连接,自然延迟会上升,而且高并发建立连接会导致backlog积压,进而导致请求失败」,测试需要对齐。netpoll我们内部的测试也是比标准库要好,可以关注下 netpoll 的压测数据哈
怎么能没有hprose这个框架呢 http://hprose.com
@lesismal 压测脚本有环境要求。
你需要修改 benchmark_pb.sh 的 taskset 参数,或是在满足要求的机器上运行。repo 里的参考数据是以 client 压满 server 的前提下,对 Server 性能的一个摸底测试情况。
- 通信方式未对齐:rpcx使用连接多路复用,Kitex使用的是连接池,而连接池不修改配置参数,在高并发情况下退化为短连接
请教下,这个是针对你们的哪种特殊业务场景定制的吗? 因为我见过的高并发场景通常是 keepalive 的连接, idle timeout 了才会断开,如果是高并发、活跃链接反倒退化成短链接,有点不可思议。所以如果是可配置,是否默认 keepalive 会更好些呢?
这并不是特殊场景的定制,连接池和连接多路复用就是两种通信模式,连接多路是基于io多路复用可以极大的提升吞吐,连接池是早期BIO的通信模式(但底层NIO,上层也可以使用连接池),每次请求都从池子里取一个连接直到请求结束放回池子,连接池的作用是复用连接减少短连接建连的消耗,连接池模式要提高吞吐需要对应调整连接池的配置,比如100并发下,同时有100个请求发出,如果连接池容量是10,那只有10个请求能复用连接,其他请求只能新建连接发送请求就会退化为短连接。连接池通信模式会带来额外的资源消耗,性能是比不上连接多路复用的。 而你说的 idle timeout 只是空闲连接关闭策略,与此无关。
复杂的微服务体系并不是单纯的Golang语言、单一的框架,需要很多兼容性考虑。 Q: 为什么Kitex不默认连接多路复用? 开启连接多路复用的前提是服务端要支持连接多路复用通信模式,由上面所说,Kitex不仅仅需要与Kitex通信还有其他语言其他框架甚至proxy,保证兼容性通信则无法默认开启连接多路复用,更特殊的像一些Python框架,很多都是多进程模式,使用长连接会block服务端,这种case设置连接池都无法使用,只能短连接。
kitex 这个 p99 真是惊人。。。。 之前我测过 easygo 的那个 netpoll, 在 4c 下固定 qps 压测(记得是1000还是2000),p99 比标准库好 上了 8c 就不太行了,p99 比标准库大得多,核心越多,表现越差
@cch123 后面已做回复,「连接池不修改配置参数,在高并发情况下退化为短连接,自然延迟会上升,而且高并发建立连接会导致backlog积压,进而导致请求失败」,测试需要对齐。netpoll我们内部的测试也是比标准库要好,可以关注下 netpoll 的压测数据哈
我之前提过issue,netpoll 的压测代码你们能否提供下 😂
不好意思哈,因为最近还有其他事情比较忙,估计这周netpoll的压测代码会提交上去。
我上面提到的 “针对你们的哪种特殊业务场景定制” 其实最大的疑问是 RPC 默认长连接可能会更好,所以对 “而连接池不修改配置参数,在高并发情况下退化为短连接” 这种默认参数时短连接策略有点没get到,现在能懂你意思了
这是 Kitex 的长连接池模式的压测代码配置,但上面对Kitex的测试,应该不是使用这个配置,Kitex默认的长连接配置容量也较小,如果不单独调整容量,极限测试性能也不会符合预期,池子容量还是要根据具体场景来设置。
常规理解,这个配置应该是全局、每个地址最大非活跃连接数都是1000,超时时间为1分钟,所以 kitex benchmark 的代码应该是长连接、不会因为短连接而影响性能了
鸟窝老师的测试中还有2k-5k的并发,1k池子容量也无法避免长连接的退化,更合理的是统一使用连接多路复用才能对齐测试。
不管哪种语言,如果 RPC server 是阻塞 io 都比较难受,字节应该不差时间把其他语言的也改造成非阻塞 io 的异步 RPC,或者大佬干脆让其他语言的团队也转 go,继续壮大 go 社区最好了
嗯嗯,这自然是我们希望的,如果这位老师参与过庞大的微服务治理和维护就知道版本收敛是一个艰巨的过程,不是短期能达成的,这位老师也一直在强调arpc的通用性,我们不可能忽略其他服务强制达到最优的性能。
我 4c8t ubuntu 18.04 vm 上用 benchmark_pb.sh 测了下是上面的结果,只对比 kitex 和 rpcx 好像和你们 repo 文档上的数据也不一样,会不会因为你们 repo 文档上的数据用的是内部内核 patch 相关的版本? 或者这个 benchmark 的 kitex 代码还需要修改哪些参数?
- Kitex的 压测 并没有使用特定的内核版本测试哈,或者说并没有使用针对netpoll优化的内核。
- 同机测试不限制核数对测试是有影响的,前面也有回复「Client->Server 同机测试且两端进程未绑定核,不符合实际场景,通常Client/Server需要分开来看,否则测试时两端会互相影响,Client消耗了较多CPU,导致Server在CPU消耗不一致情况下对比性能」。 而且我们使用golang都知道,go进程根据runtime.NumCPU()获取可用cpu数进而决定processor数,不限制核两个进程获取的都是机器的cpu数,processor多于实际可用cpu数会带来额外的调度开销,另外netpoll默认的loop设置对4c比较友好,核数多时需要调整loop数量,这个在新的pr上已经做了调整。 建议测试最好是绑核或两个机器测试,分别对比client和server。
- 从arpc的代码看,poller_epoll.go#L202 这里是串行处理,貌似并不适用于实际的rpc调用场景,这种方式netpoll也做过特定支持,如果handler处理很快的话吞吐表现优异,而实际rpc场景handler有业务逻辑耗时会高,串行的表现急剧下降,可以在handler中sleep 1ms看下arpc的表现呢。
非常感谢 @lesismal 老师回复了这么多,Kitex的默认配置做压力测试的确不是最优的,需要做一点额外配置,也是给大家测试对比带来了一些困惑。 针对 @lesismal 老师的留言,借鸟窝老师的宝地我再做一些回复和补充哈。后面的讨论可以在Kitex和Netpoll的issue中发起,不占用领地继续回复。
同机测试确实不准确,但是你们benchmark代码里也有cpu平均占比,计算下单位cpu对应的tps其实得到的结果大致也差不多,当然,多机测试结果更靠谱。
你直接看到的 Kitex benchmark 输出的CPU是调用端进程统计,服务端CPU在服务端进程日志有输出,如果是服务端极限测试,需要打满服务端的CPU。 Kitex Client引入了一些额外的逻辑,同QPS下CPU消耗与Server是不对等的,这也是我们后续要优化的一个点,所以目前Kitex 压测是不限制Client CPU的情况下,看Server极限性能,我们提供的压测对比也都是限制 Server 的核数,当然延迟指标还是需要从Client来看。
这个可能你误解了,这个是 nbio 的代码。arpc 默认使用标准库
你提的benchmark pr直接测试的确性能表现不错,以为网络库使用nbio,发现 poller_epoll.go#L202 做了串行处理,我们针对缓存场景也做了类似的支持性能确实更优,但handler耗时高会导致性能急剧下降,通过对各框架handler加了sleep 1ms对比后,验证了这个问题,arpc的性能劣化明显,如果使用的是标准库那arpc处理应该是类似的串行处理。而实际场景大部分RPC服务 handler 耗时>1ms。
arpc 的 handler,可以根据需要自行定制所有消息都go一个协程处理,也可以按路由定制是否该路由全go一个协程去处理,也可以读协程度到一个就处理一个(one-by-one),还可以根据您自己业务逻辑中的需要随时进行异步处理,比如:
谢谢提供demo说明,这里需要用户自行定制处理消息,为解决handler耗时高性能劣化问题,用户必须在Handler中起协程处理,所以与常规rpc框架做对比的话,handler也要起协程。 另外,即使这样处理了,poller协程还要做解码、中间件的执行,与你提到的 “netpoll的代码向上层暴露了阻塞读的接口” 可能引起的问题是一样的 -> 阻塞了 poller 协程(下面解释netpoll是否存在这个问题)。不知道我这样的理解有没有问题哈,毕竟还未完整读源码,只是从部分代码逻辑做了这个猜测。
我没有 review kitex 代码,不确定 kitex 是同步解析完整包,如果是这种,那么对于可能存在慢连接的场景,这会让服务变慢,比如某个慢连接阻塞了 poller 协程,在同一个event loop中的其他连接要等待,或者没收到完整包就单开一个协程去处理这个连接、则类似标准库方案了,可能协程数量会更大。当然,如果 netpoll 只是针对 RPC 场景提供网络层,因为通常是内网、基础设施可靠性较高,那么这种风险或者问题就不大,但是对于公网服务,慢连接、“streaming的粘包” 还是比较常见的,则不适合使用 netpoll + 同步解析完整包的方式。
注意到你提了两个关于这个问题的issue哈,不过这里的确不存在你说的阻塞 poller 协程问题,初看代码会有些误解。我尝试解释一下,poller在收到连接上的读事件后,开始读消息,读到就InputAck,继续处理其他事件,并不会阻塞poller协程,你看的阻塞读是上层接口,比如RPC框架层面,Kitex 的确是同步解析包,但netpoll不是,而且netpoll作为网络库本身也不应该关注包大小,所以不会出现读不到完整包阻塞poller协程问题。 额外补充下,虽然Kitex同步解析包,但每次读多少取决于解码逻辑,Kitex 支持一次读完完整的rpc消息,也支持逐步解码读,前者的性能会更好。
可以试下用你们的机器测下 arpc 的数据
这个没有问题哈,之前不知道arpc这个高性能框架,只关注到鸟窝老师的rpcx,你的PR已经合并了,我们会补充数据的,但测试场景还需要沟通对齐。
另外,Kitex 也并未强耦合 Netpoll,同样支持各种扩展包括:传输模块、Codec等等,详见框架扩展。如果@lesismal 老师愿意,欢迎支持Kitex对nbio的扩展哈。场景的差异,Kitex 的确没有arpc提供的广播、推送、异步支持,但服务端异步是计划支持的,其他特性我们会结合Kitex用户的需求程度来决定是否支持。
@lesismal 老师,我们交流中还是有没有对齐的地方哈,文字沟通的确很难清楚的阐述问题,避免对这里过多的打扰,我不再引用回复,移步到内部的issue我们讨论吧 ;)
@cch123 easygo 不够强,试试俺的 nbio 。不过连接数较少时吞吐量优势似乎不大,我主要在压 http/websocket 的,能保证更大连接数时的低内存占用、响应性能、稳定性,但连接数少的时候没有优势甚至响应略慢,可能我的异步 http/websocket parser 复杂度和实现的代码质量导致性能还不够好,在想办法优化,有点瓶颈了,对着pprof琢磨进一步节省的地方但也似乎空间比较小了,曹大要是有空有兴趣来瞅瞅帮我优化优化
啊哈哈,最近暂时不上班,没有好机器测试,你这个如果在 8c 16c 下小包大包都比标准库好,那确实很厉害
4c 基本能干过标准库。 8c 中小包标准库好些,但是很奇怪,8c 时我不默认 NumCPU 个 poller 协程,而是手动配置 6 个 poller 协程能干过标准库,另外,8c 大包 4k 8k 时也能干过标准库。我闲了多跑几轮玩。
https://github.com/lesismal/go-net-benchmark/issues/1
,比如 5w连接数(并发),看看自定义
@cch123 @taoyuanyuan @guonaihong
今天又扩展了两样:
一是给 arpc 增加了可配置的 executor(异步响应时可以用协程池代替 go func() 从而限制异步响应的协程数量),这个比较简单 二是封装了个 net.Listener,用这个 Listener 支持两个 chan 分发 conn,其中一个限制数量、给标准库 server 使用,超过数量后 conn 分发给另一个 nbio 的 server,这样就打通了 标准库+nbio 服务同一个端口:
- 阈值内数量的连接数由标准库进行处理、获得跟arpc默认标准库方案同一水平的响应性能
- 超过阈值的连接数由 nbio 处理,协程数量、内存都可控
日常自己折腾,可能换各种姿势,而且还没经过大量测试验证比如开启内存相关的pool有没有脏内存之类的bug,所以就不打算再 PR 到字节同学的仓库了,有兴趣的兄弟可以来这里看下: https://github.com/lesismal/kitex-benchmark/blob/main/protobuf/arpc-nbio/main.go
刚跑了下 5w 连接的数据,(脚本我在自己分支上修改过支持了连接数的-pool参数)。
5w连接数
arpc-nbio有少量失败应该是超时,实际场景可以在合理调整协程池、超时时间等参数。TPS等响应指标好于arpc,而且cpu和内存占用都低得多,arpc标准库3G多内存占用,arpc-nbio只需要200M
普通连接数
普通连接数时arpc-nbio和arpc默认标准库同一水平
个个都是人才,建议轮子造出来后多弄点文档,让我们可以直接飞起来
这并不是特殊场景的定制,连接池和连接多路复用就是两种通信模式,连接多路是基于io多路复用可以极大的提升吞吐,连接池是早期BIO的通信模式(但底层NIO,上层也可以使用连接池),每次请求都从池子里取一个连接直到请求结束放回池子,连接池的作用是复用连接减少短连接建连的消耗,连接池模式要提高吞吐需要对应调整连接池的配置,比如100并发下,同时有100个请求发出,如果连接池容量是10,那只有10个请求能复用连接,其他请求只能新建连接发送请求就会退化为短连接。连接池通信模式会带来额外的资源消耗,性能是比不上连接多路复用的。 而你说的 idle timeout 只是空闲连接关闭策略,与此无关。
- 通信方式未对齐:rpcx使用连接多路复用,Kitex使用的是连接池,而连接池不修改配置参数,在高并发情况下退化为短连接
请教下,这个是针对你们的哪种特殊业务场景定制的吗? 因为我见过的高并发场景通常是 keepalive 的连接, idle timeout 了才会断开,如果是高并发、活跃链接反倒退化成短链接,有点不可思议。所以如果是可配置,是否默认 keepalive 会更好些呢?
这并不是特殊场景的定制,连接池和连接多路复用就是两种通信模式,连接多路是基于io多路复用可以极大的提升吞吐,连接池是早期BIO的通信模式(但底层NIO,上层也可以使用连接池),每次请求都从池子里取一个连接直到请求结束放回池子,连接池的作用是复用连接减少短连接建连的消耗,连接池模式要提高吞吐需要对应调整连接池的配置,比如100并发下,同时有100个请求发出,如果连接池容量是10,那只有10个请求能复用连接,其他请求只能新建连接发送请求就会退化为短连接。连接池通信模式会带来额外的资源消耗,性能是比不上连接多路复用的。 而你说的 idle timeout 只是空闲连接关闭策略,与此无关。
复杂的微服务体系并不是单纯的Golang语言、单一的框架,需要很多兼容性考虑。 Q: 为什么Kitex不默认连接多路复用? 开启连接多路复用的前提是服务端要支持连接多路复用通信模式,由上面所说,Kitex不仅仅需要与Kitex通信还有其他语言其他框架甚至proxy,保证兼容性通信则无法默认开启连接多路复用,更特殊的像一些Python框架,很多都是多进程模式,使用长连接会block服务端,这种case设置连接池都无法使用,只能短连接。
是不是长短连接和连接池有什么关系吗?只要能保活都是长连接呀。新建立连接发送请求为什么会成为短连接,没有保活?
是不是长短连接和连接池有什么关系吗?只要能保活都是长连接呀。新建立连接发送请求为什么会成为短连接,没有保活?
应该是不能保活。新建立的连接没有在池里,不会进行复用了
一是给 arpc 增加了可配置的 executor(异步响应时可以用协程池代替 go func() 从而限制异步响应的协程数量),这个比较简单 二是封装了个 net.Listener,用这个 Listener 支持两个 chan 分发 conn,其中一个限制数量、给标准库 server 使用,超过数量后 conn 分发给另一个 nbio 的 server,这样就打通了 标准库+nbio 服务同一个端口:
- 阈值内数量的连接数由标准库进行处理、获得跟arpc默认标准库方案同一水平的响应性能
- 超过阈值的连接数由 nbio 处理,协程数量、内存都可控
@smallnest @cch123 @taoyuanyuan @YangruiEmma @guonaihong 近期nbio发了个版,在去年这个思路下,把http/websocket支持了多种IO模式(阻塞模式,非阻塞模式,混合模式),这样在低在线时获得更好的响应性能,高在线时交给poller来提高承载量的前提下保持低占用和稳定性。 因为本来就实现了streaming parser,既然支持异步解析,标准库方案的同步解析当然也能支持,所以稍微改造下,websocket也直接支持使用标准库server了,我简单压测了下。阻塞IO的连接的http性能好于标准库,websocket略好于gorilla/websocket: https://github.com/lesismal/nbio/releases/tag/v1.3.5
但是HTTP2.0和3.0的支持还很远,这俩都是个大活,暂时没档期搞,希望以后能有时间把Poller的HTTP2.0/3.0都支持上。