成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Netty(二) 從線程模型的角度看 Netty 為什么是高性能的?

G9YH / 2877人閱讀

摘要:主從多線程該模型將客戶端連接那一塊的線程也改為多線程,稱為主線程。同時(shí)也是多個(gè)子線程來處理事件響應(yīng),這樣無論是連接還是事件都是高性能的。多線程提高并發(fā)效率。

前言

在之前的 SpringBoot 整合長(zhǎng)連接心跳機(jī)制 一文中認(rèn)識(shí)了 Netty。

但其實(shí)只是能用,為什么要用 Netty?它有哪些優(yōu)勢(shì)?這些其實(shí)都不清楚。

本文就來從歷史源頭說道說道。

傳統(tǒng) IO

在 Netty 以及 NIO 出現(xiàn)之前,我們寫 IO 應(yīng)用其實(shí)用的都是用 java.io.* 下所提供的包。

比如下面的偽代碼:

ServeSocket serverSocket = new ServeSocket(8080);
Socket socket = serverSocket.accept() ;
BufferReader in = .... ;

String request ;
 
while((request = in.readLine()) != null){
    new Thread(new Task()).start()
}

大概是這樣,其實(shí)主要想表達(dá)的是:這樣一個(gè)線程只能處理一個(gè)連接。

如果是 100 個(gè)客戶端連接那就得開 100 個(gè)線程,1000 那就得 1000 個(gè)線程。

要知道線程資源非常寶貴,每次的創(chuàng)建都會(huì)帶來消耗,而且每個(gè)線程還得為它分配對(duì)應(yīng)的棧內(nèi)存。

即便是我們給 JVM 足夠的內(nèi)存,大量線程所帶來的上下文切換也是受不了的。

并且傳統(tǒng) IO 是阻塞模式,每一次的響應(yīng)必須的是發(fā)起 IO 請(qǐng)求,處理請(qǐng)求完成再同時(shí)返回,直接的結(jié)果就是性能差,吞吐量低。
Reactor 模型

因此業(yè)界常用的高性能 IO 模型是 Reactor。

它是一種異步、非阻塞的事件驅(qū)動(dòng)模型。

通常也表現(xiàn)為以下三種方式:

單線程

從圖中可以看出:

它是由一個(gè)線程來接收客戶端的連接,并將該請(qǐng)求分發(fā)到對(duì)應(yīng)的事件處理 handler 中,整個(gè)過程完全是異步非阻塞的;并且完全不存在共享資源的問題。所以理論上來說吞吐量也還不錯(cuò)。

但由于是一個(gè)線程,對(duì)多核 CPU 利用率不高,一旦有大量的客戶端連接上來性能必然下降,甚至?xí)写罅空?qǐng)求無法響應(yīng)。
最壞的情況是一旦這個(gè)線程哪里沒有處理好進(jìn)入了死循環(huán)那整個(gè)服務(wù)都將不可用!
多線程

因此產(chǎn)生了多線程模型。

其實(shí)最大的改進(jìn)就是將原有的事件處理改為了多線程。

可以基于 Java 自身的線程池實(shí)現(xiàn),這樣在大量請(qǐng)求的處理上性能提示是巨大的。

雖然如此,但理論上來說依然有一個(gè)地方是單點(diǎn)的;那就是處理客戶端連接的線程。

因?yàn)榇蠖鄶?shù)服務(wù)端應(yīng)用或多或少在連接時(shí)都會(huì)處理一些業(yè)務(wù),如鑒權(quán)之類的,當(dāng)連接的客戶端越來越多時(shí)這一個(gè)線程依然會(huì)存在性能問題。

于是又有了下面的線程模型。

主從多線程

該模型將客戶端連接那一塊的線程也改為多線程,稱為主線程。

同時(shí)也是多個(gè)子線程來處理事件響應(yīng),這樣無論是連接還是事件都是高性能的。

Netty 實(shí)現(xiàn)

以上談了這么多其實(shí) Netty 的線程模型與之的類似。

我們回到之前 SpringBoot 整合長(zhǎng)連接心跳機(jī)制TCP-Heartbeat/) 中的服務(wù)端代碼:

    private EventLoopGroup boss = new NioEventLoopGroup();
    private EventLoopGroup work = new NioEventLoopGroup();


    /**
     * 啟動(dòng) Netty
     *
     * @return
     * @throws InterruptedException
     */
    @PostConstruct
    public void start() throws InterruptedException {

        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss, work)
                .channel(NioServerSocketChannel.class)
                .localAddress(new InetSocketAddress(nettyPort))
                //保持長(zhǎng)連接
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new HeartbeatInitializer());

        ChannelFuture future = bootstrap.bind().sync();
        if (future.isSuccess()) {
            LOGGER.info("啟動(dòng) Netty 成功");
        }
    }

其實(shí)這里的 boss 就相當(dāng)于 Reactor 模型中處理客戶端連接的線程池。

work 自然就是處理事件的線程池了。

那么如何來實(shí)現(xiàn)上文的三種模式呢?其實(shí)也很簡(jiǎn)單:

單線程模型:

private EventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(group)
                .childHandler(new HeartbeatInitializer());

多線程模型:

private EventLoopGroup boss = new NioEventLoopGroup(1);
private EventLoopGroup work = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss,work)
                .childHandler(new HeartbeatInitializer());

