《Linux高效能伺服器程式設計》 讀書筆記
第一章 TCP/IP協議族
資料鏈路層可以看成是一個網絡卡驅動,為上層提供了一個統一的介面。
Telnet協議是一種遠端登入協議,它使得我們能在本地完成遠端任務。
第二章 IP協議詳解
第三章 TCP協議詳解
產生復位報文段的三種情況:
- 訪問不存在的埠
- 異常終止連線
- 處理半開啟連線
tcp互動資料流(Telnet,ssh)和成塊資料流(ftp)
tcp利用緊急指標標誌和緊急指標來實現所謂的帶外資料(只有一個位元組)。
第五章 Linux網路程式設計基礎API
分為三個部分:
- socket地址API(ip,port)
- socket基礎API(sys/socket.h)
- 網路資訊API(netdb.h,用於主機名和IP地址的轉換)
第六章 高階IO函式
詳見書中。
第七章 linux伺服器程式規範
(需要更深入地理解)
- 系統日誌(Linux提供了一個寫日誌的介面)
- 使用者資訊(UID, EUID, GID, EGID)
- 程序間關係
- 系統資源限制
- 改變工作目錄和根目錄
- 伺服器程式後臺化
第八章 高效能伺服器程式框架
阻塞IO,IO複用,訊號驅動IO都是同步IO模型,因為它們都是在IO事件發生之後,由應用程式來完成(將資料從使用者空間寫入核心空間)。對非同步IO來說,則是全部交給了核心(資料在核心和使用者空間之間的移動由核心完成)。同步IO嚮應用程式通知的是IO就緒事件,非同步IO對應用程式通知的是IO完成事件。
兩種高效的事件處理模式:reactor模式(同步IO模型)和Proactor模式(非同步IO模型)
Proactor模式將所有的IO操作交給主執行緒和核心來完成:
併發程式設計就是為了提高CPU的利用率嘛,如果是計算密集型的那併發程式設計就沒有用了。
併發程式設計模式:
- 半同步半非同步模式:同步執行緒用於處理客戶邏輯,非同步執行緒用於處理IO事件,一種變體如下:
- 領導者追隨者模式:
有限狀態機(一種高效的邏輯處理方式)的使用:舉了一個解析http的例子。(由於不知道http的頭部長度,所以我們通過使用狀態機邊解析邊判斷,如果未讀完則繼續讀取,解析出錯則可以直接返回,不用等到全部讀完才解析了)這個有限狀態機的程式碼實現值得研究。
提高伺服器效能的其他建議:
- 使用池(記憶體池,程序池,執行緒池,連線池):以空間換時間,避免對核心的頻繁訪問。記憶體池通常用於socket的接收快取和傳送快取,連線池通常用於伺服器或伺服器群的內部永久連線(例如:每個邏輯單元要訪問資料庫時,直接從連線池中取得一個連線實體並使用,完成之後再返回給連線池)。
- 減少資料複製(比如ftp需要傳送一個檔案,可以直接使用零拷貝函式sendfile,而不用讀到應用緩衝區再發送給核心)
- 上下文切換和鎖:不應該有太多的執行緒,儘量避免使用鎖(鎖不但不處理任何業務邏輯,還需要訪問核心資源),減少鎖的粒度(使用讀寫鎖)。
第九章 IO複用
IO多路複用的應用:
- 客戶端非阻塞的connect,可以同時發起多個連線
- splice函式也可以用來實現零拷貝,將使用者輸入內容直接定向到網路連線上(使用者輸入就是檔案描述符0)。
第十章 訊號
統一事件源:
第十一章 定時器
使用一個連結串列來升序儲存每個定時器的觸發內容,當有定時事件發生時,主迴圈(使用統一事件源)監測到可讀事件就會去遍歷連結串列執行可以執行的定時事件。可以使用這個方法去實現服務端定時清除非活躍連線的功能。
兩種高效的管理定時器的容器:時間輪(雜湊)和時間堆(二叉樹)
高效能IO框架庫libevent
linux伺服器必須處理的三種事件:IO事件,訊號和定時事件(這三種都可以統一事件源)。