2021最新版BAT大廠Netty面試題集(有詳盡答案)

      網(wǎng)友投稿 806 2025-03-31

      辯明 BIO、NIO 和 AIO


      BIO

      單向流且阻塞。

      一個(gè)連接一個(gè)線程,客戶端有連接請求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程去處理。線程開銷大。

      2021最新版BAT大廠Netty面試題集(有詳盡答案)

      偽異步 IO

      將請求連接放入線程池,一對(duì)多。

      NIO

      面向緩沖區(qū)。NIO 的 channel 是雙向的。

      一個(gè)請求一個(gè)線程,但客戶端發(fā)送的連接請求都會(huì)注冊到多路復(fù)用器,多路復(fù)用 器輪詢到連接有 I/O 請求時(shí)才啟動(dòng)一個(gè)線程去處理。

      NIO 的特點(diǎn):事件驅(qū)動(dòng)模型、單線程處理多任務(wù)、非阻塞 I/O,I/O 讀寫不再阻塞,而是返 回 0、基于 block 的傳輸比基于流的傳輸更高效、更高級(jí)的 IO 函數(shù) zero-copy、IO 多路復(fù)用 大大提高了 Java 網(wǎng)絡(luò)應(yīng)用的可伸縮性和實(shí)用性。基于 Reactor 線程模型。

      在 Reactor 模式中,事件分發(fā)器等待某個(gè)事件或者可應(yīng)用或個(gè)操作的狀態(tài)發(fā)生,事件分發(fā) 器就把這個(gè)事件傳給事先注冊的事件處理函數(shù)或者回調(diào)函數(shù),由后者來做實(shí)際的讀寫操 作。如在 Reactor 中實(shí)現(xiàn)讀:注冊讀就緒事件和相應(yīng)的事件處理器、事件分發(fā)器等待事 件、事件到來,激活分發(fā)器,分發(fā)器調(diào)用事件對(duì)應(yīng)的處理器、事件處理器完成實(shí)際的讀操 作,處理讀到的數(shù)據(jù),注冊新的事件,然后返還控制權(quán)。

      AIO

      一個(gè)有效請求一個(gè)線程,客戶端的 I/O 請求都是由 OS 先完成,再通知服務(wù)器應(yīng)用去啟動(dòng)線程去處理。

      NIO 的組成

      Buffer:與 Channel 進(jìn)行交互,數(shù)據(jù)是從 Channel 讀入緩沖區(qū),從緩沖區(qū)寫入 Channel 中的

      flip方法 : 反轉(zhuǎn)此緩沖區(qū),將position給limit,然后將position置為0,其實(shí)就是切換讀 寫模式

      clear 方法 :清除此緩沖區(qū),將 position 置為 0,把 capacity 的值給 limit。

      rewind 方法 : 重繞此緩沖區(qū),將 position 置為 0

      DirectByteBuffer 可減少一次系統(tǒng)空間到用戶空間的拷貝。但 Buffer 創(chuàng)建和銷毀的成本更 高,不可控,通常會(huì)用內(nèi)存池來提高性能。直接緩沖區(qū)主要分配給那些易受基礎(chǔ)系統(tǒng)的本 機(jī) I/O 操作影響的大型、持久的緩沖區(qū)。如果數(shù)據(jù)量比較小的中小應(yīng)用情況下,可以考慮 使用 heapBuffer,由 JVM 進(jìn)行管理。

      Channel

      表示 IO 源與目標(biāo)打開的連接,雙向,但不能直接訪問數(shù)據(jù),只能與Buffer 交互。FileChannel 的 read 方法和 write 方法都會(huì)導(dǎo)致數(shù)據(jù)復(fù)制兩次。

      Selector

      可使一個(gè)單獨(dú)的線程管理多個(gè) Channel,open 方法可創(chuàng)建 Selector,register 方法向多路復(fù)用器器注冊通道,可以監(jiān)聽的事件類型:讀、寫、連接、accept。注冊事件后會(huì)產(chǎn)生一個(gè) SelectionKey:它表示 SelectableChannel 和 Selector 之間的注冊關(guān)系,wakeup 方 法:使尚未返回的第一個(gè)選擇操作立即返回,喚醒的原因是:注冊了新的 channel 或者事 件;channel 關(guān)閉,取消注冊;優(yōu)先級(jí)更高的事件觸發(fā)(如定時(shí)器事件),希望及時(shí)處理。

      Selector 在 Linux 的實(shí)現(xiàn)類是 EPollSelectorImpl,委托給 EPollArrayWrapper 實(shí)現(xiàn),其中三個(gè)

      native 方法是對(duì) epoll 的封裝,而 EPollSelectorImpl. implRegister 方法,通過調(diào)用 epoll_ctl 向 epoll 實(shí)例中注冊事件,還將注冊的文件描述符(fd)與 SelectionKey 的對(duì)應(yīng)關(guān)系添加到 fdToKey 中,這個(gè) map 維護(hù)了文件描述符與 SelectionKey 的映射。

      fdToKey 有時(shí)會(huì)變得非常大,因?yàn)樽缘?Selector 上的 Channel 非常多(百萬連接);過期 或失效的 Channel 沒有及時(shí)關(guān)閉。fdToKey 總是串行讀取的,而讀取是在 select 方法中進(jìn)行 的,該方法是非線程安全的。

      Pipe:兩個(gè)線程之間的單向數(shù)據(jù)連接,數(shù)據(jù)會(huì)被寫到 sink 通道,從 source 通道讀取

      NIO 的服務(wù)端建立過程:Selector.open():打開一個(gè) Selector;ServerSocketChannel.open(): 創(chuàng)建服務(wù)端的 Channel;bind():綁定到某個(gè)端口上。并配置非阻塞模式;register():注冊 Channel 和關(guān)注的事件到 Selector 上;select()輪詢拿到已經(jīng)就緒的事件

      Netty 的特點(diǎn)?

      一個(gè)高性能、異步事件驅(qū)動(dòng)的 NIO 框架,它提供了對(duì) TCP、UDP 和文件傳輸的支持 使用更高效的 socket 底層,對(duì) epoll 空輪詢引起的 cpu 占用飆升在內(nèi)部進(jìn)行了處理,避免 了直接使用 NIO 的陷阱,簡化了 NIO 的處理方式。

      采用多種 decoder/encoder 支持,對(duì) TCP 粘包/分包進(jìn)行自動(dòng)化處理 可使用接受/處理線程池,提高連接效率,對(duì)重連、心跳檢測的簡單支持 可配置IO線程數(shù)、TCP參數(shù), TCP接收和發(fā)送緩沖區(qū)使用直接內(nèi)存代替堆內(nèi)存,通過內(nèi)存 池的方式循環(huán)利用 ByteBuf

      通過引用計(jì)數(shù)器及時(shí)申請釋放不再引用的對(duì)象,降低了 GC 頻率 使用單線程串行化的方式,高效的 Reactor 線程模型

      大量使用了 volitale、使用了 CAS 和原子類、線程安全類的使用、讀寫鎖的使用

      Netty 的線程模型?

      Netty 通過 Reactor 模型基于多路復(fù)用器接收并處理用戶請求,內(nèi)部實(shí)現(xiàn)了兩個(gè)線程池, boss 線程池和 work 線程池,其中 boss 線程池的線程負(fù)責(zé)處理請求的 accept 事件,當(dāng)接收 到 accept 事件的請求時(shí),把對(duì)應(yīng)的 socket 封裝到一個(gè) NioSocketChannel 中,并交給 work 線程池,其中 work 線程池負(fù)責(zé)請求的 read 和 write 事件,由對(duì)應(yīng)的 Handler 處理。

      單線程模型:所有 I/O 操作都由一個(gè)線程完成,即多路復(fù)用、事件分發(fā)和處理都是在一個(gè) Reactor 線程上完成的。既要接收客戶端的連接請求,向服務(wù)端發(fā)起連接,又要發(fā)送/讀取請 求或應(yīng)答/響應(yīng)消息。一個(gè) NIO 線程同時(shí)處理成百上千的鏈路,性能上無法支撐,速度 慢,若線程進(jìn)入死循環(huán),整個(gè)程序不可用,對(duì)于高負(fù)載、大并發(fā)的應(yīng)用場景不合適。

      多線程模型:有一個(gè)NIO 線程(Acceptor) 只負(fù)責(zé)監(jiān)聽服務(wù)端,接收客戶端的TCP 連接 請求;NIO 線程池負(fù)責(zé)網(wǎng)絡(luò)IO 的操作,即消息的讀取、解碼、編碼和發(fā)送;1 個(gè)NIO 線 程可以同時(shí)處理N 條鏈路,但是1 個(gè)鏈路只對(duì)應(yīng)1 個(gè)NIO 線程,這是為了防止發(fā)生并發(fā) 操作問題。但在并發(fā)百萬客戶端連接或需要安全認(rèn)證時(shí),一個(gè)Acceptor 線程可能會(huì)存在性 能不足問題。

      主從多線程模型:Acceptor 線程用于綁定監(jiān)聽端口,接收客戶端連接,將 SocketChannel 從主線程池的Reactor 線程的多路復(fù)用器上移除,重新注冊到Sub 線程池的線程上,用于

      處理 I/O 的讀寫等操作,從而保證 mainReactor 只負(fù)責(zé)接入認(rèn)證、握手等操作;

      TCP 粘包/拆包的原因及解決方法?

      TCP 是以流的方式來處理數(shù)據(jù),一個(gè)完整的包可能會(huì)被 TCP 拆分成多個(gè)包進(jìn)行發(fā)送,也可 能把小的封裝成一個(gè)大的數(shù)據(jù)包發(fā)送。

      TCP 粘包/分包的原因:

      應(yīng)用程序?qū)懭氲淖止?jié)大小大于套接字發(fā)送緩沖區(qū)的大小,會(huì)發(fā)生拆包現(xiàn)象,而應(yīng)用程序?qū)?入數(shù)據(jù)小于套接字緩沖區(qū)大小,網(wǎng)卡將應(yīng)用多次寫入的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上,這將會(huì)發(fā)生粘 包現(xiàn)象;

      進(jìn)行 MSS 大小的 TCP 分段,當(dāng) TCP 報(bào)文長度-TCP 頭部長度>MSS 的時(shí)候?qū)l(fā)生拆包 以太網(wǎng)幀的 payload(凈荷)大于 MTU(1500 字節(jié))進(jìn)行 ip 分片。

      解決方法

      消息定長:FixedLengthFrameDecoder 類 包尾增加特殊字符分割:行分隔符類:LineBasedFrameDecoder 或自定義分隔符類 : DelimiterBasedFrameDecoder

      將消息分為消息頭和消息體:LengthFieldBasedFrameDecoder 類。分為有頭部的拆包與粘 包、長度字段在前且有頭部的拆包與粘包、多擴(kuò)展頭部的拆包與粘包。

      了解哪幾種序列化協(xié)議?

      序列化(編碼)是將對(duì)象序列化為二進(jìn)制形式(字節(jié)數(shù)組),主要用于網(wǎng)絡(luò)傳輸、數(shù)據(jù)持久 化等;而反序列化(解碼)則是將從網(wǎng)絡(luò)、磁盤等讀取的字節(jié)數(shù)組還原成原始對(duì)象,主要 用于網(wǎng)絡(luò)傳輸對(duì)象的解碼,以便完成遠(yuǎn)程調(diào)用。

      影響序列化性能的關(guān)鍵因素:序列化后的碼流大小(網(wǎng)絡(luò)帶寬的占用)、序列化的性能 (CPU 資源占用);是否支持跨語言(異構(gòu)系統(tǒng)的對(duì)接和開發(fā)語言切換)。

      Java 默認(rèn)提供的序列化:無法跨語言、序列化后的碼流太大、序列化的性能差

      XML,優(yōu)點(diǎn):人機(jī)可讀性好,可指定元素或特性的名稱。缺點(diǎn):序列化數(shù)據(jù)只包含數(shù)據(jù)本 身以及類的結(jié)構(gòu),不包括類型標(biāo)識(shí)和程序集信息;只能序列化公共屬性和字段;不能序列 化方法;文件龐大,文件格式復(fù)雜,傳輸占帶寬。適用場景:當(dāng)做配置文件存儲(chǔ)數(shù)據(jù),實(shí) 時(shí)數(shù)據(jù)轉(zhuǎn)換。

      JSON,是一種輕量級(jí)的數(shù)據(jù)交換格式,優(yōu)點(diǎn):兼容性高、數(shù)據(jù)格式比較簡單,易于讀寫、 序列化后數(shù)據(jù)較小,可擴(kuò)展性好,兼容性好、與 XML 相比,其協(xié)議比較簡單,解析速度比 較快。缺點(diǎn):數(shù)據(jù)的描述性比 XML 差、不適合性能要求為 ms 級(jí)別的情況、額外空間開銷 比較大。適用場景(可替代XML):跨防火墻訪問、可調(diào)式性要求高、基于 Web browser 的 Ajax 請求、傳輸數(shù)據(jù)量相對(duì)小,實(shí)時(shí)性要求相對(duì)低(例如秒級(jí)別)的服務(wù)。

      Fastjson,采用一種“假定有序快速匹配”的算法。優(yōu)點(diǎn):接口簡單易用、目前 java 語言中 最快的 json 庫。缺點(diǎn):過于注重快,而偏離了“標(biāo)準(zhǔn)”及功能性、代碼質(zhì)量不高,文檔不 全。適用場景:協(xié)議交互、Web 輸出、Android 客戶端

      Thrift,不僅是序列化協(xié)議,還是一個(gè) RPC 框架。優(yōu)點(diǎn):序列化后的體積小, 速度快、支持 多種語言和豐富的數(shù)據(jù)類型、對(duì)于數(shù)據(jù)字段的增刪具有較強(qiáng)的兼容性、支持二進(jìn)制壓縮編 碼。缺點(diǎn):使用者較少、跨防火墻訪問時(shí),不安全、不具有可讀性,調(diào)試代碼時(shí)相對(duì)困 難、不能與其他傳輸層協(xié)議共同使用(例如 HTTP)、無法支持向持久層直接讀寫數(shù)據(jù),即 不適合做數(shù)據(jù)持久化序列化協(xié)議。適用場景:分布式系統(tǒng)的 RPC 解決方案

      Avro,Hadoop 的一個(gè)子項(xiàng)目,解決了 JSON 的冗長和沒有 IDL 的問題。優(yōu)點(diǎn):支持豐富的 數(shù)據(jù)類型、簡單的動(dòng)態(tài)語言結(jié)合功能、具有自我描述屬性、提高了數(shù)據(jù)解析速度、快速可 壓縮的二進(jìn)制數(shù)據(jù)形式、可以實(shí)現(xiàn)遠(yuǎn)程過程調(diào)用 RPC、支持跨編程語言實(shí)現(xiàn)。缺點(diǎn):對(duì)于 習(xí)慣于靜態(tài)類型語言的用戶不直觀。適用場景:在 Hadoop 中做 Hive、Pig 和 MapReduce 的持久化數(shù)據(jù)格式。

      Protobuf,將數(shù)據(jù)結(jié)構(gòu)以.proto 文件進(jìn)行描述,通過代碼生成工具可以生成對(duì)應(yīng)數(shù)據(jù)結(jié)構(gòu)的 POJO 對(duì)象和 Protobuf 相關(guān)的方法和屬性。優(yōu)點(diǎn):序列化后碼流小,性能高、結(jié)構(gòu)化數(shù)據(jù)存 儲(chǔ)格式(XML JSON 等)、通過標(biāo)識(shí)字段的順序,可以實(shí)現(xiàn)協(xié)議的前向兼容、結(jié)構(gòu)化的文檔 更容易管理和維護(hù)。缺點(diǎn):需要依賴于工具生成代碼、支持的語言相對(duì)較少,官方只支持 Java 、C++ 、python。適用場景:對(duì)性能要求高的RPC調(diào)用、具有良好的跨防火墻的訪問 屬性、適合應(yīng)用層對(duì)象的持久化

      其它

      protostuff 基于 protobuf 協(xié)議,但不需要配置 proto 文件,直接導(dǎo)包即可 Jboss marshaling 可以直接序列化 java 類, 無須實(shí) java.io.Serializable 接口 Message pack 一個(gè)高效的二進(jìn)制序列化格式

      Hessian 采用二進(jìn)制協(xié)議的輕量級(jí) remoting onhttp 工具

      kryo 基于 protobuf 協(xié)議,只支持 java 語言,需要注冊(Registration),然后序列化 (Output),反序列化(Input)

      如何選擇序列化協(xié)議?

      具體場景

      對(duì)于公司間的系統(tǒng)調(diào)用,如果性能要求在 100ms 以上的服務(wù),基于 XML 的 SOAP 協(xié)議是一 個(gè)值得考慮的方案。

      基于 Web browser 的 Ajax,以及 Mobile app 與服務(wù)端之間的通訊,JSON 協(xié)議是首選。對(duì)于 性能要求不太高,或者以動(dòng)態(tài)類型語言為主,或者傳輸數(shù)據(jù)載荷很小的的運(yùn)用場景,JSON 也是非常不錯(cuò)的選擇。

      對(duì)于調(diào)試環(huán)境比較惡劣的場景,采用 JSON 或 XML 能夠極大的提高調(diào)試效率,降低系統(tǒng)開 發(fā)成本。

      當(dāng)對(duì)性能和簡潔性有極高要求的場景,Protobuf,Thrift,Avro 之間具有一定的競爭關(guān)系。 對(duì)于 T 級(jí)別的數(shù)據(jù)的持久化應(yīng)用場景,Protobuf 和 Avro 是首要選擇。如果持久化后的數(shù)據(jù) 存儲(chǔ)在 hadoop 子項(xiàng)目里,Avro 會(huì)是更好的選擇。

      對(duì)于持久層非 Hadoop 項(xiàng)目,以靜態(tài)類型語言為主的應(yīng)用場景,Protobuf 會(huì)更符合靜態(tài)類 型語言工程師的開發(fā)習(xí)慣。由于 Avro 的設(shè)計(jì)理念偏向于動(dòng)態(tài)類型語言,對(duì)于動(dòng)態(tài)語言為主 的應(yīng)用場景,Avro 是更好的選擇。

      如果需要提供一個(gè)完整的 RPC 解決方案,Thrift 是一個(gè)好的選擇。 如果序列化之后需要支持不同的傳輸層協(xié)議,或者需要跨防火墻訪問的高性能場景, Protobuf 可以優(yōu)先考慮。

      protobuf 的數(shù)據(jù)類型有多種:bool、double、float、int32、int64、string、bytes、enum、 message。protobuf的限定符:required: 必須賦值,不能為空、optional:字段可以賦值,也 可以不賦值、repeated: 該字段可以重復(fù)任意次數(shù)(包括 0 次)、枚舉;只能用指定的常量 集中的一個(gè)值作為其值;

      protobuf 的基本規(guī)則:每個(gè)消息中必須至少留有一個(gè) required 類型的字段、包含 0 個(gè)或多 個(gè) optional 類型的字段;repeated 表示的字段可以包含 0 個(gè)或多個(gè)數(shù)據(jù);[1,15]之內(nèi)的標(biāo)識(shí) 號(hào)在編碼的時(shí)候會(huì)占用一個(gè)字節(jié)(常用),[16,2047]之內(nèi)的標(biāo)識(shí)號(hào)則占用 2 個(gè)字節(jié),標(biāo)識(shí)號(hào) 一定不能重復(fù)、使用消息類型,也可以將消息嵌套任意多層,可用嵌套消息類型來代替 組。

      protobuf 的消息升級(jí)原則:不要更改任何已有的字段的數(shù)值標(biāo)識(shí);不能移除已經(jīng)存在的 required 字段,optional 和 repeated 類型的字段可以被移除,但要保留標(biāo)號(hào)不能被重用。 新添加的字段必須是 optional 或 repeated。因?yàn)榕f版本程序無法讀取或?qū)懭胄略龅?required 限定符的字段。

      編譯器為每一個(gè)消息類型生成了一個(gè).java 文件,以及一個(gè)特殊的 Builder 類(該類是用來創(chuàng) 建消息類接口的)。如:UserProto.User.Builder builder = UserProto.User.newBuilder();builder.build();

      Netty 中的使用:ProtobufVarint32FrameDecoder 是用于處理半包消息的解碼類; ProtobufDecoder(UserProto.User.getDefaultInstance())這是創(chuàng)建的 UserProto.java 文件中的解 碼類;ProtobufVarint32LengthFieldPrepender 對(duì) protobuf 協(xié)議的消息頭上加上一個(gè)長度為 32 的整形字段,用于標(biāo)志這個(gè)消息的長度的類;ProtobufEncoder 是編碼類

      將 StringBuilder 轉(zhuǎn)換為 ByteBuf 類型:copiedBuffer()方法

      Netty 的零拷貝實(shí)現(xiàn)?

      Netty 的接收和發(fā)送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接內(nèi)存進(jìn)行 Socket 讀 寫,不需要進(jìn)行字節(jié)緩沖區(qū)的二次拷貝。堆內(nèi)存多了一次內(nèi)存拷貝,JVM 會(huì)將堆內(nèi)存 Buffer 拷貝一份到直接內(nèi)存中,然后才寫入 Socket 中。ByteBuffer 由 ChannelConfig 分配, 而 ChannelConfig 創(chuàng)建 ByteBufAllocator 默認(rèn)使用 Direct Buffer

      CompositeByteBuf 類可以將多個(gè) ByteBuf 合并為一個(gè)邏輯上的 ByteBuf, 避免了傳統(tǒng)通過 內(nèi)存拷貝的方式將幾個(gè)小 Buffer 合并成一個(gè)大的 Buffer。addComponents 方法將 header 與 body 合并為一個(gè)邏輯上的 ByteBuf, 這兩個(gè) ByteBuf 在 CompositeByteBuf 內(nèi)部都是單 獨(dú)存在的, CompositeByteBuf 只是邏輯上是一個(gè)整體

      通過 FileRegion 包裝的 FileChannel.tranferTo 方法 實(shí)現(xiàn)文件傳輸, 可以直接將文件緩沖區(qū) 的數(shù)據(jù)發(fā)送到目標(biāo) Channel,避免了傳統(tǒng)通過循環(huán) write 方式導(dǎo)致的內(nèi)存拷貝問題。

      通過 wrap 方法, 我們可以將 byte[] 數(shù)組、ByteBuf、ByteBuffer 等包裝成一個(gè) Netty ByteBuf 對(duì)象, 進(jìn)而避免了拷貝操作。

      Selector BUG:若 Selector 的輪詢結(jié)果為空,也沒有 wakeup 或新消息處理,則發(fā)生空輪 詢,CPU 使用率 100%,

      Netty 的解決辦法:對(duì) Selector 的 select 操作周期進(jìn)行統(tǒng)計(jì),每完成一次空的 select 操作進(jìn) 行一次計(jì)數(shù),若在某個(gè)周期內(nèi)連續(xù)發(fā)生 N 次空輪詢,則觸發(fā)了 epoll 死循環(huán) bug。重建 Selector,判斷是否是其他線程發(fā)起的重建請求,若不是則將原 SocketChannel 從舊的 Selector 上去除注冊,重新注冊到新的 Selector 上,并將原來的 Selector 關(guān)閉。

      Netty 的高性能表現(xiàn)在哪些方面?

      心跳,對(duì)服務(wù)端:會(huì)定時(shí)清除閑置會(huì)話 inactive(netty5),對(duì)客戶端:用來檢測會(huì)話是否斷 開,是否重來,檢測網(wǎng)絡(luò)延遲,其中 idleStateHandler 類 用來檢測會(huì)話狀態(tài)

      串行無鎖化設(shè)計(jì),即消息的處理盡可能在同一個(gè)線程內(nèi)完成,期間不進(jìn)行線程切換,這樣 就避免了多線程競爭和同步鎖。表面上看,串行化設(shè)計(jì)似乎 CPU 利用率不高,并發(fā)程度不 夠。但是,通過調(diào)整 NIO 線程池的線程參數(shù),可以同時(shí)啟動(dòng)多個(gè)串行化的線程并行運(yùn)行, 這種局部無鎖化的串行線程設(shè)計(jì)相比一個(gè)隊(duì)列-多個(gè)工作線程模型性能更優(yōu)。

      可靠性,鏈路有效性檢測:鏈路空閑檢測機(jī)制,讀/寫空閑超時(shí)機(jī)制;內(nèi)存保護(hù)機(jī)制:通過 內(nèi)存池重用 ByteBuf;ByteBuf 的解碼保護(hù);優(yōu)雅停機(jī):不再接收新消息、退出前的預(yù)處理操 作、資源的釋放操作。

      Netty安全性:支持的安全協(xié)議:SSL V2和V3,TLS,SSL單向認(rèn)證、雙向認(rèn)證和第三方CA 認(rèn)證。

      高效并發(fā)編程的體現(xiàn):volatile 的大量、正確使用;CAS 和原子類的廣泛使用;線程安全容 器的使用;通過讀寫鎖提升并發(fā)性能。IO 通信性能三原則:傳輸(AIO)、協(xié)議(Http)、線 程(主從多線程)

      流量整型的作用(變壓器):防止由于上下游網(wǎng)元性能不均衡導(dǎo)致下游網(wǎng)元被壓垮,業(yè)務(wù) 流中斷;防止由于通信模塊接受消息過快,后端業(yè)務(wù)線程處理不及時(shí)導(dǎo)致?lián)嗡绬栴}。

      TCP 參數(shù)配置:SO_RCVBUF 和 SO_SNDBUF:通常建議值為 128K 或者 256K; SO_TCPNODELAY:NAGLE 算法通過將緩沖區(qū)內(nèi)的小封包自動(dòng)相連,組成較大的封包,阻止 大量小封包的發(fā)送阻塞網(wǎng)絡(luò),從而提高網(wǎng)絡(luò)應(yīng)用效率。但是對(duì)于時(shí)延敏感的應(yīng)用場景需要 關(guān)閉該優(yōu)化算法;

      NIOEventLoopGroup 源碼?

      NioEventLoopGroup(其實(shí)是 MultithreadEventExecutorGroup) 內(nèi)部維護(hù)一個(gè)類型為 EventExecutor children [], 默認(rèn)大小是處理器核數(shù) * 2, 這樣就構(gòu)成了一個(gè)線程池,初始化

      EventExecutor 時(shí) NioEventLoopGroup 重載 newChild 方法,所以 children 元素的實(shí)際類型為 NioEventLoop。

      線程啟動(dòng)時(shí)調(diào)用 SingleThreadEventExecutor 的構(gòu)造方法,執(zhí)行 NioEventLoop 類的 run 方 法,首先會(huì)調(diào)用 hasTasks()方法判斷當(dāng)前 taskQueue 是否有元素。如果 taskQueue 中有元 素,執(zhí)行 selectNow() 方法,最終執(zhí)行 selector.selectNow(),該方法會(huì)立即返回。如果 taskQueue 沒有元素,執(zhí)行 select(oldWakenUp) 方法

      select ( oldWakenUp) 方法解決了 Nio 中的 bug,selectCnt 用來記錄 selector.select 方法的 執(zhí)行次數(shù)和標(biāo)識(shí)是否執(zhí)行過 selector.selectNow(),若觸發(fā)了 epoll 的空輪詢 bug,則會(huì)反復(fù) 執(zhí)行selector.select(timeoutMillis),變量selectCnt 會(huì)逐漸變大,當(dāng)selectCnt 達(dá)到閾值(默 認(rèn) 512),則執(zhí)行 rebuildSelector 方法,進(jìn)行 selector 重建,解決 cpu 占用 100%的 bug。

      rebuildSelector方法先通過openSelector方法創(chuàng)建一個(gè)新的selector。然后將old selector的 selectionKey 執(zhí)行 cancel。最后將 old selector 的 channel 重新注冊到新的 selector 中。 rebuild 后,需要重新執(zhí)行方法 selectNow,檢查是否有已 ready 的 selectionKey。

      接下來調(diào)用 processSelectedKeys 方法(處理 I/O 任務(wù)),當(dāng) selectedKeys != null 時(shí),調(diào)用 processSelectedKeysOptimized方法,迭代 selectedKeys 獲取就緒的 IO 事件的selectkey存 放在數(shù)組 selectedKeys 中, 然后為每個(gè)事件都調(diào)用 processSelectedKey 來處理它, processSelectedKey 中分別處理 OP_READ;OP_WRITE;OP_CONNECT 事件。

      最后調(diào)用 runAllTasks 方法(非 IO 任務(wù)),該方法首先會(huì)調(diào)用 fetchFromScheduledTaskQueue 方法,把 scheduledTaskQueue 中已經(jīng)超過延遲執(zhí)行時(shí)間的任務(wù)移到 taskQueue 中等待被執(zhí) 行,然后依次從 taskQueue 中取任務(wù)執(zhí)行,每執(zhí)行 64 個(gè)任務(wù),進(jìn)行耗時(shí)檢查,如果已執(zhí)行 時(shí)間超過預(yù)先設(shè)定的執(zhí)行時(shí)間,則停止執(zhí)行非 IO 任務(wù),避免非 IO 任務(wù)太多,影響 IO 任務(wù) 的執(zhí)行。

      每個(gè) NioEventLoop 對(duì)應(yīng)一個(gè)線程和一個(gè) Selector,NioServerSocketChannel 會(huì)主動(dòng)注冊到某 一個(gè) NioEventLoop 的 Selector 上,NioEventLoop 負(fù)責(zé)事件輪詢。

      Outbound 事件都是請求事件, 發(fā)起者是 Channel,處理者是 unsafe,通過 Outbound 事 件進(jìn)行通知,傳播方向是 tail到head。Inbound 事件發(fā)起者是 unsafe,事件的處理者是 Channel, 是通知事件,傳播方向是從頭到尾。

      內(nèi)存管理機(jī)制,首先會(huì)預(yù)申請一大塊內(nèi)存 Arena,Arena 由許多 Chunk 組成,而每個(gè) Chunk 默認(rèn)由 2048 個(gè) page 組成。Chunk 通過 AVL 樹的形式組織 Page,每個(gè)葉子節(jié)點(diǎn)表示一個(gè) Page,而中間節(jié)點(diǎn)表示內(nèi)存區(qū)域,節(jié)點(diǎn)自己記錄它在整個(gè) Arena 中的偏移地址。當(dāng)區(qū)域被 分配出去后,中間節(jié)點(diǎn)上的標(biāo)記位會(huì)被標(biāo)記,這樣就表示這個(gè)中間節(jié)點(diǎn)以下的所有節(jié)點(diǎn)都 已被分配了。大于 8k 的內(nèi)存分配在 poolChunkList 中,而 PoolSubpage 用于分配小于 8k 的 內(nèi)存,它會(huì)把一個(gè) page 分割成多段,進(jìn)行內(nèi)存分配。

      ByteBuf 的特點(diǎn):支持自動(dòng)擴(kuò)容(4M),保證 put 方法不會(huì)拋出異常、通過內(nèi)置的復(fù)合緩沖 類型,實(shí)現(xiàn)零拷貝(zero-copy);不需要調(diào)用 flip()來切換讀/寫模式,讀取和寫入索引分

      開;方法鏈;引用計(jì)數(shù)基于 AtomicIntegerFieldUpdater 用于內(nèi)存回收;PooledByteBuf 采用 二叉樹來實(shí)現(xiàn)一個(gè)內(nèi)存池,集中管理內(nèi)存的分配和釋放,不用每次使用都新建一個(gè)緩沖區(qū) 對(duì)象。UnpooledHeapByteBuf 每次都會(huì)新建一個(gè)緩沖區(qū)對(duì)象。

      TCP/IP 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:為什么公司wps總是卡死(wps老是卡死)
      下一篇:復(fù)制粘貼表格如何保留原格式(excel表格粘貼復(fù)制如何保留原格式)
      相關(guān)文章
      亚洲国产精品午夜电影 | 亚洲人成人网站18禁| 久久久久久久亚洲Av无码| 亚洲最大AV网站在线观看| 自拍偷自拍亚洲精品第1页| 亚洲福利在线播放| 亚洲AV成人潮喷综合网| 亚洲AV成人潮喷综合网| 男人的天堂av亚洲一区2区| 亚洲成在人线在线播放无码| 亚洲狠狠色丁香婷婷综合| 亚洲AV无码资源在线观看| 亚洲av午夜国产精品无码中文字 | 亚洲一区在线观看视频| 亚洲国产成人综合| 亚洲大香伊人蕉在人依线| 亚洲一区二区三区久久| 亚洲综合在线一区二区三区| 亚洲色偷偷色噜噜狠狠99| 亚洲精华国产精华精华液好用 | 亚洲电影国产一区| 亚洲精品第一国产综合精品| 亚洲人成在久久综合网站| 学生妹亚洲一区二区| 亚洲乱色伦图片区小说| 青青青亚洲精品国产| 亚洲成年看片在线观看| 国产亚洲一区二区三区在线不卡| 国产亚洲精品成人a v小说| 亚洲欧洲国产精品香蕉网| 图图资源网亚洲综合网站| 亚洲男人的天堂在线| 色婷五月综激情亚洲综合| 亚洲爆乳无码精品AAA片蜜桃| 国产亚洲精彩视频| 成人午夜亚洲精品无码网站| 亚洲AV无码一区二区二三区软件 | 亚洲白嫩在线观看| 亚洲熟妇AV一区二区三区浪潮| 久久亚洲色WWW成人欧美| 国产成人毛片亚洲精品|