tft每日頭條

 > 科技

 > linux服務器管理工具開源

linux服務器管理工具開源

科技 更新时间:2025-04-22 05:27:56
問題聚焦:

服務器一般分為如下三個主要模塊:I/O處理單元(四種I/O模型,兩種高效事件處理模塊),邏輯單元(兩種高效并發模式,有效狀态機)和存儲單元(不讨論)。


服務器模型

C/S模型

結構:

linux服務器管理工具開源(高性能服務器編程)1

特點:

邏輯簡單。

工作流程:

linux服務器管理工具開源(高性能服務器編程)2

I/O複用技術:select,同時監聽多個客戶請求。

優點:适合資源相對集中的場合。

缺點:當訪問量過大,可能所有客戶都将得到很慢的相應。

P2P模型

結構:兩種結構

linux服務器管理工具開源(高性能服務器編程)3

結構b比結構a增加了發現服務器,用于主機之間的互相發現,盡快找到自己需要的資源。

特點:

摒棄了服務器為中心的格局,讓網絡上所有主機處于對等的地位。

每台機器在消耗服務的同時也給别人提供服務

缺點:當用戶之間傳輸的請求過多時,網絡的負載将加重


服務器編程框架

基本框架:

linux服務器管理工具開源(高性能服務器編程)4

模塊說明:

linux服務器管理工具開源(高性能服務器編程)5


I/O模型

阻塞I/O

socket在創建的時候是阻塞的。我們可以給socket系統調用的第2個參數傳遞SOCK_NONBLOCK 标志,或者通過fcntl 系統調用的F_SETFL 命令,将其設置為非阻塞。

阻塞模型和非阻塞模型:

阻塞I/O:阻塞的文件描述符,系統調用可能因為無法立即完成而被操作系統挂起。

例如:客戶端connect發起連接,服務器相應之前的這段時間,connect調用将被挂起,直到确認報文段到達将之喚起。

可能被阻塞的系統調用包括accept,send,recv和connect 。

非阻塞I/O:非阻塞的文件描述符,總是立即返回,不管時間是否發生。

如果事件沒有立即發生,這些系統調用返回-1,這時我們就要确認是延遲還是出錯,此時我們必須根據errno來區分這兩種情況。

對accept.send和recv而言,事件未發生時errno通常被設置成EAGAIN(再來一次)或者EWOULDBLOCK(期望阻塞);對connect而言,errno則被設置成EINPROGRESS(在處理中)。

注意:通常情況下,非阻塞I/O要和其他I/O通知機制一起使用才能提高程序的效率。

I/O複用

常用:I/O通知機制

描述:應用程序通過I/O複用函數向内核注冊一組事件,内核通過I/O複用函數把其中就緒的事件通知應用程序。

I/O複用函數:select、poll和epoll_wait,後面的章節會讨論這些函數。

注意:I/O複用函數本身是阻塞的,它們能提高程序效率的原因在于它們具有同時監聽多個I/O事件的能力。

SIGIO信号

作用:報告I/O事件

描述:我們可以為一個目标文件描述符指定宿主進程,那麼指定的宿主進程将捕獲到SIGIO信号。這樣,當目标文件描述符上有事件發生時,SIGIO信号的信号處理函數将被觸發,我們也就可以在該信号處理函數中對目标文件描述符執行非阻塞I/O操作了。

異步I/O模型

上面讨論的三種模型都屬于同步I/O模型

同步I/O模型和異步I/O模型的區别

同步:I/O的讀寫操作發生在I/O事件之後,由應用程序(用戶代碼)來完成。

異步:異步I/O的讀寫操作總是立即返回的,不論I/O事件是否被阻塞,因為真正的讀寫操作被内核接管,即内核來執行I/O操作,具體表現為數據在内核緩沖區和用戶緩沖區之間的移動。

可以認為,同步I/O向應用程序通知I/O就緒事件,異步I/O向應用程序通知I/O完成事件(可能并沒有真正的完成)。

I/O模型對比如下:

linux服務器管理工具開源(高性能服務器編程)6


兩種高效的事件處理模式

服務器程序通常需要處理三類事件:I/O事件,信号和定時事件。後面會一次介紹。

這一節先介紹兩種高效的事件處理模式:Reactor(同步I/O模型)和Proactor(異步I/O模型)。

Reactor模式

描述:

  • 它要求主線程隻負責監聽文件描述上是否有事件發生,有的話就立即将該事件通知工作線程。
  • 除此之外,主線程不做任何其他實質性的工作。
  • 工作線程負責讀寫數據,接受新的連接,以及處理客戶請求。

流程:

使用同步I/O模型(以epoll_wait為例)實現的Reactor模式的工作流程是:

  1. 主線程往epoll内核事件表中注冊socket上的讀就緒事件。
  2. 主線程調用epoll_wait等待socket上有數據可讀。
  3. 當socket上有數據可讀時,epoll_wait通知主線程,主線程則将socket可讀事件放入請求隊列。
  4. 睡眠在請求隊列上的某個工作線程被喚醒,它從socket讀取數據,并處理客戶請求,然後往epoll内核事件表中注冊該socket上的寫就緒事件。
  5. 當socket可寫時,epoll_wait通知主線程,主線程将socket可寫事件放入請求隊列。
  6. 睡眠在請求隊列上的某個工作線程被喚醒,它往socket上寫入服務器處理客戶請求的結果。

流程圖如下:

linux服務器管理工具開源(高性能服務器編程)7

Proactor模式

