- BIO、NIO 和 AIO 的區(qū)別?
- BIO,同步阻塞式IO,面向流,一個連接來創(chuàng)建一個線程進(jìn)行處理
- 偽異步IO,線程池管理線程進(jìn)行處理
- NIO,同步非阻塞式IO,面向緩沖區(qū),一個連接一個線程,通過Selector多路復(fù)用器
輪詢所有操作狀態(tài)的改變來管理N個連接和事件,Channel進(jìn)行讀寫- AIO,異步非阻塞IO,無需一個線程去輪詢所有IO操作的狀態(tài)改變,在相應(yīng)的狀態(tài)改變后,
系統(tǒng)會通知對應(yīng)的線程來處理
- NIO的組成
- Selector,多路復(fù)用器,負(fù)責(zé)管理channel的所有事件
- Buffer,緩沖區(qū),數(shù)據(jù)流入、流出所必須的區(qū)域
- Channel,通道,用來進(jìn)行讀寫
- netty的特點(diǎn)
- netty是一個采用多線程Reactor模式的高性能、異步事件驅(qū)動的NIO框架,提供了對TCP、UDP、文件傳輸?shù)闹С帧?br>
- 簡化了NIO的使用,封裝了多種編解碼器、粘包/半包處理、心跳檢測、http/ssl等開箱即用的處理器
- 緩沖區(qū)通過內(nèi)存池的方式循環(huán)利用,ByteBuf通過引用計數(shù)器及時申請釋放不再引用的對象,降低了 GC 頻率
- 大量使用了 volitale、使用了 CAS 和原子類、線程安全類的使用、讀寫鎖的使用
- netty的線程模型
netty可以選擇構(gòu)建兩個線程池,boss線程池和worker線程池
- boss線程池用于mainReactor線程負(fù)責(zé)建立連接,subReactor線程負(fù)責(zé)監(jiān)聽事件
- worker線程負(fù)責(zé)handller的處理
- 什么是粘包半包,怎么處理
導(dǎo)致粘包/半包的原因如下
- 由于TCP采用nagel算法為了減少網(wǎng)絡(luò)開銷,每一次都在MISS大小想盡可能嘴大的發(fā)送數(shù)據(jù)包
,會對數(shù)據(jù)進(jìn)行拆分發(fā)送- 接收數(shù)據(jù)的緩沖區(qū)在大小不足時會進(jìn)行拆包處理
netty提供了4個已經(jīng)封裝好的處理器解決粘包/半包問題
- FixedLengthFrameDecoder(int frameLength),固定長度拆包,適用于數(shù)據(jù)包長度固定
- LineBasedFrameDecoder(int maxLength),按行拆包,數(shù)據(jù)("\r\n")結(jié)尾
- DelimiterBasedFrameDecoder(int maxFrameLength, ByteBuf delimiter), 固定分隔符拆包,數(shù)據(jù)必須以分隔符結(jié)尾
- LengthFieldBasedFrameDecoder,基于長度域拆包
- 了解哪些序列化協(xié)議
數(shù)據(jù)包需要以二進(jìn)制形式在網(wǎng)絡(luò)傳輸中傳輸,所以數(shù)據(jù)需要編碼為二進(jìn)制流傳輸,接收在進(jìn)行
解碼使用影響序列化的幾個因素有
- 序列化后的碼流大小,影響網(wǎng)絡(luò)開銷
- 序列化的性能,影響CPU的資源占用
- 是否支持跨語言,影響開發(fā)語言的切換和平臺的對接
常見的序列化方式有以下幾種
- java自帶序列化,無法跨語言、碼流太大、序列化的性能差
- xml,可讀性好,不能序列化方法,文件大,當(dāng)做配置文件存儲數(shù)據(jù),實(shí)時數(shù)據(jù)轉(zhuǎn)換。
- JSON,兼容性高、格式簡單、碼流小、擴(kuò)展性好,描述性差,額外空間開銷大,適用于
跨防火墻訪問、可調(diào)式性要求高、基于 Web browser 的 Ajax 請求、傳輸數(shù)據(jù)量相對小,實(shí)時性要求相對低(例如秒級別)的服務(wù)- FastJSON,簡單易用,速度快,適用場景:協(xié)議交互、Web 輸出、Android 客戶端
- Thrift,不僅是序列化協(xié)議,還是一個 RPC 框架,體積小, 速度快、支持多種語言和
豐富的數(shù)據(jù)類型、對于數(shù)據(jù)字段的增刪具有較強(qiáng)的兼容性、支持二進(jìn)制壓縮編 碼。
缺點(diǎn):使用者較少、跨防火墻訪問時,不安全、不具有可讀性,調(diào)試代碼時相對困難、
不能與其他傳輸層協(xié)議共同使用(例如 HTTP)、無法支持向持久層直接讀寫數(shù)據(jù),即:
不適合做數(shù)據(jù)持久化序列化協(xié)議。適用場景:分布式系統(tǒng)的 RPC 解決方案- Protobuf,將數(shù)據(jù)結(jié)構(gòu)以.proto 文件進(jìn)行描述,序列化后碼流小,性能高、
結(jié)構(gòu)化數(shù)據(jù)存 儲格式(XML JSON 等)、通過標(biāo)識字段的順序,可以實(shí)現(xiàn)協(xié)議的前向兼容、
結(jié)構(gòu)化的文檔 更容易管理和維護(hù)。缺點(diǎn):需要依賴于工具生成代碼、支持的語言相對較少,
官方只支持 Java 、C++ 、python。適用場景:對性能要求高的RPC調(diào)用、
具有良好的跨防火墻的訪問 屬性、適合應(yīng)用層對象的持久化- protostuff 基于 protobuf 協(xié)議,但不需要配置 proto 文件,直接導(dǎo)包即可
- Hessian 采用二進(jìn)制協(xié)議的輕量級 remoting onhttp 工具
- MessagePack
- Netty 的零拷貝實(shí)現(xiàn)
Netty 接收或發(fā)送Bytebuf采用DirectMemory,不要拷貝到localMemory中,減少堆拷貝的過程。
- CHannelConfig創(chuàng)建ByteBufAllocator默認(rèn)使用Drect Buffer
- CompositeByteBuf可以合并多個ByteBuf為一個寫入/寫出,內(nèi)部個個buf是獨(dú)立的
- FileRegion包裝的FileChannel.tranferTo可直接將文件緩存區(qū)中的數(shù)據(jù)發(fā)送到指定Channel,
避免循環(huán)write導(dǎo)致的內(nèi)存拷貝
- netty的高性能表現(xiàn)在哪些方面
- 心跳,服務(wù)端用來定時清除閑置會話,客戶端用來檢測測會話是否斷 開,是否重來,檢測網(wǎng)絡(luò)延遲
- 串行無鎖化設(shè)計,避免線程的競爭、上下文切換
- 可靠性,讀寫超時處理、內(nèi)存池重復(fù)使用、優(yōu)雅停機(jī)、資源釋放
- 安全性,支持的安全協(xié)議:SSL V2和V3,TLS,SSL單向認(rèn)證、雙向認(rèn)證和第三方CA 認(rèn)證
- TCP 參數(shù)配置
- NIOEventLoopGroup 源碼