欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

怎么去實(shí)現(xiàn)一個(gè)WebServer

最近重構(gòu)了去年造的一個(gè)輪子 Vino。Vino 旨在實(shí)現(xiàn)一個(gè)輕量并且能夠保證性能的 Web Server,僅關(guān)注 Web Server 的本質(zhì)部分。在重構(gòu)過(guò)程中,Vino 借鑒了許多優(yōu)秀開(kāi)源項(xiàng)目的思想,如 Nginx、Mongoose 和 Webbench。因此,對(duì)比上一個(gè)版本的 Vino,現(xiàn)在的 Vino 不僅性能得到提升,而且設(shè)計(jì)也更為優(yōu)雅、健壯 :D。

港閘網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)成立與2013年到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。

本文將會(huì)對(duì) Vino 目前所具備的關(guān)鍵特性進(jìn)行闡述,并總結(jié)開(kāi)發(fā)過(guò)程中的一點(diǎn)心得。

單線程 + Non-Blocking

Vino 整體采用了基于事件驅(qū)動(dòng)的單線程 + Non-Blocking 模型。采用單線程模型,避免了系統(tǒng)分配多線程及線程之間通信的開(kāi)銷(xiāo),同時(shí)降低了內(nèi)存的耗用。由于采用了單線程模型,為了更好的提高線程利用率,Vino 將默認(rèn) Blocking 的 I/O 設(shè)置為 Non-Blocking I/O,即在線程讀/寫(xiě)數(shù)據(jù)的過(guò)程中,如果緩沖區(qū)為空/緩沖區(qū)滿,線程不會(huì)阻塞,而是立即返回,并設(shè)置 errno。

Vino 最初的靈感來(lái)源于 Computer Systems: A Programmer\'s Perspective 一書(shū)講述網(wǎng)絡(luò)編程時(shí)實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的 Web Server,每到來(lái)一個(gè)請(qǐng)求,Web Server 都會(huì) fork 一個(gè)進(jìn)程去處理。顯然,在高并發(fā)的場(chǎng)景下,這種模型是不合理的。每次 fork 進(jìn)程會(huì)帶來(lái)巨大的開(kāi)銷(xiāo),并且系統(tǒng)中進(jìn)程的數(shù)量是有限的。同時(shí),伴隨多進(jìn)程帶來(lái)的進(jìn)程調(diào)度的開(kāi)銷(xiāo)也不可小覷,CPU 會(huì)花費(fèi)大量的時(shí)間用于決定調(diào)用哪一個(gè)進(jìn)程。進(jìn)程調(diào)度引發(fā)的進(jìn)程上下文之間的切換,也需要耗費(fèi)相當(dāng)大的資源。

很容易聯(lián)想到采用多線程模型來(lái)替代多進(jìn)程模型,相比于多進(jìn)程模型,多線程模型占用的系統(tǒng)資源會(huì)大大降低,但是本質(zhì)上并沒(méi)有減小線程調(diào)度帶來(lái)的開(kāi)銷(xiāo)。為了減小由線程調(diào)度導(dǎo)致的開(kāi)銷(xiāo),我們可以采用線程池模型,即固定線程的數(shù)量,但是問(wèn)題依舊存在:因?yàn)?Linux 默認(rèn) I/O 是阻塞(Blocking)的,如果線程池中所有的線程同時(shí)阻塞于正在處理的請(qǐng)求,那么新到來(lái)的請(qǐng)求就沒(méi)有線程去處理了。因此,如果我們用 Non-Blocking 的 I/O 替換默認(rèn)的 Blocking I/O,線程將不會(huì)阻塞于數(shù)據(jù)的讀寫(xiě),問(wèn)題便可得到解決。

HTTP Keep-Alive

Vino 支持 HTTP 長(zhǎng)連接(Persistent Connections),即多個(gè)請(qǐng)求可以復(fù)用同一個(gè) TCP 連接,以此減少由 TCP 建立/斷開(kāi)連接所帶來(lái)的性能開(kāi)銷(xiāo)。每到來(lái)一個(gè)請(qǐng)求,Vino 會(huì)對(duì)請(qǐng)求進(jìn)行解析,判斷請(qǐng)求頭中是否存在 Connection: keep-alive 請(qǐng)求頭。如果存在,在處理完一個(gè)請(qǐng)求后會(huì)保持連接,并對(duì)數(shù)據(jù)緩沖區(qū)(用于保存請(qǐng)求內(nèi)容,響應(yīng)內(nèi)容)及狀態(tài)標(biāo)記進(jìn)行重置,否則,關(guān)閉連接。

關(guān)于 HTTP Keep-Alive 的優(yōu)勢(shì),RFC 2616 有著更完善的總結(jié),引用如下。

By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.

HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.

Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.

Latency on subsequent requests is reduced since there is no time spent in TCP\'s connection opening handshake.

HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old semantics after an error is reported.

定時(shí)器 Timer

如果一個(gè)請(qǐng)求在建立連接后遲遲沒(méi)有發(fā)送數(shù)據(jù),或者對(duì)方突然斷電,應(yīng)該如何處理?我們需要實(shí)現(xiàn)定時(shí)器來(lái)處理超時(shí)的請(qǐng)求。Vino 定時(shí)器的實(shí)現(xiàn)參考了 Nginx 的設(shè)計(jì),Nginx 使用一顆紅黑樹(shù)來(lái)存儲(chǔ)各個(gè)定時(shí)事件,每次事件循環(huán)時(shí)從紅黑樹(shù)中不斷找出最小(早)的事件,如果超時(shí)則觸發(fā)超時(shí)處理。為了簡(jiǎn)化實(shí)現(xiàn),在 Vino 中,我實(shí)現(xiàn)了一個(gè)小頂堆來(lái)存儲(chǔ)定時(shí)事件,如果被處理的定時(shí)事件同時(shí)支持長(zhǎng)連接,那么在該請(qǐng)求處理完畢后會(huì)更新該請(qǐng)求對(duì)應(yīng)的定時(shí)器,也就是重新計(jì)時(shí)。定時(shí)器相關(guān)代碼見(jiàn) vn_event_timer.h 和 vn_event_timer.c。

HTTP Parser

由于網(wǎng)絡(luò)的不確定性,我們并不能保證一次就能讀取所有的請(qǐng)求數(shù)據(jù)。因此,對(duì)于每一個(gè)請(qǐng)求,我們都會(huì)開(kāi)辟一段緩沖區(qū)用于保存已經(jīng)讀取到的數(shù)據(jù)。同時(shí),我們需要同時(shí)對(duì)讀取到的數(shù)據(jù)進(jìn)行解析,以保證讀取到的數(shù)據(jù)都是合理的數(shù)據(jù),例如,假設(shè)目前緩沖區(qū)內(nèi)的數(shù)據(jù)為 GET /index.html HTT,那么下一次讀取到的字符必須為 P,否則,應(yīng)立即檢測(cè)出當(dāng)前請(qǐng)求是一個(gè)異常的請(qǐng)求,并主動(dòng)關(guān)閉當(dāng)前的連接。

基于以上分析,我們需要實(shí)現(xiàn)一個(gè) HTTP 狀態(tài)機(jī)(Parser)來(lái)維持當(dāng)前的解析狀態(tài),Vino 狀態(tài)機(jī)的實(shí)現(xiàn)參考了 Nginx 的設(shè)計(jì),并對(duì) Nginx 的實(shí)現(xiàn)做了簡(jiǎn)化。HTTP Parser 相關(guān)代碼見(jiàn) vn_http_parse.h 和 vn_http_parse.c。

Memory Pool

我們一般使用 malloc/calloc/free 來(lái)分配/釋放內(nèi)存,但是這些函數(shù)對(duì)于一些需要長(zhǎng)時(shí)間運(yùn)行的程序來(lái)說(shuō)會(huì)有一些弊端。頻繁使用這些函數(shù)分配和釋放內(nèi)存,會(huì)導(dǎo)致內(nèi)存碎片,不容易讓系統(tǒng)直接回收內(nèi)存。典型的例子就是大并發(fā)頻繁分配和回收內(nèi)存,會(huì)導(dǎo)致進(jìn)程的內(nèi)存產(chǎn)生碎片,并且不會(huì)立馬被系統(tǒng)回收。

