《netty入門與實戰》筆記-02:服務端啟動流程

為什么80%的碼農都做不了架構師?>>> ??hot3.png

1.服務端啟動流程

這一小節,我們來學習一下如何使用 Netty 來啟動一個服務端應用程序,以下是服務端啟動的一個非常精簡的 Demo:

NettyServer.java

public class NettyServer {public static void main(String[] args) {NioEventLoopGroup bossGroup = new NioEventLoopGroup();NioEventLoopGroup workerGroup = new NioEventLoopGroup();ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<NioSocketChannel>() {protected void initChannel(NioSocketChannel ch) {}});serverBootstrap.bind(8000);}
}
  • 首先看到,我們創建了兩個NioEventLoopGroup,這兩個對象可以看做是傳統IO編程模型的兩大線程組,bossGroup表示監聽端口,accept 新連接的線程組,workerGroup表示處理每一條連接的數據讀寫的線程組。用生活中的例子來講就是,一個工廠要運作,必然要有一個老板負責從外面接活,然后有很多員工,負責具體干活,老板就是bossGroup,員工們就是workerGroupbossGroup接收完連接,扔給workerGroup去處理。
  • 接下來 我們創建了一個引導類 ServerBootstrap,這個類將引導我們進行服務端的啟動工作,直接new出來開搞。
  • 我們通過.group(bossGroup, workerGroup)給引導類配置兩大線程組,這個引導類的線程模型也就定型了。
  • 然后,我們指定我們服務端的 IO 模型為NIO,我們通過.channel(NioServerSocketChannel.class)來指定 IO 模型,當然,這里也有其他的選擇,如果你想指定 IO 模型為 BIO,那么這里配置上OioServerSocketChannel.class類型即可,當然通常我們也不會這么做,因為Netty的優勢就在于NIO。
  • 接著,我們調用childHandler()方法,給這個引導類創建一個ChannelInitializer,這里主要就是定義后續每條連接的數據讀寫,業務處理邏輯,不理解沒關系,在后面我們會詳細分析。ChannelInitializer這個類中,我們注意到有一個泛型參數NioSocketChannel,這個類呢,就是 Netty 對 NIO 類型的連接的抽象,而我們前面NioServerSocketChannel也是對 NIO 類型的連接的抽象,NioServerSocketChannelNioSocketChannel的概念可以和 BIO 編程模型中的ServerSocket以及Socket兩個概念對應上

我們的最小化參數配置到這里就完成了,我們總結一下就是,要啟動一個Netty服務端,必須要指定三類屬性,分別是線程模型、IO 模型、連接讀寫處理邏輯,有了這三者,之后在調用bind(8000),我們就可以在本地綁定一個 8000 端口啟動起來,以上這段代碼讀者可以直接拷貝到你的 IDE 中運行。

2.自動綁定遞增端口

在上面代碼中我們綁定了 8000 端口,接下來我們實現一個稍微復雜一點的邏輯,我們指定一個起始端口號,比如 1000,然后呢,我們從1000號端口往上找一個端口,直到這個端口能夠綁定成功,比如 1000 端口不可用,我們就嘗試綁定 1001,然后 1002,依次類推。

serverBootstrap.bind(8000);這個方法呢,它是一個異步的方法,調用之后是立即返回的,他的返回值是一個ChannelFuture,我們可以給這個ChannelFuture添加一個監聽器GenericFutureListener,然后我們在GenericFutureListeneroperationComplete方法里面,我們可以監聽端口是否綁定成功,接下來是監測端口是否綁定成功的代碼片段

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

我們接下來從 1000 端口號,開始往上找端口號,直到端口綁定成功,我們要做的就是在 if (future.isSuccess())else邏輯里面重新綁定一個遞增的端口號,接下來,我們把這段綁定邏輯抽取出一個bind方法

private static void bind(final ServerBootstrap serverBootstrap, final int port) {serverBootstrap.bind(port).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 + "]綁定失敗!");bind(serverBootstrap, port + 1);}}});
}

