# 案例探討: 強化 server-framework 效能 ###### tags: `sysprog2016` :::info 主講人: [jserv](http://wiki.csie.ncku.edu.tw/User/jserv) / 課程討論區: [2016 年系統軟體課程](https://www.facebook.com/groups/system.software2016/) :mega: 返回「[進階電腦系統理論與實作](http://wiki.csie.ncku.edu.tw/sysprog/schedule)」課程進度表 ::: ## 預期目標 * 詳實分析 server-framework 的架構、系統設計,效能評估,以及效能改進方案 * 說明 async, reactor, protocol-server 彼此之間的關聯 * 探討 epoll, pipe, signals 等系統呼叫,以及 server-framework 如何使用 * 多執行緒設計的議題 mutex lock, condition variables, thread pool 對效能的影響 * 分析 HTTP request 和 web server 的行為 * 實做與分析 lock-less thread pool * 提出效能分析 (含 HTTP 1.1 Keep-Alive) 以及改善方案 ## Part 1 * video: [Part 1](https://www.youtube.com/watch?v=YnfQVvL7m0g) * server framework 運作流程 * 說明 async, reactor, protocol-server 彼此之間的關聯 * 實做與分析 lock-less thread pool **報告內容的改進和提問** * 格式: `[ 時間點 ] 簡單描述` * [ 04:06 ] pipe 可否取代為其他機制?是否會對效能產生衝擊? * [ 07:30 ] 不是 "wiki",而是 "Wikipedia" * [ ??:?? ] 接口(對岸術語)->(介面) * [ 03:34 ] epoll 解釋清楚,ready queue(放在哪裡???kernel or user),觀念釐清,讓 kernel 幫我們追蹤 * [ 04:45 ] 取代pipe,用什麼方法,讓thread停下來的方式,semophore * [ 05:32 ] protocol server wait * [ 08:40 ] synchronous 蒐集事件,在一次處理 * [ 10:06 ] if is async -> it is not a reactor !! * [ 11:39 ] 為了命名更符合實際行為,可以將async 改成 thread pool * [ 11:50?? ] 訊號的用語 -> 改為block  * [ 13:34 ] 字要大一點,解釋為甚麼有兩個perform_tasks(async) * 解釋sched_yield():提示sched不再排程這個程式了(linux-2.6.23 改用 [CFS](https://en.wikipedia.org/wiki/Completely_Fair_Scheduler) 後,sched_yield() 行為已不同,基本上不會實際影響 CFS) * [ 15:10 ] reacter_review解釋,後面跳過,thread join示意圖 * [ 17:16 ] socket accept詳細,如何處理同時連線的問題 * [ 20:42] 不用交給下位同學 * [ 22:59 ] Epoll跟poll再甚麼情況下會一樣,如何用ab去測試`-c`? * [ 32:47 ] timeout 的影響,解讀清楚 * [ 33:46 ] 演說須知:麥克風若拿得太靠近嘴緣,會導致回音 * [ 37:34 ] 可以加上git commit * ab+google evidence ## Part 2 * video: [Part 2](https://youtu.be/p_GYmjOGWA0) * 分析 HTTP request 和 web server 的行為 * 探討 epoll, pipe, signals 等系統呼叫,以及 server-framework 如何使用 * 彙整Server-framework行為與改進方式 (workqueue 的效能) * kernel-mode web server 分析,作為日後 Web accelerator 的準備 **報告內容的改進和提問** * [00:42] NCSA [mosaic](https://en.wikipedia.org/wiki/Mosaic_%28web_browser%29) 最早的瀏覽器(browser),支援多種通訊協定 * HTTP:stateless * HTTPS(security): [TLS/SSL is stateful](http://stackoverflow.com/questions/11067500/is-https-stateful-or-stateless)**.**  * [2:21] 最新:HTTP 2.0 * [7:47] 效能好壞與 user space socket 處理方式有關 * [9:01] Why 完成連線與未完成連線的queue只有在kernel裡面並只有kernel專屬?? * 避免像filesystem存取需要大量r/w lock ,socket只須block accept() ,kernel做完再copy到user space,以空間換取時間 * [15:40] unix signal: async ![](https://www.sharcnet.ca/help/images/3/39/Conceptual_picture_of_signals.png) * 如ping 後,在terminate下ctrl+c ,ping中偵測到handler,將統計訊息印出後exit * [30:53] monolithic(kernel是全部包好的),linux module被注入時就是kernel不可分割個一部份 ## Server-framework 效能強化 永勁、仲庭: * [分析 HTTP request 和 web server 的行為](https://embedded2016.hackpad.com/PyTnJGajWfl#分析-HTTP-request-和-web-server-的行為) 紹華: * [說明 async, reactor, protocol-server 彼此之間的關聯](https://embedded2016.hackpad.com/-async-reactor-protocol-server--5uDCriIegs8) 博聖: * [探討 epoll, pipe, signals 等系統呼叫](https://embedded2016.hackpad.com/80jubVZ3ccT#探討-epoll,-pipe,-signals-等系統呼叫) * [http parser](https://embedded2016.hackpad.com/pOh7414xAH3) 鏡清: * [彙整Server-framework行為與改進方式](https://embedded2016.hackpad.com/Server-framework-dydgnlf9Hbw) 鈺融: * [分析 lock-less thread pool](https://embedded2016.hackpad.com/g7nhI7Mrmq2#分析-lock-less-thread-pool) ## Kernel-mode Web Server * [](https://github.com/tianqiu/kernelhttp)https://github.com/tianqiu/kernelhttp * [](https://github.com/george7551858/kernel-web)https://github.com/george7551858/kernel-web * [](https://en.wikipedia.org/wiki/In-kernel_web_server)https://en.wikipedia.org/wiki/In-kernel_web_server * [](https://lwn.net/Articles/580419/)https://lwn.net/Articles/580419/ * [](http://fred-zone.blogspot.tw/2008/02/linux-kernel-space-udp-server.html)http://fred-zone.blogspot.tw/2008/02/linux-kernel-space-udp-server.html * [](https://blog.cloudflare.com/kernel-bypass/)https://blog.cloudflare.com/kernel-bypass/ * [](https://github.com/kaiyuanl/kws)https://github.com/kaiyuanl/kws * [](https://github.com/Taketsuru/khttpd)https://github.com/Taketsuru/khttpd (FreeBSD) * [](http://zqscm.qiniucdn.com/data/20071030095941/index.html)http://zqscm.qiniucdn.com/data/20071030095941/index.html (Chinese) **Action items** * 在 GitHub 上 fork 出自己的版本,後續修正和改良都在裡頭 * 將原本作為參數設定的 Python 程式,用 C 程式重寫 **Kernel server 原理介紹** * 使用 kernel server 必須有一咪咪模組的概念,送您[鳥哥](http://linux.vbird.org/linux_basic/0510osloader.php#kernel_look) * 簡單來說,試著把模組理解成在核心中的執行檔,只不過這個執行檔是必須透過一些手續 ( insmod ) 才能運作的,完成掛載後,此時的你正身處在核心中,那"直接"使用核心的資源就相當正常了!當能使用核心資源時,就會省去原本從 user space 進行系統呼叫時的成本。 * 而這邊所謂的成本就是使用核心資源或者一些需要 kernel mode 運行的操作時,我們並不是直接去存取核心,而是透過切換模式( user -> kernel ),在這樣的前提下,context switch 自然就是成本之一;而另一成本便是 user 與 kernel 在切換時必須將狀態傳送給另外一方,而不是直接的存取,因此這邊的解決辦法便是"複製"一份自身的資訊給對方,而這邊memory copy 的行為也會有成本存在! * 因此讓 server 在核心中直接運行,將可以省去上述成本,也就是 no-copy 的行為!當然 kernel web server 不單純只有在kernel 中運作,還會透過方法與 user space 進行溝通,如 TUX的架構,這邊只簡單介紹 kernel web server 的概念,並未探討 kernel 與 user 之間的溝通方法。 **User space 透過系統呼叫 socket( ) 的實作**: ![](https://hackpad-attachments.s3.amazonaws.com/embedded2016.hackpad.com_Vbmxrh9mRPj_p.572037_1463383801648_%E6%9C%AA%E5%91%BD%E5%90%8D.png) * 這個架構中是需要copy的成本的! **Kernel web server 透過模組直接掛載在 kernel space 之中**: ![](https://hackpad-attachments.s3.amazonaws.com/embedded2016.hackpad.com_Vbmxrh9mRPj_p.572037_1463384021950_%E6%9C%AA%E5%91%BD%E5%90%8D.png) * 圖中 client 直接訪問 kernel 中的 server socket,因此不需要有 copy 的成本! * 要注意的是,此處的 server request handler 是不局限於 user space 的,也可以將處理 request 的工作放在 kernel 之中。 * 在這邊 kernel web 中使用到了 netlink 的系統呼叫,是 kernel 與 user 直接的溝通,在後續實作上也沒有使用到,目前正在研究中,因此暫不說明。 **kernelhttp** * [Link](https://embedded2016.hackpad.com/QcyEen3Ar39#Link) * Our Github:[](https://github.com/oiz5201618/kernelhttp)https://github.com/oiz5201618/kernelhttp * 澄清與解釋 kernelhttp 專案的問題 **kernel-web** * [Link](https://paper.dropbox.com/doc/kernel-web-fTxS0GK9KbeXKxCOc8ffc) * [kweb](https://embedded2016.hackpad.com/1SrYaPOW8eT#kweb)(原本的備份)