多路複用

背景

服務器客戶端架構的程序,服務器端如何處理業務?
三種解決方案:
1.單線程 一個線程處理全部任務java

2.多線程 每一個線程處理一個任務linux

3.仍是單線程處理多個任務,可是使用多路複用選擇器git


優缺點
1.單線程
優勢
簡單易用github

缺點
阻塞。只有當前面一個任務執行完以後,才能執行下一個任務,cpu被閒置。web

2.多線程
優勢
解決了單線程的缺點。面試

缺點
1)須要建立多線程,線程是很重的資源(即佔內存空間不少,一個線程0.5~1M)
2)建立完以後,還須要維護線程的各類數據/狀態
3)cpu在不一樣線程之間切換是很累的,就像人的腦子工做的時候被人打擾會很煩同樣redis

3.多路複用
優勢
解決多線程的缺點。編程

缺點
編程複雜小程序


與單線程處理任務的區別?
1.單線程阻塞。浪費CPU。
2.多路複用,非阻塞。服務器輪訓鏈接和事件。設計模式


應用場景
1.單線程
簡單的小程序,用戶量不少的話不適用。

2.多線程
web服務器。例子tomcat等。

3.多路複用
1)java nio-Selector
2)基於java nio的通訊框架。例如netty mina。
3)基於通訊框架的rpc框架。例如grpc dubbo ice。


實現原理?如何實現?
基於操做系統提供的功能-select()/epoll()函數。


select和epoll的區別?
同樣。epoll優化多路複用選擇器。


代碼
github.com/diedai/java…

總結

多路複用 入口?
socket 服務器端套接字.accept()方法?
多路複用是怎麼接受客戶端鏈接的?

思考問題的時候,把多路複用和socket的流程一一對應起來,不少流程被多路複用/框架封裝起來了。

java nio

步驟

while(true){  
1.阻塞獲取事件 //獲取一個或多個事件  
2.循環處理獲取到的事件集合  
}
複製代碼

netty

步驟
1.註冊事件處理器類
2.當有新的事件到來,事件處理器類自動處理


總結
沒有顯式地循環獲取和處理事件集合的過程,而是被netty框架封裝了


和nio的區別?
1.註冊事件
事件處理器

2.處理事件
事件處理器處理事件

redis

相似netty

架構圖

主要包含四部分
1.套接字
2.多路複用(便可以同時監聽多個客戶端套接字的事件)
3.事件分發 //所謂事件分發,其實就是while(true){1.阻塞獲取事件集合2.遍歷處理事件集合}
分發給誰?事件處理器。
4.事件處理器

linux epoll 多路複用 事件驅動機制

多路複用-研究API的輸入數據和輸出數據?

面試題1

是什麼
撥動開關

www.zhihu.com/question/32…


代碼具體怎麼實現撥動開關?
1.select
代碼實現?

2.poll
解決了鏈接數量上限問題。
select上限1024個鏈接。
代碼實現?

3.epoll
解決了查找哪一個鏈接速度慢的問題。

代碼怎麼實現?


參考
zhuanlan.zhihu.com/p/45872289

linux編程接口-63章

面試題2

發展史
1.單線程-阻塞
2.多線程-非阻塞
3.單線程-非阻塞
多路複用


單線程-非阻塞
一個請求來了,還能夠繼續多個請求。同時,其餘請求的事件被監聽處理。總之,接受客戶端鏈接和監聽已有鏈接的事件都是輪訓/循環執行的。


解決方案
有三種
1.select
2.poll
3.epoll


最佳實踐
epoll


三種解決方案的區別
主要是速度。
12是N
3是logN

爲何?這個速度具體指什麼?


操做系統層面到底如何實現?


處理流程圖?
多個請求-單線程-分發。不要管這個流程圖,還有分發這個關鍵字,容易誤解人,也不容易理解。其實就是非阻塞處理全部的鏈接和讀寫事件。具體實現方法就是使用循環。

設計模式-反應堆模式Reactor

註冊事件,而後分發給各類不一樣處理器類的一種設計模式。


redis
ae.c ,以及任意一個 ae_*.c 文件(取決於你所使用的多路複用庫)。 Redis 的事件處理器實現(基於 Reactor 模式)。

參考

相關文章
相關標籤/搜索