第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁(yè) 慕課教程 Netty 教程 Netty 教程 ServerBootstrap 服務(wù)端啟動(dòng)類

Netty ServerBootstrap 服務(wù)端啟動(dòng)類

1. 前言

本節(jié)主要講解服務(wù)端主啟動(dòng)類 ServerBootstrap 的核心 API 的使用。

2. ServerBootstrap 流程

ServerBootstrap 的用法基本上都是固定的,一般對(duì)于新接觸 Netty 的同學(xué)來(lái)說(shuō),會(huì)覺(jué)得這些模板代碼比較多,難以理解。我們主要記住幾個(gè)核心配置即可。

  1. 指定線程模型: 通過(guò).group(bossGroup, workerGroup) 給引導(dǎo)類配置兩大線程組,這個(gè)引導(dǎo)類的線程模型也就定型了。其中 bossGroup 表示監(jiān)聽(tīng)端口,accept 新連接的線程組;workerGroup 表示處理每一條連接的數(shù)據(jù)讀寫的線程組;
  2. 指定 IO 模型: 通過(guò).channel(NioServerSocketChannel.class) 來(lái)指定 NIO 模型。如果指定 IO 模型為 BIO,那么這里配置上 OioServerSocketChannel.class 類型即可,通常都是使用 NIO,因?yàn)?Netty 的優(yōu)勢(shì)就在于 NIO;
  3. 指定處理邏輯: 通過(guò) childHandler () 方法,給這個(gè)引導(dǎo)類創(chuàng)建一個(gè) ChannelInitializer,這里主要就是定義后續(xù)每條連接的數(shù)據(jù)讀寫,業(yè)務(wù)處理邏輯;
  4. 綁定端口號(hào): 調(diào)用 bind (80),端口號(hào)自定義,不要和其他應(yīng)用的端口號(hào)有沖突即可。

3. 核心方法

方法 說(shuō)明
group() 用來(lái)指定線程模型
channel() 用來(lái)指定 IO 模型
handler() 用來(lái)指定服務(wù)端通道需要處理的業(yè)務(wù)邏輯(了解)
childHandler() 用來(lái)指定客戶端通道需要處理的業(yè)務(wù)邏輯(掌握)
attr() 給服務(wù)端通道綁定自定義屬性(了解)
childAttr() 給客戶端通道綁定自定義屬性(掌握)
option() 給服務(wù)端通道設(shè)置配置(了解)
childOption() 給客戶端通道設(shè)置配置(了解)
bind() 用來(lái)綁定端口號(hào)

說(shuō)明:客戶端和服務(wù)端連接之后,會(huì)維持一個(gè) Channel 通道,可以給其指定邏輯處理器和屬性配置;當(dāng)然,服務(wù)端啟動(dòng)的時(shí)候它也是一個(gè)特殊的 Channel 通道。

在開(kāi)發(fā)當(dāng)中,需要我們?nèi)プ远x的方法主要是 childHandler () 和 childAttr () 這兩個(gè)。childHandler () 用來(lái)綁定業(yè)務(wù)邏輯器,childAttr () 用來(lái)設(shè)置 Channel 屬性。比如:綁定用戶身份信息。其它方法的使用相對(duì)固定,了解即可。

圖片描述

4. 核心方法詳解

4.1 bind()

bind () 主要用來(lái)綁定本地端口號(hào)。

實(shí)例:

ChannelFuture future=serverBootstrap.bind(80);

future.addListener(new GenericFutureListener<Future<? super Void>>() {
    public void operationComplete(Future<? super Void> future) {
        if (future.isSuccess()) {
            System.out.println("端口綁定成功!");
        } else {
            System.err.println("端口綁定失敗!");
        }
    }
});

代碼升級(jí),如果綁定的端口已經(jīng)存在,則端口號(hào)遞增。當(dāng)然,實(shí)際情況很少會(huì)去遞增端口號(hào),一般都是上線之前確定端口號(hào),否則客戶端不知道端口號(hào),無(wú)法連接。

實(shí)例:

private static void bind(ServerBootstrap serverBootstrap, final int port) {
    ChannelFuture future=serverBootstrap.bind(port);
    future.addListener(new GenericFutureListener<Future<? super Void>>() {
        public void operationComplete(Future<? super Void> future) {
            if (future.isSuccess()) {
                System.out.println("端口[" + port + "]綁定成功!");
            } else {
                System.err.println("端口[" + port + "]綁定失敗!");
                //遞歸重新綁定端口號(hào)
                bind(serverBootstrap, port + 1);
            }
        }
    });
}

4.2 attr()