然后呢,以上代碼中最關鍵的就是在端口綁定失敗之后,重新調用自身方法,并且把端口號加一,然后,在我們的主流程里面,我們就可以直接調用

bind(serverBootstrap, 1000)

端口成功綁定了在1024,從 1000 開始到 1023,端口均綁定失敗了,這是因為在我的 MAC 系統下,1023 以下的端口號都是被系統保留了,需要 ROOT 權限才能綁定。

以上就是自動綁定遞增端口的邏輯,接下來,我們來一起學習一下,服務端啟動,我們的引導類ServerBootstrap除了指定線程模型,IO 模型,連接讀寫處理邏輯之外,他還可以干哪些事情?

3.服務端啟動其他方法

handler() 方法

serverBootstrap.handler(new ChannelInitializer<NioServerSocketChannel>() {protected void initChannel(NioServerSocketChannel ch) {System.out.println("服務端啟動中");}
})

handler()方法呢,可以和我們前面分析的childHandler()方法對應起來,childHandler()用于指定處理新連接數據的讀寫處理邏輯,handler()用于指定在服務端啟動過程中的一些邏輯,通常情況下呢,我們用不著這個方法。

attr() 方法

serverBootstrap.attr(AttributeKey.newInstance("serverName"), "nettyServer")

attr()方法可以給服務端的 channel,也就是NioServerSocketChannel指定一些自定義屬性,然后我們可以通過channel.attr()取出這個屬性,比如,上面的代碼我們指定我們服務端channel的一個serverName屬性,屬性值為nettyServer,其實說白了就是給NioServerSocketChannel維護一個map而已,通常情況下,我們也用不上這個方法。

那么,當然,除了可以給服務端 channel NioServerSocketChannel指定一些自定義屬性之外,我們還可以給每一條連接指定自定義屬性

childAttr() 方法

serverBootstrap.childAttr(AttributeKey.newInstance("clientKey"), "clientValue")

上面的childAttr可以給每一條連接指定自定義屬性,然后后續我們可以通過channel.attr()取出該屬性。

childOption() 方法

serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true).childOption(ChannelOption.TCP_NODELAY, true)

childOption()可以給每條連接設置一些TCP底層相關的屬性,比如上面,我們設置了兩種TCP屬性,其中

  • ChannelOption.SO_KEEPALIVE表示是否開啟TCP底層心跳機制,true為開啟
  • ChannelOption.TCP_NODELAY表示是否開始Nagle算法,true表示關閉,false表示開啟,通俗地說,如果要求高實時性,有數據發送時就馬上發送,就關閉,如果需要減少發送次數減少網絡交互,就開啟。

其他的參數這里就不一一講解,有興趣的同學可以去這個類里面自行研究。

option() 方法

除了給每個連接設置這一系列屬性之外,我們還可以給服務端channel設置一些屬性,最常見的就是so_backlog,如下設置

serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024)

表示系統用于臨時存放已完成三次握手的請求的隊列的最大長度,如果連接建立頻繁,服務器處理創建新連接較慢,可以適當調大這個參數

4.總結

  • 本文中,我們首先學習了 Netty 服務端啟動的流程,一句話來說就是:創建一個引導類,然后給他指定線程模型,IO模型,連接讀寫處理邏輯,綁定端口之后,服務端就啟動起來了。
  • 然后,我們學習到 bind 方法是異步的,我們可以通過這個異步機制來實現端口遞增綁定。
  • 最后呢,我們討論了 Netty 服務端啟動額外的參數,主要包括給服務端 Channel 或者客戶端 Channel 設置屬性值,設置底層 TCP 參數。

以上內容來源于掘金小冊《Netty 入門與實戰:仿寫微信 IM 即時通訊系統》,若想獲得更多,更詳細的內容,請用微信掃碼訂閱:

轉載于:https://my.oschina.net/funcy/blog/2242215

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389527.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389527.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389527.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

