學習內容
P1P43,P110P116,中間章節好枯燥啊,暫時用不到,先跳過了
IO模型參考:https://blog.csdn.net/lzb348110175/article/details/98941378
學習鏈接:https://www.bilibili.com/video/BV1DJ411m7NR?p=42&vd_source=510ec700814c4e5dc4c4fda8f06c10e8
系統優化:要麼是分層處理,要麼是叫緩存
🔥1. 基本內容
1.1.基本概念
1.1.0 IO模型--前提
1.1.0.1 基本概念
先做一個鋪墊吧,IO模型分爲同步阻塞BIO、同步非阻塞NIO、多路複用IO、異步AIO。後面詳細介紹
1.1.0.2 BIO--同步阻塞IO
BIO(Blocking IO):同步阻塞IO。這種阻塞是針對內核空間而言的,內核空間需要準備數據 。適合連接數少的情況,實際用戶請求一次就是開一個線程處理,雖然有線程池可以優化
1.1.0.3 NIO--同步非阻塞IO
NIO(Non-Blocking IO): 同步非阻塞IO。適合連接數多且時長短的,比如聊天連接器
1.1.0.4 多路複用IO--異步阻塞IO(略)
1.1.0.5 AIO--異步非阻塞IO
Asynchronous IO。適合連接數多且時長長的
1.1.1 Netty
1.1.1.1 基本概念
本質就是NIO框架,底層是jdk代碼,更下層是TCP/IP協議。比如阿里的Dubbo的RPC框架就是用的Netty、Spark
1.1.1.2 NIO概念
三大組件Channel通道,Buffer緩衝區,Selector選擇器
原本BIO是每有一個客戶連接服務端就創建一個線程處理,現在NIO就創建一個線程進行選擇處理,如果沒有通道有數據,那就跳過不阻塞(和Kafka消費者與kafka-Broker關係類似)
1.1.1.3 NIO--三大組件
總結就是一個Selector監聽多個Channel,每個Channel又對應一個Buffer。Buffer是面向塊(底層是個數組,BIO是面向字節流)
1.1.1.4 Buffer
緩衝區,面向塊編程,底層就是個數組,用各個標記控制數組長度與大小,由於可讀也可寫,所以實時都會改變
1.1.1.5 Channel
Channel本身是個接口,Buffer有源碼,Channel也有。可用於讀取文件、網絡傳輸等等等等。之前的InputStream內部就包含了Channel
1.1.1.6 Buffer-Channel實戰
程序 <=> Buffer <=> Channel <=> 文件:所以不僅可以讀取文件內容程序輸出,也可以讀取文件內容輸出到另一個文件。除了單個Buffer,還可以定義Buffer數組(服務器網絡交互中進行處理,一個Channel對應一個Buffer數組)
Channel.write(Buffer):表明Buffer往Channel寫
Channel.read(Buffer):表明Channel從Buuffer讀
1.1.1.7 MappedByteMapper(略)
在直接內存(堆外內存)操作數據,操作系統就不需要拷貝一次
1.1.1.8 Selector
就是將每個Channel註冊到Selector中,然後當Channel有數據傳入進來時,Selector非阻塞式讀取,避免了每個請求都創建一個線程,減少了多線程上下文的切換。
具體註冊流程就是客戶端通過ServerSocketChannel註冊到Selector中,Selector維護一個SelectionKey的集合返回
1.1.1.9 NIO--羣聊系統(略)
就是用Selector + Channel + Buffer實現局域網消息單聊與羣聊,暫時感覺用不到,比較枯燥,先跳過,先了解理論知識即可。
1.2 基本名詞
1.2.1 零拷貝
1.2.1.1 基本概念
DMA:direct memory access 直接內存拷貝,不使用CPU
1.2.1.2 實際場景
參考鏈接:https://blog.csdn.net/shenchaohao12321/article/details/115464117
零拷貝:本質就是內核緩衝區中間沒有重複數據,減少數據拷貝次數
傳統IO:用戶依次發起read、write請求,整個過程發送4次用戶態和內核態上下文切換與數據拷貝
mmap內存映射:4次上下文切換,3次數據拷貝。write的時候減少了一次。適合小文件讀取
sendFile(Linux中):3次上下文切換,最少2次數據拷貝,適合大文件讀取
1.2.2 AIO
AIO兩種模式:Reactor, Proactor。NIO本身也是一個Reactor。
1.2.3 Netty
1.2.3.1 基本概念
Es,dubbo底層都用到了Netty, netty對nio各種api接口進行了封裝
1.2.3.2 線程模型
- 傳統IO模型:就是類似BIO,每個連接創建一個線程處理
- Reactor模型:就是用一個單獨線程處理多個客戶端連接,然後類似用線程池分發處理
- 單Reactor單線程:服務器單線程處理客戶端某個請求的時候,其他客戶端請求會阻塞
1. - 單Reactor多線程:服務器單線程用類似線程池分發處理客戶端的多個請求。
1. - 主從Reactor多線程(Netty就是基於這個做了改進):分了3層,主線程建立連接,請求分給多個子線程,每個子線程又分給多個線程來進行handler處理,處理結果可以返回給子線程(不給主線程)。
1.
🔥2.進階內容
2.1. 基本概念
2.1.1 RPC
2.1.1.1 基本概念
遠程過程調用:計算機程序調用另一個計算機子程序。
常見RPC框架:dubbo, springcloud
2.1.1.2 基本開發
實際開發中,使用Netty實現rpc調用,就是需要客戶端和服務端都開發netty代碼,然後調用返回相應的對象。