不少人學習編程技術通常都經過一本編程語言的入門書籍,而後嘗試作一些例子和小項目。可是這些都不能讓咱們深刻的學習不少的編程技巧和高深技術,固然這個時候不少有經驗的學習人員就會告訴你們,找一個好的開源軟件理解它的設計與實現原理,閱讀開源項目的源代碼,都知道源碼以前了無祕密。我也認可讀源碼可以快速提升咱們的編程能力和編程思惟,我也常常研究不少項目的源代碼,有些是工做須要,有些是興趣。可是我今天想說的都不是這些,我想說的是更高一層的學習方案,就是經過本身的實踐實現一個開源軟件,也許這個開源軟件沒有任何人使用,可是在實現的這個過程當中你會學習到不少,由於實現一個真正的開源軟件須要使用到不少編程知識和技巧,這就會驅使你不斷去學習這些編程知識和技巧,學會以後可以立刻用於實踐,真正實踐完成之後你對這些編程知識和技巧理解就更深刻了。nginx
我目前就正在作這樣一件事情,我選擇的是實現一個相似nginx的高性能http服務器。選擇這個的理由很簡單,我在一個互聯網公司,http協議和http服務器常常和我打交道,在架構設計和分佈式系統實現的時候可能都須要考慮這些。我開源的地址以下:https://github.com/brucewoo/JHttpServer,若是你也對這個感興趣能夠一塊兒參與,包括設計功能,架構和實現。作這個開源項目的惟一目的就是學習,經過實踐的方式來學習。關於這個開源軟件的一切我都會以博客或者wiki的方式記錄,包括每個模塊實現的原理,考慮,設計等等,可能還有核心代碼的解讀,爭取作第一個學習型的開源軟件。雖然這個開源項目沒有實際的需求來驅動,可是nginx就是個人目標和超越的對象,固然實現的過程當中確定會借鑑其餘不少開源軟件的設計思想和編程思惟,也會借鑑某一個模塊或者功能的實現,或者基於改進。git
說了這麼多一點兒也沒有和標題扯上關係,今天就是爲我這個開源軟件寫的第一個博客,實現一個高性能的網絡服務器的第一個就須要選擇一個很好的高性能編程框架,今天就分析這個,這個也算本身開始前的準備,學習高性能服務器編程框架:github
網絡服務器的編程步驟就不須要多介紹了,有網絡編程知識的都很清楚。首先對網絡服務器組成的基本軟件模塊作一個簡單的說明,以下表:數據庫
模塊 |
單機 |
集羣 |
I/O處理單元 | 處理客戶端鏈接,讀寫網絡數據 | 做爲介入服務器,實現負載均衡 |
邏輯單元 | 業務進程或者線程 | 邏輯服務器 |
網絡存儲單元 | 本地數據庫,文件或者緩存 | 數據庫服務器 |
請求隊列 | 各單元之間的同窗方式 | 各服務器之間的永久tcp鏈接 |
既然上面提到的第一個模塊是IO處理單元,咱們就分析和學習一下IO模型,IO處理單元主要處理客戶端鏈接,接收客戶端發送過來的數據,還有就是返回服務器返回給客戶端的數據。下面仍是經過表格的方式展現IO模型,以下:編程
IO模型 | 讀寫操做和阻塞階段 |
阻塞 | 程序阻塞於讀寫函數 |
複用 | 程序阻塞於IO複用系統調用,但可同時監聽多個IO事件。對IO自己的讀寫操做是非阻塞的 |
SIGIO信號 | 信號觸發讀寫就緒事件,用戶程序執行讀寫操做,程序沒有阻塞階段 |
異步 | 內核執行讀寫操做並觸發讀寫完成事件,程序沒有阻塞階段。 |
下面在說說高效的事件處理模式:緩存
三類事件,IO事件,信號和定時事件;兩種高效的事件處理模式:Reactor和Proactor。服務器
(1)先說說Reactor模式:主線程負責監聽文件描述上的事件,而後把事件丟給工做線程處理。下面以epoll模型爲例說明處理流程:網絡
1) 主線程往epoll內核事件表中註冊socket的讀就緒事件;架構
2)主線程調用epoll_wait等待socket上有數據可讀;負載均衡
3)當socket上有數據可讀時,epoll_wait通知主線程,主線程將可讀事件放入請求隊列;
4)工做線程被喚醒,讀取客戶端數據,處理客戶端請求而後往epoll內核事件表中註冊socket上的可寫就緒事件;
5)主線程繼續調用 epoll_wait等待socket可寫事件;
6)socket可寫,epoll_wait通知主線程,主線程放入socket可寫事件到請求隊列;
7)工做線程處理可寫事件。
(2)再說說Proactor模式:今天已經很晚,改天再下一篇博客繼續介紹。