譜聚類思想及實現

&#xff08;這個我也沒有怎么懂&#xff0c;為了防止以后能用上&#xff0c;還是記錄下來&#xff09; 譜聚類 注意&#xff1a;譜聚類核心聚類算法還是K-means 算法進行聚類~ 譜聚類的實現過程&#xff1a; 1.根據數據構造一個 圖結構&#xff08;Graph&#xff09; &…

Tengine HTTPS原理解析、實踐與調試【轉】

本文邀請阿里云CDN HTTPS技術專家金九&#xff0c;分享Tengine的一些HTTPS實踐經驗。內容主要有四個方面&#xff1a;HTTPS趨勢、HTTPS基礎、HTTPS實踐、HTTPS調試。 一、HTTPS趨勢 這一章節主要介紹近幾年和未來HTTPS的趨勢&#xff0c;包括兩大瀏覽器chrome和firefox對HTTPS的…

Linux 指定運行時動態庫路徑【轉】

轉自&#xff1a;http://www.cnblogs.com/cute/archive/2011/02/24/1963957.html 眾所周知&#xff0c; Linux 動態庫的默認搜索路徑是 /lib 和 /usr/lib 。動態庫被創建后&#xff0c;一般都復制到這兩個目錄中。當程序執行時需要某動態庫&#xff0c; 并且該動態庫還未加載到…

opencv:SIFT——尺度不變特征變換

SIFT概念&#xff1a; Sift&#xff08;尺度不變特征變換&#xff09;&#xff0c;全稱是Scale Invariant Feature Transform Sift提取圖像的局部特征&#xff0c;在尺度空間尋找極值點&#xff0c;并提取出其位置、尺度、方向信息。 Sfit的應用范圍包括 物體辨別、機器人地圖…

pca(主成分分析技術)_主成分分析技巧

pca(主成分分析技術)介紹 (Introduction) Principal Component Analysis (PCA) is an unsupervised technique for dimensionality reduction.主成分分析(PCA)是一種無監督的降維技術。 What is dimensionality reduction?什么是降維&#xff1f; Let us start with an exam…

npm link run npm script

npm link & run npm script https://blog.csdn.net/juhaotian/article/details/78672390 npm link命令可以將一個任意位置的npm包鏈接到全局執行環境&#xff0c;從而在任意位置使用命令行都可以直接運行該npm包。 app-cmd.cmd #!/usr/bin/env nodeecho "666" &a…

一文詳解java中對JVM的深度解析、調優工具、垃圾回收

2019獨角獸企業重金招聘Python工程師標準>>> jvm監控分析工具一般分為兩類&#xff0c;一種是jdk自帶的工具&#xff0c;一種是第三方的分析工具。jdk自帶工具一般在jdk bin目錄下面&#xff0c;以exe的形式直接點擊就可以使用&#xff0c;其中包含分析工具已經很強…

借用繼承_博物館正在數字化,并在此過程中從數據中借用

借用繼承Data visualization is a great way to celebrate our favorite pieces of art as well as reveal connections and ideas that were previously invisible. More importantly, it’s a fun way to connect things we love — visualizing data and kicking up our fee…

高斯噪聲,椒鹽噪聲的思想及多種噪聲的實現

圖像噪聲&#xff1a; 概念&#xff1a; ? 圖像噪聲是圖像在獲取或是傳輸過程中受到隨機信號干擾&#xff0c;妨礙人們對圖像理解及分析處理 的信號。 ? 很多時候將圖像噪聲看做多維隨機過程&#xff0c;因而描述噪聲的方法完全可以借用隨機過程的描述&#xff0c; 也就是使…

bzoj1095 [ZJOI2007]Hide 捉迷藏

據說是道很厲害的題。。。。黃學長的安利啊。。。。 然而我卻用它學分治。。。。 一個坑就擺在這里了。。。。 轉載于:https://www.cnblogs.com/LLppdd/p/9124394.html