描述:将所有I/O操作都交給主線程和内核來處理,工作線程僅僅負責業務邏輯。更符合之前提到的服務器編程框架。

流程:使用異步I/O模型(以aio_read和aio_write為例)實現Proactor模式的工作流程是:

  1. 主線程調用aio_read函數向内核注冊socket上的讀寫完成事件,并告訴内核用戶讀緩沖區的位置,以及讀操作完成後如何通知應用程序。
  2. 主線程繼續處理其他邏輯。
  3. 當socket上的數據被讀入用戶緩沖區後,内核将向應用程序發送一個 信号,以通知應用程序數據可用。
  4. 應用程序預先定義好的信号處理函數選擇一個工作線程來處理客戶請求。工作線程處理完客戶請求之後,調用aio_write函數想内核注冊socket的寫完成事件,并告訴内核用戶寫緩沖區的位置,以及寫操作完成時如何通知應用程序。
  5. 主線程繼續處理其他邏輯。
  6. 當用戶緩沖區的數據被寫入socket之後,内核将向應用程序發送一個信号,以通知應用程序數據已經發送完畢。
  7. 應用程序預先定義好的信号處理函數選擇一個工作線程來做善後處理,比如決定是否關閉socket。

流程圖如下:

linux服務器管理工具開源(高性能服務器編程)8

連接socket上的讀寫事件是通過aio_read/aio_write 向内核注冊的,因此内核将通過信号來向應用程序報告連接socket上的讀寫事件。所以,主線程中的epoll_wait調用僅能用來檢測監聽socket 上的連接請求事件,而不能用來檢測連接socket 上的讀寫事件。

同步I/O方式模拟Proactor模式

原理:主線程執行數據讀寫操作,讀寫完成之後,主線程向工作線程通知這一“完成事件”,工作線程處理後續邏輯。

流程:

  1. 主線程往epoll内核事件表中注冊socket上的讀就緒事件。
  2. 主線程調用epoll_wait等待socket上有數據可讀。
  3. 當socket上有數據可讀時,epoll_wait通知主線程。主線程從socket循環讀取數據,直到沒有更多數據可讀,然後将讀取到的數據封裝成一個請求對象并插入請求隊列。
  4. 睡眠在請求隊列上的某個工作線程被喚醒,它獲得請求對象并處理客戶請求,然後往epoll内核事件表中注冊socket上的寫就緒事件。
  5. 主線程調用epoll_wait等待socket可寫。
  6. 當socket可寫時,epoll_wait通知主線程。主線程往socket上寫入服務器處理客戶請求的結果。

流程圖如下:

linux服務器管理工具開源(高性能服務器編程)9


兩種高效的并發模式

并發模式适合:I/O密集型任務

方式:多進程和多線程(後面讨論)

描述:并發模式是指I/O處理單元和多個邏輯單元之間協調完成任務的方法。

服務器主要有兩種并發編程模式:

  • 半同步/半異步模式
  • 領導者/追随者模式

半同步/半異步模式

解釋:這裡的“同步”和“異步”

同步:程序完全按照代碼序列的順序執行

異步:程序的執行需要由系統事件來驅動,這裡的系統事件包括中斷、信号等。

linux服務器管理工具開源(高性能服務器編程)10

同步線程:按照同步方式運行的線程稱為同步線程

異步線程:按照異步方式運行的線程稱為異步線程

半同步/半異步模式:同步線程用于處理客戶邏輯,異步線程用于處理I/O事件。

半同步/半反應堆模式

結合考慮兩種事件處理模式(Reactor和Proactor)和幾種I/O模型(阻塞I/O,I/O複用,SIGIO信号,異步I/O),則半同步/半異步就存在多種變體

半同步/半反應堆模式就是其中的一種。

如下圖所示:

linux服務器管理工具開源(高性能服務器編程)11

特點:

  1. 異步線程隻有一個,由主線程來充當,負責監聽所有socket上的事件。
  2. 如果有新的連接請求,主線程就接受之,以得到新的連接socket
  3. 在epoll内核事件表中注冊該socket上的讀寫事件
  4. 如果連接socket上有讀寫事件發生,即有新的客戶請求到來或有數據要發送到客戶端,主線程就将該連接socket插入請求隊列。
  5. 所有工作線程都睡眠在請求隊列上,當有任務到來時,它們将通過競争獲得任務的接管權。
領導者/追随者模式

描述:多個工作線程輪流獲得事件源集合,輪流監聽、分發并處理事件的一種模式。

關鍵:領導者的變換和I/O事件的處理

實現:在任意時間點,程序都僅有一個領導者線程, 它負責監聽I/O事件,而其他線程都是追随者,它們休眠在進程池等待成為新的領導者。當前領導者如果檢測到I/O事件,首先要從線程池中推選出新的領導者線程,然後處理I/O事件。

結構:

linux服務器管理工具開源(高性能服務器編程)12

說明:

句柄集:表示I/O資源,在Linux下通常就是一個文件描述符。

線程集:所有工作線程的管理者。負責各線程之間的同步和新領導者線程的推選。

事件處理器及其子類: 用回調函數的方式處理某事件發生時對應的業務。

工作流程:

linux服務器管理工具開源(高性能服務器編程)13

To be continued:後面的專題将介紹有限狀态機和提高服務器性能的一些建議

小結:

這篇主要介紹了服務器方面的核心框架和設計模式,是這個系列的核心。後續的篇幅都是實現這些模型的技術相關的介紹。

服務器編程的路很深,但技術方面也是穩定的,不像前端技術那樣技術革新很頻繁和有趣。


來源:CSDN

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved