# 案例探討: 強化 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)(原本的備份)