attr () 方法可以給服務(wù)端的 channel,也就是 NioServerSocketChannel 指定一些自定義屬性,可以通過(guò) channel.attr() 取出這個(gè)屬性。

實(shí)例:

//省略了其它模板代碼
serverBootstrap.attr(AttributeKey.newInstance("serverName"), "nettyServer")

總結(jié),一般來(lái)說(shuō) attr () 運(yùn)用的比較少,了解即可。

4.3 childAttr()

childAttr 可以給每一條連接指定自定義屬性,可以通過(guò) channel.attr() 取出該屬性。

實(shí)例:

//省略了其它模板代碼
serverBootstrap.childAttr(AttributeKey.newInstance("clientKey"), "clientValue")

總結(jié),常見(jiàn)的運(yùn)用場(chǎng)景,客戶端登錄成功之后,給其對(duì)應(yīng)的 Channel 綁定標(biāo)識(shí),下次只需要判斷該 Channel 是否有標(biāo)識(shí)即可知道其是否已經(jīng)登錄。

4.4 handler()

handler () 用于指定在服務(wù)端啟動(dòng)過(guò)程中的一些邏輯。

實(shí)例:

//省略了其它模板代碼
serverBootstrap.handler(new ChannelInitializer<NioServerSocketChannel>() {
    protected void initChannel(NioServerSocketChannel ch) {
        System.out.println("服務(wù)端啟動(dòng)中");
    }
});

總結(jié),可以在服務(wù)端啟動(dòng)的過(guò)程中做一些初始化方面的工作,比如,讀取數(shù)據(jù)庫(kù)的配置數(shù)據(jù)放到緩存當(dāng)中,這個(gè)作為了解即可。

4.5 childHandler()

childHandler () 用于指定處理新連接數(shù)據(jù)的讀寫處理邏輯。

實(shí)例:

//省略了其它模板代碼
serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
    protected void initChannel(NioSocketChannel ch) {
        //責(zé)任鏈,指定自定義處理業(yè)務(wù)的 Handler
        ch.pipeline().addLast(new NettyServerHandler());
    }
});

總結(jié),這個(gè)是核心,主要管理業(yè)務(wù)邏輯處理雙向鏈表,后面會(huì)具體講解

4.6 option()

option () 給服務(wù)端 channel 設(shè)置一些屬性,最常見(jiàn)的就是 so_backlog。

實(shí)例:

//省略了其它模板代碼
serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024)

表示系統(tǒng)用于臨時(shí)存放已完成三次握手的請(qǐng)求的隊(duì)列的最大長(zhǎng)度,如果連接建立頻繁,服務(wù)器處理創(chuàng)建新連接較慢,可以適當(dāng)調(diào)大這個(gè)參數(shù)。其實(shí),客戶端請(qǐng)求在服務(wù)端也是排隊(duì)執(zhí)行的,服務(wù)端的兩大線程組分別監(jiān)聽(tīng)客戶端連接和處理客戶端連接,一旦并發(fā)量很高的時(shí)候,服務(wù)端處理不過(guò)來(lái),則會(huì)把等待處理的請(qǐng)求放入到臨時(shí)隊(duì)列里面,這個(gè)跟 Java 線程池的思想是一樣的。

4.7 childOption()

childOption () 給每條連接設(shè)置一些 TCP 底層相關(guān)的屬性。

實(shí)例:

//省略了其它模板代碼
serverBootstrap
        .childOption(ChannelOption.SO_KEEPALIVE, true)
        .childOption(ChannelOption.TCP_NODELAY, true)

代碼說(shuō)明:

  1. ChannelOption.SO_KEEPALIVE 表示是否開(kāi)啟 TCP 底層心跳機(jī)制,true 為開(kāi)啟;
  2. ChannelOption.TCP_NODELAY 表示是否開(kāi)啟 Nagle 算法,true 表示關(guān)閉,false 表示開(kāi)啟,通俗地說(shuō),如果要求高實(shí)時(shí)性,有數(shù)據(jù)發(fā)送時(shí)就馬上發(fā)送,就關(guān)閉,如果需要減少發(fā)送次數(shù)減少網(wǎng)絡(luò)交互,就開(kāi)啟。

5. 小結(jié)

本節(jié)學(xué)習(xí)的核心知識(shí)點(diǎn)掌握,具體如下:

  1. 四個(gè)核心流程,分別是①設(shè)置線程組;②設(shè)置 IO 模型;③指定連接讀寫處理邏輯;④綁定端口號(hào);
  2. 核心方法的使用場(chǎng)景,重點(diǎn)掌握①bind ();②childAttr ();③childHandler ();④childOption () 的使用。