當前位置:
首頁 > 最新 > 單伺服器高性能模式

單伺服器高性能模式

高性能模式涉及磁碟,操作系統,CPU,內存,緩存,網路,編程語言和平台,架構。很具有挑戰性。

高性能架構設計:

提高單伺服器性能,將單機性能發揮到極致

如果單機服務無法支撐,設計集群方案

架構設計決定了性能的上限,實現細節決定了性能的下限。

並發模型:

如何管理連接

如何處理請求

並發模型設計IO模型及進程模型

IO模型:阻塞,非阻塞,非同步,同步

進程模型:單進程,多進程,多線程

PPC

每次有新連接,fork()新的進程來處理連接請求。早期Unix網路模型,實現簡單,適用於連接數不高的場景。

父進程接收連接

父進程「fork」子進程

子進程處理連接的讀寫請求

子進程關閉連接

弊端體現在:

fork代價高,需要分配很多內核資源,還要拷貝父進程的內存映像

父子進程通信複雜,需要IPC來盡心信息傳遞

並發數量有限最大幾百, 如果連接持續時間很長,新連接不斷接入,進程調度和切換越來越高,系統壓力很大

Prefork

prefork採用預先fork,在啟動時就預先創建好進程,然後才開始接受用戶請求,省去了fork的耗時操作。多個進程,accept同一個socket,最終只有一個成功,存在「驚群」現象,即多個子進程都被喚醒去爭取,但只有一個成功,增加了不必要的進程調度和上下文切換。Linux 2.6以後已經解決accept驚群問題。

prefork仍然存在父子進程通信複雜,支持並發數量有限的問題。

TPC

每個新連接都創建一個新線程去處理這個連接的請求,線程比進程輕量級,創建消耗少。多線程共享進程空間,通信更簡單。

父進程接受新連接

創建子線程

子線程處理連接的讀寫數據

子線程關閉連接

註:TPC模式下,子線程不會複製文件描述符,TPP下會複製文件描述符

也有一些缺點:

線程創建仍然有代價

多線程共享進程內存,需要引用互斥,處理不好有死鎖,並發複雜

多線程會相互影響,特殊情況會導致主進程退出,exit,內存越界。

相比TPP,TPC更簡單,但同樣無法TPC也無法承載太多的並發。

Prethread同Prefork,但實現靈活。海量連接都不適合TPC和TPP。

Reactor和Proactor

針對TPC和TPP用完釋放提出資源復用,不為單獨的連接創建單獨的線程或者進程,創建一個進程池,將連接分配給其中一個進程。一個進程也可以處理多個連接。連接沒數據可讀是,會被阻塞到該連接上。將read改為非阻塞的,針對一個進程處理多個連接的話, 採用不斷輪詢,但如果連接數太多,挨個輪詢很消耗CPU,並且效率很低。

IO多路復用:

多連接共用一個阻塞對象,只需要在一個阻塞對象上等待,無需輪序所有連接,epoll,poll,kqueue

某個連接有數據可以處理時,OS通知進程,進程從阻塞態返回,開始業務處理

Reactor就是IO多路復用結合線程池,事件反應,通俗理解是:來了一個事件我就有相應的反應。我就是reactor,根據不同的時間類型,調用不同的邏輯。IO多路復用統一監聽事件,收到事件再Dispatch給某個進程。

Reactor模式的核心組成部分是Reactor和進程或者線程池。Ractor負責事件監聽和分配,線程池負責具體的事件處理。

Reactor有以下實現方式體現在:

Reactor的數量,可以一個或者多個

資源池的數量,一個或者多個

理論上四個組合,但多Reactor,單進程或線程比單Reactor和單進程或線程無性能優勢,還複雜,實際不使用。

資源池是線程還是進程根據具體語言和平台,Nginx多進程,Java多線程,C進程和線程均可。

1.單Reactor和單進程

Reactor監聽事件

是新連接建立,accept處理,創建Handler處理

非連接建立,Reactor直接調用handler處理

Handler完成raead-- 業務處理--send 整個流程

模式簡單,無IPC以及競爭,但無法發揮多核性能,必須等待Handler挨個處理。性能有瓶頸。

2.單Reactor和多線程

主線程Reactor通過select監聽連接接事件,收到後通過dispatch分發

不是連接事件,Acceptor通過Accept接受連接,並創建Handler處理後續連接

不是連接事件,Ractor會調用對應的Handler處理

Handler只負責響應事件,不進行業務處理,read到數據後,發給processor處理

processor在獨立線程中完成真正處理,Handler收到響應後把結果通過send給client

能夠充分利用多核多CPU的處理能力,但多線程數據共享和訪問較複雜,Ractor承擔所有事件的監聽和響應,瞬間高並發存在性能瓶頸。單Ractor多進程,IPC通信複雜,使用不多。

3.多Reactor多線程

mainReactor通過select監聽建立事件,收到事件後通過Acceptor接受,將新的連接分配給某個線程

subReactor將mainRactor分配的連接加入連接隊列,進行監聽,創建Handler用於處理連接的各種事件

新事件發生,subRactor來調用對應的Handler進行相應

Handler完成read-->業務處理-->send的完成業務流程

看起來比單Ractor和多線程池複雜,單實現其實更簡單:

父子進程職責明確,父進程只負責新連接建立,子進程負責後續業務處理

交互簡單,父進程直接把新連接給子進程,無需返回數據

字父進程間的文件連接互相獨立,無需同步共享處理

Proactor

Ractor是非阻塞同步網路模型,read和send都需要用戶進程同步操作。如果將read和send同步操作改為非同步的,就成了非同步網路模型Proactor。

Reactor可以理解為:來了事件通知你,你來處理。Proactor可以理解為:來了事件,我處理好了告訴你。這裡我是指操作系統內核,事件就是新的連接,數據可讀,可寫等I/O事件,你指事件的回調。

理論上Proactor模型比Reactor效率高,非同步性能更高,但系統層面並沒有對非同步的完全支持,Boost.Asio linux下都是用epoll模擬出來的非同步模型。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

瑜伽是一種心境,一種狀態
去動物園的無數次兩隻老虎主題

TAG:全球大搜羅 |