Spring Cloud Gateway中netty线程池优化

Spring Cloud Gateway中netty线程池优化,第1张

最近测试同学对系统进行压测。报出一个问题:几乎所有接口的成绩都不太好。甚至一些仅仅是主键查询,并且数据量不大的接口也是如此。排查过程中:跳过gateway网关,直接通过目标服务器ip进行压测发现成绩提升明显。初步判断是网关问题。网上翻阅资料发现一个优化点,就是netty本身的线程池配置。

要设置起本身可同时工作的线程数需要设置netty中的 reactor.netty.ioWorkerCount 参数。该参数无法直接配置,需要通过 System.setProperty 设置,故我们可以创建以下配置类来配置该参数:

我这里版本是 reactor-netty-core-1.0.3 ,版本不一样的话 可能参数key不太一样。可以看一下LoopResources 中写的key。

Runtime.getRuntime().availableProcessors() 获取的是cpu核心线程数也就是计算资源,而不是CPU物理核心数,对于支持超线程的CPU来说,单个物理处理器相当于拥有两个逻辑处理器,能够同时执行两个线程。

接下来看一下 DefaultLoopResources做了什么

可以看出来,如果未配置。netty是没有select线程组的。结合分析reactor模型可以发现,这种情况对处理效率是有影响的。而且最大只和cpu核心数量相同的配置也明显无法重复利硬件用资源。

在实战三中,我们处理了同一个端口上来的2种不同协议的数据,项目上线后,运行良好,之后项目又需要添加一种数据协议,按照同样的方法处理再上线后,发现在网络很差的情况下,会有数据丢包现象。

为了更加通用,针对项目进行了重构,对于netty处理也增加了不少优化。

优化点:

重构之后,过两天就会上线,现在我们总共支持4种不同的数据协议(四种不同厂家的设备),就算还要继续增加,项目结构上也可以很快处理完成。

1、NettyServer.class

2、NettyServerInitializer.class

3、NettyServerDecoder.class

4、NettyServerHandler.class

5、SpringbootApplication.class

基本思路就是不断从TCP缓冲区中读取数据,每次读取完都需要判断是否是一个完整的数据包

若当前读取的数据不足以拼接成一个完整的业务数据包,那就保留该数据,继续从tcp缓冲区中读取,直到得到一个完整的数据包

若当前读到的数据加上已经读取的数据足够拼接成一个数据包,那就将已经读取的数据拼接上本次读取的数据,够成一个完整的业务数据包传递到业务逻辑, 多余的数据仍然保留,以便和下次读到的数据尝试拼接

这里最重要的是就是,使用markReaderIndex标记读索引,使的多余的数据保留,继续等待后面的数据


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/654079.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-07-23
下一篇2023-07-23

发表评论

登录后才能评论

评论列表(0条)

    保存