主從多線程:

private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss,work)
                .childHandler(new HeartbeatInitializer());

相信大家一看也明白。

總結(jié)

其實(shí)看過了 Netty 的線程模型之后能否對(duì)我們平時(shí)做高性能應(yīng)用帶來點(diǎn)啟發(fā)呢?

我認(rèn)為是可以的:

接口同步轉(zhuǎn)異步處理。

回調(diào)通知結(jié)果。

多線程提高并發(fā)效率。

無非也就是這些,只是做了這些之后就會(huì)帶來其他問題:

異步之后事務(wù)如何保證?

回調(diào)失敗的情況?

多線程所帶來的上下文切換、共享資源的問題。

這就是一個(gè)博弈的過程,想要做到一個(gè)盡量高效的應(yīng)用是需要不斷磨合試錯(cuò)的。

上文相關(guān)的代碼:

https://github.com/crossoverJie/netty-action

歡迎關(guān)注公眾號(hào)一起交流:

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/71483.html

相關(guān)文章

  • 少啰嗦!一分鐘帶你讀懂JavaNIO和經(jīng)典IO區(qū)別

    摘要:的選擇器允許單個(gè)線程監(jiān)視多個(gè)輸入通道。一旦執(zhí)行的線程已經(jīng)超過讀取代碼中的某個(gè)數(shù)據(jù)片段,該線程就不會(huì)在數(shù)據(jù)中向后移動(dòng)通常不會(huì)。 1、引言 很多初涉網(wǎng)絡(luò)編程的程序員,在研究Java NIO(即異步IO)和經(jīng)典IO(也就是常說的阻塞式IO)的API時(shí),很快就會(huì)發(fā)現(xiàn)一個(gè)問題:我什么時(shí)候應(yīng)該使用經(jīng)典IO,什么時(shí)候應(yīng)該使用NIO? 在本文中,將嘗試用簡(jiǎn)明扼要的文字,闡明Java NIO和經(jīng)典IO之...

    Meils 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列(五):深入淺出學(xué)NioEventLoopGroup

    摘要:接下來的兩篇文章,我將從源碼角度為大家深入淺出的剖析的線程模型工作機(jī)制。我們看一下的源碼通過的代碼發(fā)現(xiàn),實(shí)現(xiàn)了接口,其內(nèi)部會(huì)通過指定的默認(rèn)線程工廠來創(chuàng)建線程,并執(zhí)行相應(yīng)的任務(wù)。至此,初始化完成了。下一篇我們將詳細(xì)介紹,敬請(qǐng)期待。 我們都知道Netty的線程模型是基于React的線程模型,并且我們都知道Netty是一個(gè)高性能的NIO框架,那么其線程模型必定是它的重要貢獻(xiàn)之一。 在使用ne...

    MSchumi 評(píng)論0 收藏0
  • 徹底理解Netty,這一篇文章就夠了

    摘要:如果什么事都沒得做,它也不會(huì)死循環(huán),它會(huì)將線程休眠起來,直到下一個(gè)事件來了再繼續(xù)干活,這樣的一個(gè)線程稱之為線程。而請(qǐng)求處理邏輯既可以使用單獨(dú)的線程池進(jìn)行處理,也可以跟放在讀寫線程一塊處理。 Netty到底是什么 從HTTP說起 有了Netty,你可以實(shí)現(xiàn)自己的HTTP服務(wù)器,F(xiàn)TP服務(wù)器,UDP服務(wù)器,RPC服務(wù)器,WebSocket服務(wù)器,Redis的Proxy服務(wù)器,MySQL的P...

    yy13818512006 評(píng)論0 收藏0
  • netty實(shí)戰(zhàn)》閱讀筆記(1)——Netty 概念及體系結(jié)構(gòu)

    摘要:它使用了事件通知以確定在一組非阻塞套接字中有哪些已經(jīng)就緒能夠進(jìn)行相關(guān)的操作。目前,可以把看作是傳入入站或者傳出出站數(shù)據(jù)的載體。出站事件是未來將會(huì)觸發(fā)的某個(gè)動(dòng)作的操作結(jié)果,這些動(dòng)作包括打開或者關(guān)閉到遠(yuǎn)程節(jié)點(diǎn)的連接將數(shù)據(jù)寫到或者沖刷到套接字。 netty的概念 定義 Netty 是一款異步的事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架,支持快速地開發(fā)可維護(hù)的高性能的面向協(xié)議的服務(wù)器和客戶端。我們可以很簡(jiǎn)單的...

    solocoder 評(píng)論0 收藏0
  • 【源起Netty 正傳】Netty Channel

    摘要:搞懂了這部分后,我們將明白在世界中扮演的角色進(jìn)擊的此圖展示的已經(jīng)算是優(yōu)化后的了用到了線程池。多線程將這種處理操作分隔出來,非型操作業(yè)務(wù)操作配備以線程池,進(jìn)化成多線程模型這樣的架構(gòu),系統(tǒng)瓶頸轉(zhuǎn)移至部分。 Channel定位 注意:如無特別說明,文中的Channel都指的是Netty Channel(io.netty.channel) 一周時(shí)間的Channel家族學(xué)習(xí),一度讓我懷疑人生——...

    jindong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<