netty線程模型
Netty是一個高性能、高可擴展性異步事件驅動的網絡應用程序框架,它極大簡化了TCP和UDP客戶端和服務器開發等網絡編程
結構:
Netty四個重要內容:
1、Reactor線程模型:一種高性能的多線程程序設計思路
2、Netty中自己定義的Channel概念:增強版的通道概念
3、ChannelPipeline職責聯設計模式:時間處理機制
4、內存管理:增強的ByteBuf緩衝區
Tony源碼中文分析註釋:https://github.com/crazyFeng/netty/tree/netty-4.1.32.final-remark
優秀博客:https://www.cnblogs.com/lighten/p/8909254.html
整體結構 三大塊
1、支持Socket等多種傳輸方式
2、提供了多種協議的編碼實現
3、核心設計包含:
事件處理模型
API的使用
ByteBuffer的增強
netty線程模型
1、Resources資源(請求/任務)
2、Synchronius Event Demultiplexer同步事件複用器
3、Dispatch分配器
4、Request Handler請求處理器
EvenLoopGroup初始化過程
構造函數 -> 確定線程數量(默認cpus的兩倍)-> new Executor構建線程執行器 -> for--newChild()構建ExentLoop -> new EventExecutorChooser
EventLoopGroup:
Main EventLoopGroup:輪詢通過事件分配執行任務(任務隊列、事件選擇器)
sub EventLoopGroup:處理請求(IO)
netty中ServerSocketChannel用的是NioMessageUnsafe,socketChannel用的是NioByteUnsafe
責任鏈模式 chins
爲請求創建了一個處理對象的鏈。發起請求個具體處理請求的過程進行解耦:責任鏈上的處理者扶着處理請求,客戶只需要將請求發送到
職責鏈上即可,無須關心請求的處理細節和請求的傳遞
4個要素:
處理器抽象類、具體處理器實現類、保存處理器信息、處理執行
零拷貝複製機制 https://blog.csdn.net/linsongbin1/article/details/77650105
傳統讀操作:
當應用發起一個從磁盤讀取文件的操作時,請求會先經過內核,由內核與磁盤進行交互。數據會從磁盤拷貝到內核的緩存區中。
這個copy動作由DMA(硬件和軟件的信息傳輸、直接存儲器訪問)完成,整個過程中基本上不消耗CPU。如果應用想拿到信息,
還得從內核緩衝區獲取,這裏又存在一個cpu copy的動作,將數據從內核緩衝區中拷貝到應用緩衝區中。這個copy動作是需要消耗CPU的。
所以應用想拿到數據需要2次copy動作。
傳統讀操作流程:
傳統寫操作:
應用想將數據傳遞給客戶端,必須經過內核,將數據先從應用緩衝區中copy(cpu copy)到內核的緩衝區中,對於寫操作而言,通常這個內核緩
衝區叫kernel socket buffer,接着DMA會從kernel socket buffer中將數據拷貝(DMA copy)到protocol engine,最終將數據發送給客戶端。
這裏又發生2次copy動作,一次是cpu copy,另外一次是DMA copy。
傳統寫操作流程:
ByteBuf:
JDK ByteBuffer的缺點:
無法動態擴容:
JDK的ByteBuffer長單獨是固定的,不能動態擴展和收縮,當數據大於ByteBuffer容量時,會發生索引越界異常
API使用複雜:
讀寫時需手動調用flip()和rewind()等方法,需謹慎使用這些API,容易出現錯誤
ByteBuf做了增強:
1、API操作便捷性
2、動態擴容
3、多種ByteBuf實現
4、零拷貝機制
屬性:
1、capacity 容量
2、readerIndex 讀取位置
3、writerIndex 寫入位置
網絡編程(推送)
短鏈接:請求/響應之後,關閉已建立的TCP鏈接,下次請求重新建立請求
長鏈接:請求/響應之後,不關閉TCP鏈接,多次請求,複用同一個鏈接
粘包:Nagle算法-客戶端累積一定量或者緩衝一段時間緊再傳輸。服務端緩衝區堆積,導致多個請求粘貼在一起
拆包:發送的數據大於發送緩衝區,及逆行分片 傳輸。服務端緩衝區堆積,導致服務端讀取的數據不完整
TCP鏈接四元組:
服務器IP+服務器PORT+客戶端IP+客戶端PORT
郵箱
海量用戶的情況如下:
1、知道哪些接受者需要接受這條消息
2、確定哪些服務器需要接受推送這個消息
4、消息存到MQ
代更新。。