服務器客戶端架構的程序,服務器端如何處理業務?
三種解決方案:
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優化多路複用選擇器。
多路複用 入口?
socket 服務器端套接字.accept()方法?
多路複用是怎麼接受客戶端鏈接的?
思考問題的時候,把多路複用和socket的流程一一對應起來,不少流程被多路複用/框架封裝起來了。
步驟
while(true){
1.阻塞獲取事件 //獲取一個或多個事件
2.循環處理獲取到的事件集合
}
複製代碼
步驟
1.註冊事件處理器類
2.當有新的事件到來,事件處理器類自動處理
總結
沒有顯式地循環獲取和處理事件集合的過程,而是被netty框架封裝了
和nio的區別?
1.註冊事件
事件處理器
2.處理事件
事件處理器處理事件
相似netty
主要包含四部分
1.套接字
2.多路複用(便可以同時監聽多個客戶端套接字的事件)
3.事件分發 //所謂事件分發,其實就是while(true){1.阻塞獲取事件集合2.遍歷處理事件集合}
分發給誰?事件處理器。
4.事件處理器
是什麼
撥動開關
代碼具體怎麼實現撥動開關?
1.select
代碼實現?
2.poll
解決了鏈接數量上限問題。
select上限1024個鏈接。
代碼實現?
3.epoll
解決了查找哪一個鏈接速度慢的問題。
代碼怎麼實現?
參考
zhuanlan.zhihu.com/p/45872289
linux編程接口-63章
發展史
1.單線程-阻塞
2.多線程-非阻塞
3.單線程-非阻塞
多路複用
單線程-非阻塞
一個請求來了,還能夠繼續多個請求。同時,其餘請求的事件被監聽處理。總之,接受客戶端鏈接和監聽已有鏈接的事件都是輪訓/循環執行的。
解決方案
有三種
1.select
2.poll
3.epoll
最佳實踐
epoll
三種解決方案的區別
主要是速度。
12是N
3是logN
爲何?這個速度具體指什麼?
操做系統層面到底如何實現?
處理流程圖?
多個請求-單線程-分發。不要管這個流程圖,還有分發這個關鍵字,容易誤解人,也不容易理解。其實就是非阻塞處理全部的鏈接和讀寫事件。具體實現方法就是使用循環。
註冊事件,而後分發給各類不一樣處理器類的一種設計模式。
redis
ae.c ,以及任意一個 ae_*.c 文件(取決於你所使用的多路複用庫)。 Redis 的事件處理器實現(基於 Reactor 模式)。