spring cloud gateway中netty线程池小优化

 更新时间:2023年07月21日 08:52:34   作者:whale-52赫兹  
这篇文章主要介绍了spring cloud gateway中netty线程池小优化技巧示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

关于spring cloud gateway中 netty线程池的一点小优化

最近测试同学对系统进行压测。报出一个问题:几乎所有接口的成绩都不太好。甚至一些仅仅是主键查询,并且数据量不大的接口也是如此。

排查过程中:跳过gateway网关,直接通过目标服务器ip进行压测发现成绩提升明显。初步判断是网关问题。

网上翻阅资料发现一个优化点,就是netty本身的线程池配置。

源码

package reactor.netty.resources;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import java.time.Duration;
import java.util.Objects;
import reactor.core.Disposable;
import reactor.core.publisher.Mono;
@FunctionalInterface
public interface LoopResources extends Disposable {
	// 这里是worker线程数,未配置的话。从cpu核心数和4直接取一个
    int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioWorkerCount", "" + Math.max(Runtime.getRuntime().availableProcessors(), 4)));
    // 这里是select线程数 默认是-1
    int DEFAULT_IO_SELECT_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioSelectCount", "-1"));
    ....
    // 创建一个默认的资源,把两个线程数的参数传递过去
	static LoopResources create(String prefix) {
		if (Objects.requireNonNull(prefix, "prefix").isEmpty()) {
			throw new IllegalArgumentException("Cannot use empty prefix");
		}
		return new DefaultLoopResources(prefix, DEFAULT_IO_SELECT_COUNT, DEFAULT_IO_WORKER_COUNT, true);
	}
    ....

DefaultLoopResources做了什么

DefaultLoopResources(String prefix, int selectCount, int workerCount, boolean daemon) {
		this.running = new AtomicBoolean(true);
		this.daemon = daemon;
		this.workerCount = workerCount;
		this.prefix = prefix;
		this.serverLoops = new AtomicReference<>();
		this.clientLoops = new AtomicReference<>();
		this.cacheNativeClientLoops = new AtomicReference<>();
		this.cacheNativeServerLoops = new AtomicReference<>();
		// 因为默认没有配置 所以selectCode必然是-1
		if (selectCount == -1) {
			this.selectCount = workerCount;
			// serverSelectLoops没有创建,而是直接使用的serverLoops
			this.serverSelectLoops = this.serverLoops;
			this.cacheNativeSelectLoops = this.cacheNativeServerLoops;
		}
		else {
			this.selectCount = selectCount;
			this.serverSelectLoops = new AtomicReference<>();
			this.cacheNativeSelectLoops = new AtomicReference<>();
		}
	}
	@SuppressWarnings("FutureReturnValueIgnored")
	EventLoopGroup cacheNioSelectLoops() {
		// 两个相等的话 使用 cacheNioServerLoops 返回工作组
		if (serverSelectLoops == serverLoops) {
			return cacheNioServerLoops();
		}
		EventLoopGroup eventLoopGroup = serverSelectLoops.get();
		if (null == eventLoopGroup) {
			EventLoopGroup newEventLoopGroup = new NioEventLoopGroup(selectCount,
					threadFactory(this, "select-nio"));
			if (!serverSelectLoops.compareAndSet(null, newEventLoopGroup)) {
				//"FutureReturnValueIgnored" this is deliberate
				newEventLoopGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS);
			}
			eventLoopGroup = cacheNioSelectLoops();
		}
		return eventLoopGroup;
	}
	// 这里相当于返回了工作组
	@SuppressWarnings("FutureReturnValueIgnored")
	EventLoopGroup cacheNioServerLoops() {
		EventLoopGroup eventLoopGroup = serverLoops.get();
		if (null == eventLoopGroup) {
			EventLoopGroup newEventLoopGroup = new NioEventLoopGroup(workerCount,
					threadFactory(this, "nio"));
			if (!serverLoops.compareAndSet(null, newEventLoopGroup)) {
				//"FutureReturnValueIgnored" this is deliberate
				newEventLoopGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS);
			}
			eventLoopGroup = cacheNioServerLoops();
		}
		return eventLoopGroup;
	}

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

目前解决是注入一下参数,当然也可以启动jvm时指定。两种都差不多

System.setProperty("reactor.netty.ioSelectCount","1");
// 这里工作线程数为2-4倍都可以。看具体情况
      System.setProperty("reactor.netty.ioWorkerCount",String.valueOf(Math.max(Runtime.getRuntime().availableProcessors()*3, 4)));

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

以上就是spring cloud gateway中netty线程池小优化的详细内容,更多关于spring cloud gateway netty的资料请关注脚本之家其它相关文章!

相关文章

  • Java必须学会的类的继承与多态

    Java必须学会的类的继承与多态

    这篇文章主要介绍了Java类的继承与多态的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-08-08
  • 使用IDEA查看jar包及jar包的正确打开方式

    使用IDEA查看jar包及jar包的正确打开方式

    IDEA 是把 jar 包添加为 Libraries,然后展开后即可查看,因为是编译后的 class 文件,所以注释是没有的,今天小编给大家介绍下使用IDEA查看jar包及jar包的正确打开方式,感兴趣的朋友一起看看吧
    2023-07-07
  • Java ynchronized重量级锁的核心原理详解

    Java ynchronized重量级锁的核心原理详解

    这篇文章主要为大家详细介绍了Java ynchronized重量级锁的核心原理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • 深入了解Java内部类的用法

    深入了解Java内部类的用法

    java类的五大成员:属性,方法,构造器(构造方法),代码块,内部类。本文就来和大家详细讲讲ava内部类的用法,需要的小伙伴可以参考一下
    2022-07-07
  • 详解Java线程的创建及休眠

    详解Java线程的创建及休眠

    今天带大家学习的是Java的相关知识,文章围绕着Java线程的创建及休眠展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 详谈Java中的二进制及基本的位运算

    详谈Java中的二进制及基本的位运算

    下面小编就为大家带来一篇详谈Java中的二进制及基本的位运算。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • postman中POST请求时参数包含参数list设置方式

    postman中POST请求时参数包含参数list设置方式

    这篇文章主要介绍了postman中POST请求时参数包含参数list设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • java服务器的简单实现过程记录

    java服务器的简单实现过程记录

    在线浏览网页离不开服务器,用户发出请求request,服务器做出响应response,提供给用户需要的页面,这篇文章主要给大家介绍了关于java服务器简单实现的相关资料,需要的朋友可以参考下
    2021-11-11
  • Java操作pdf的工具类itext的处理方法

    Java操作pdf的工具类itext的处理方法

    这篇文章主要介绍了Java操作pdf的工具类itext,iText是一种生成PDF报表的Java组件,通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,需要的朋友可以参考下
    2022-04-04
  • java使用正则表达式查找包含的字符串示例

    java使用正则表达式查找包含的字符串示例

    这篇文章主要介绍了java使用正则表达式查找包含的字符串功能,结合具体实例形式分析了java针对字符串匹配查找的相关实现技巧,需要的朋友可以参考下
    2017-04-04

最新评论