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本身的線程池配置。

二之宿、線程池配置

要設(shè)置可同時工作的線程數(shù)需要設(shè)置netty中的reactor.netty.ioWorkerCount參數(shù)族操。該參數(shù)無法直接配置,需要通過System.setProperty設(shè)置澈缺,故我們可以創(chuàng)建以下配置類來配置該參數(shù):

@Configuration
public static class ReactNettyConfiguration {

    @Bean
    public ReactorResourceFactory reactorClientResourceFactory() {
        System.setProperty("reactor.netty.ioSelectCount","1");

        // 這里工作線程數(shù)為2-4倍都可以坪创。看具體情況
        int ioWorkerCount = Math.max(Runtime.getRuntime().availableProcessors()*3, 4));
        System.setProperty("reactor.netty.ioWorkerCount",String.valueOf(ioWorkerCount);
        return new ReactorResourceFactory();
    }
}

我這里版本是reactor-netty-core-1.0.3姐赡,版本不一樣的話 可能參數(shù)key不太一樣∧啵可以看一下LoopResources 中寫的key项滑。

Runtime.getRuntime().availableProcessors()獲取的是cpu核心線程數(shù)也就是計算資源,而不是CPU物理核心數(shù)涯贞,對于支持超線程的CPU來說枪狂,單個物理處理器相當(dāng)于擁有兩個邏輯處理器危喉,能夠同時執(zhí)行兩個線程。

三州疾、源碼分析

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ù)利硬件用資源哑蔫。

資料來源:關(guān)于spring cloud gateway中 netty線程池的一點小優(yōu)化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弧呐,隨后出現(xiàn)的幾起案子闸迷,更是在濱河造成了極大的恐慌,老刑警劉巖俘枫,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稿黍,死亡現(xiàn)場離奇詭異,居然都是意外死亡崩哩,警方通過查閱死者的電腦和手機巡球,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邓嘹,“玉大人酣栈,你說我怎么就攤上這事⌒谘海” “怎么了矿筝?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棚贾。 經(jīng)常有香客問我窖维,道長,這世上最難降的妖魔是什么妙痹? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任铸史,我火速辦了婚禮,結(jié)果婚禮上怯伊,老公的妹妹穿的比我還像新娘琳轿。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布崭篡。 她就那樣靜靜地躺著挪哄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪琉闪。 梳的紋絲不亂的頭發(fā)上迹炼,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音颠毙,去河邊找鬼斯入。 笑死,一個胖子當(dāng)著我的面吹牛吟秩,可吹牛的內(nèi)容都是我干的咱扣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼涵防,長吁一口氣:“原來是場噩夢啊……” “哼闹伪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起壮池,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤偏瓤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后椰憋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厅克,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年橙依,在試婚紗的時候發(fā)現(xiàn)自己被綠了证舟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡窗骑,死狀恐怖女责,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情创译,我是刑警寧澤抵知,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站软族,受9級特大地震影響刷喜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜立砸,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一掖疮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仰禽,春花似錦氮墨、人聲如沸纺蛆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至温峭,卻和暖如春猛铅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凤藏。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工奸忽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人揖庄。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓栗菜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹄梢。 傳聞我的和親對象是個殘疾皇子疙筹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容