使用內(nèi)存池分配內(nèi)存,可以在一定程度上提升內(nèi)存分配的效率,不需要每次都調(diào)用 malloc/calloc 函數(shù)。同時(shí),使用內(nèi)存池使得內(nèi)存管理更加簡(jiǎn)單。在 Vino 中,針對(duì)每一個(gè)請(qǐng)求,Vino 都會(huì)為其分配一或多個(gè)內(nèi)存池(各個(gè)內(nèi)存池形成一個(gè)單鏈表),在請(qǐng)求處理完畢后,一并釋放所有的內(nèi)存。

Vino 內(nèi)存池的實(shí)現(xiàn)依舊參考了 Nginx 的實(shí)現(xiàn),并做了簡(jiǎn)化,Memory Pool 相關(guān)代碼見(jiàn) vn_palloc.h 和 vn_palloc.c。

其他

在開(kāi)發(fā) Vino 的過(guò)程中,還有許多需要考慮和權(quán)衡的地方。響應(yīng)請(qǐng)求時(shí),如果用戶(hù)請(qǐng)求的是一個(gè)很大的文件,導(dǎo)致寫(xiě)緩沖區(qū)滿,我們?nèi)绾胃玫脑O(shè)計(jì)響應(yīng)緩沖區(qū)?如何更高效的設(shè)計(jì)底層數(shù)據(jù)結(jié)構(gòu)(如字符串、鏈表、小頂堆等)?如何更優(yōu)雅的解析命令行參數(shù)?如何對(duì)特定信號(hào)進(jìn)行處理?如何更健壯的處理錯(cuò)誤信息?當(dāng)代碼的數(shù)量達(dá)到一定程度后,如何更快的定位異常代碼?

Vino 的開(kāi)發(fā) & 重構(gòu)暫時(shí)告一段落,源碼放在了 GitHub 上。當(dāng)然,Vino 還有許多不足之處,以及未實(shí)現(xiàn)的特性。

僅支持 HTTP GET 方法,暫不支持其他 HTTP method。

暫不支持動(dòng)態(tài)請(qǐng)求的處理。

支持的 HTTP/1.1 特性有限。

...

寫(xiě)這篇文章,希望對(duì)初學(xué)者有所幫助。

網(wǎng)頁(yè)題目:怎么去實(shí)現(xiàn)一個(gè)WebServer
分享鏈接:http://aaarwkj.com/article26/chcdjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)品牌網(wǎng)站建設(shè)、ChatGPT標(biāo)簽優(yōu)化、虛擬主機(jī)、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
日本欧美一区二区三区高清| 亚洲不卡一区二区在线| 国产91高清在线观看| 曰韩av毛片在线观看| 亚洲伦理第一页中文字幕| 亚州中文字幕久久一区| 欧美日韩亚洲一区二区搜索| 久久久精品免费福利视频| 无人视频在线观看高清91| 羞涩插射视频网站在线观看| 人妻少妇被粗大爽av| dy888午夜福利精品国产97| 亚洲国产欧美在线人成人| 日本人妻精品在线观看| 国产伊人久久综合网| 白白日韩欧美在线视频| 国产三级国产剧情国产av| 女子张开腿让男人捅爽| 熟女乱熟乱熟妇综合网二区| 日韩一区二区三区高清免费视频成人| 亚洲国产精品日韩专区av有中文| 欧美精品亚洲二区中文乱码| 美女口爆吞精一区二区| 日韩精品一区二区三区电影在线播放| 视频久久这里只有精品| 五月婷婷丁香视频在线| 亚洲av成人噜噜网站| 国产精品超碰在线观看| 国产精品亚洲精品久久| 深夜福利视频一区二区| 国产午夜精品一区二区三区| 国产麻豆精品传媒av| 日韩精品一区三区二区| 欧美日韩性生活视频在线| 91在线视频国产网站| 国产老熟女高潮视频| 国产第一页国产第一页| 欧美大片黄片在线观看| 69精品一区二区蜜桃视频| 日本在线电影一区二区三区| 天堂av一区二区在线播放|