spring?cloud?gateway中netty線程池小優(yōu)化
關(guān)于spring cloud gateway中 netty線程池的一點小優(yōu)化
最近測試同學(xué)對系統(tǒng)進行壓測。報出一個問題:幾乎所有接口的成績都不太好。甚至一些僅僅是主鍵查詢,并且數(shù)據(jù)量不大的接口也是如此。
排查過程中:跳過gateway網(wǎng)關(guān),直接通過目標(biāo)服務(wù)器ip進行壓測發(fā)現(xiàn)成績提升明顯。初步判斷是網(wǎng)關(guān)問題。
網(wǎng)上翻閱資料發(fā)現(xiàn)一個優(yōu)化點,就是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線程數(shù),未配置的話。從cpu核心數(shù)和4直接取一個
int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioWorkerCount", "" + Math.max(Runtime.getRuntime().availableProcessors(), 4)));
// 這里是select線程數(shù) 默認(rèn)是-1
int DEFAULT_IO_SELECT_COUNT = Integer.parseInt(System.getProperty("reactor.netty.ioSelectCount", "-1"));
....
// 創(chuàng)建一個默認(rèn)的資源,把兩個線程數(shù)的參數(shù)傳遞過去
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<>();
// 因為默認(rèn)沒有配置 所以selectCode必然是-1
if (selectCount == -1) {
this.selectCount = workerCount;
// serverSelectLoops沒有創(chuàng)建,而是直接使用的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;
}
// 這里相當(dāng)于返回了工作組
@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線程組的。結(jié)合分析reactor模型可以發(fā)現(xiàn),這種情況對處理效率是有影響的。而且最大只和cpu核心數(shù)量相同的配置也明顯無法重復(fù)利硬件用資源。
目前解決是注入一下參數(shù),當(dāng)然也可以啟動jvm時指定。兩種都差不多
System.setProperty("reactor.netty.ioSelectCount","1");
// 這里工作線程數(shù)為2-4倍都可以。看具體情況
System.setProperty("reactor.netty.ioWorkerCount",String.valueOf(Math.max(Runtime.getRuntime().availableProcessors()*3, 4)));我這里版本是reactor-netty-core-1.0.3,版本不一樣的話 可能參數(shù)key不太一樣??梢钥匆幌翷oopResources 中寫的key
以上就是spring cloud gateway中netty線程池小優(yōu)化的詳細內(nèi)容,更多關(guān)于spring cloud gateway netty的資料請關(guān)注腳本之家其它相關(guān)文章!
- SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問題及解決
- spring?cloud?gateway中配置uri三種方式
- Spring?Cloud?Gateway中netty線程池優(yōu)化示例詳解
- SpringCloudGateway使用Skywalking時日志打印traceId解析
- SpringCloud?Gateway之請求應(yīng)答日志打印方式
- Spring Cloud gateway 網(wǎng)關(guān)如何攔截Post請求日志
- Spring Cloud Gateway 記錄請求應(yīng)答數(shù)據(jù)日志操作
- 基于Spring-cloud-gateway實現(xiàn)全局日志記錄的方法
相關(guān)文章
postman中POST請求時參數(shù)包含參數(shù)list設(shè)置方式
這篇文章主要介紹了postman中POST請求時參數(shù)包含參數(shù)list設(shè)置方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05