如何識別媒體偏見_描述性語言理解,以識別文本中的潛在偏見

如何識別媒體偏見TGumGum can do to bring change by utilizing our Natural Language Processing technology to shed light on potential bias that websites may have in their content. The ideas and techniques shared in this blog are a result of the GumGum Hackatho…

分享 : 警惕MySQL運維陷阱:基于MyCat的偽分布式架構

分布式數據庫已經進入了全面快速發展階段。這種發展是與時俱進的&#xff0c;與人的需求分不開&#xff0c;因為現在信息時代的高速發展&#xff0c;導致數據量和交易量越來越大。這種現象首先導致的就是存儲瓶頸&#xff0c;因為MySQL數據庫實質上還是一個單機版本的數據庫&am…

opencv:圖像讀取BGR變成RGB

opencv大坑之BGR opencv對于讀進來的圖片的通道排列是BGR&#xff0c;而不是主流的RGB&#xff01;謹記&#xff01; #opencv讀入的矩陣是BGR&#xff0c;如果想轉為RGB&#xff0c;可以這么轉 img cv2.imread(1.jpg) img cv2.cvtColor(img4,cv2.COLOR_BGR2RGB)

數據不平衡處理_如何處理多類不平衡數據說不可以

數據不平衡處理重點 (Top highlight)One of the common problems in Machine Learning is handling the imbalanced data, in which there is a highly disproportionate in the target classes.機器學習中的常見問題之一是處理不平衡的數據&#xff0c;其中目標類別的比例非常…

最小二乘法以及RANSAC(隨機采樣一致性)思想及實現

線性回歸–最小二乘法&#xff08;Least Square Method&#xff09; 線性回歸&#xff1a; 什么是線性回歸&#xff1f; 舉個例子&#xff0c;某商品的利潤在售價為2元、5元、10元時分別為4元、10元、20元&#xff0c; 我們很容易得出商品的利潤與售價的關系符合直線&#xf…

軟鍵盤彈起,導致底部被頂上去

計算出可視界面的高度&#xff0c;當軟鍵盤彈起時讓底部元素隱藏掉&#xff0c;當鍵盤收起時再讓它顯示&#xff0c;實在沒辦法時這種方法也不失為一種方法1 var hdocument.documentElement.clientHeight; 2 $(window).resize(function(){ 3 let heightdocument.documentEl…

關于LaaS,PaaS,SaaS一些個人的理解

關于LaaS,PaaS,SaaS一些個人的理解 關于LaaS,PaaS,SaaS一些個人的理解 其實如果從整個程序運營的角度來考慮比較好 第一個LaaS 這個也叫做Haas 就是硬件或者基礎設置即服務 比如現在的 aws azure 阿里云 騰訊云 百度云 都是提供服務器基礎設置服務的 包括服務器的硬件…

糖藥病數據集分類_使用optuna和mlflow進行心臟病分類器調整

糖藥病數據集分類背景 (Background) Data science should be an enjoyable process focused on delivering insights and real benefits. However, that enjoyment can sometimes get lost in tools and processes. Nowadays it is important for an applied data scientist to…

Android MVP 框架

為什么80%的碼農都做不了架構師&#xff1f;>>> 前言 根據網絡上的MVP套路寫了一個辣雞MVP DEMO 用到的 android studio MVPHelper插件,方便自動生成框架代碼rxjavaretrofit什么是MVP MVP就是英文的Model View Presenter&#xff0c;然而實際分包并不是只有這三個包…

相似圖像搜索的哈希算法思想及實現(差值哈希算法和均值哈希算法)

圖像相似度比較哈希算法: 什么是哈希&#xff08;Hash&#xff09;&#xff1f; ? 散列函數&#xff08;或散列算法&#xff0c;又稱哈希函數&#xff0c;英語&#xff1a;Hash Function&#xff09;是一種從任何一種數據中創建小 的數字“指紋”的方法。散列函數把消息或數…