monkv開發(fā)筆記

前段時(shí)間又重新看了一遍socket編程,心血來潮寫了一個(gè)mini型的HTTP服務(wù)器,這就是monkv。

monkv GitHub地址:https://github.com/cuihang/monkv

古人說的好,紙上得來終覺淺,絕知此事要躬行。很多東西的原理,大家都能侃侃而談,但具體操作起來,會(huì)面臨各種各樣棘手的小細(xì)節(jié)。真正的高手,講起大道理來未必有什么過人之處,因?yàn)榇蟮牡览碚l都會(huì)說,真正的高手體現(xiàn)在對(duì)具體細(xì)節(jié)的處理上。所以在這里我記錄一下在monkv開發(fā)過程中出現(xiàn)的各種小問題,作為自己的一種技術(shù)積累,也分享給大家,權(quán)作交流。

如何設(shè)置epoll

epoll有兩種模式,ET和LT模式。至于具體的區(qū)別,網(wǎng)上遍地都是講解,這里不展開,這里為什么會(huì)專門提到epoll模式的問題,因?yàn)樵陂_發(fā)過程中,面臨一個(gè)小問題,就是如何保證一個(gè)請(qǐng)求只被一個(gè)線程或者進(jìn)程解析。
就算沒有看過monkv的源碼,也能猜到monkv的大體架構(gòu),無非是主進(jìn)程或者主線程監(jiān)聽epoll上的客戶端socket可讀事件,如果有新的客戶端可讀事件,就新開一個(gè)進(jìn)程或者線程來處理,這是最傳統(tǒng)的多路復(fù)用模型。那么問題來了,假設(shè)一個(gè)客戶端上有一個(gè)可讀事件,我們新開一個(gè)線程來處理。然后這個(gè)客戶端上又發(fā)生了一個(gè)可讀,如果我們?cè)匍_一個(gè)線程,就意味著兩個(gè)線程同時(shí)在處理一個(gè)請(qǐng)求,這就需要涉及到復(fù)雜的同步機(jī)制。所以最好的辦法就是保證一個(gè)請(qǐng)求只能被一個(gè)線程來處理。
這種情況下怎么辦?可能有人會(huì)說設(shè)置et模式呀,請(qǐng)注意,單純?cè)O(shè)置et模式也無法解決這個(gè)問題,因?yàn)閑t模式下,客戶端新的可讀事件也會(huì)被監(jiān)聽到。
最后的解決方案就是設(shè)置EPOLLONESHOT。具體可以google一下EPOLLONESHOT的用法。

如何保存客戶端的解析狀態(tài)

網(wǎng)絡(luò)傳輸是完全不可控的。什么情況都可能發(fā)送。正常情況下,http報(bào)文會(huì)及時(shí)完整的傳輸?shù)絪erver端。server端進(jìn)行解析就可以了,但如果server端得到的http報(bào)文是殘缺的,又該如何解析呢?
注意一個(gè)問題,這里的殘缺不是指順序紊亂或者缺失,tcp是可靠的,這里的殘缺值得是在某個(gè)監(jiān)聽事件里面得到的數(shù)據(jù)是殘缺的,比如說某個(gè)可讀事件上的數(shù)據(jù)是"GET / HT",很明顯,這是個(gè)殘缺的請(qǐng)求報(bào)文。并且可以猜想,該socket上下一個(gè)監(jiān)聽事件讀出來的數(shù)據(jù)肯定是"TP/1.1\r\n......."。這種情況該如何處理呢?
所以需要保存解析狀態(tài),需要搞一個(gè)類似狀態(tài)機(jī)的東西。否則就像剛才的情況,明明是一段正確的報(bào)文,但兩次監(jiān)聽解析都顯示報(bào)文錯(cuò)誤。
還有一個(gè)問題,是狀態(tài)機(jī)該如何保存的問題。epoll_event結(jié)構(gòu)體中標(biāo)識(shí)socket的字段是data,而data是一個(gè)union,包含標(biāo)識(shí)文件描述符的fd和標(biāo)識(shí)指針的ptr。
指針是最方便的,可以指向一個(gè)自定義的request結(jié)構(gòu)體,將讀取的數(shù)據(jù),解析的狀態(tài)都保存在request中。
如果用fd也行,那么需要單獨(dú)維護(hù)一個(gè)fd到狀態(tài)機(jī)的映射關(guān)系,這樣根據(jù)這個(gè)fd就能確定該socket上的數(shù)據(jù)解析到哪一步了。

線程池的實(shí)現(xiàn)

一般不建議用多進(jìn)程,因?yàn)檫M(jìn)程的開銷太大。從效率角度來說,采用多線程比較好,但一個(gè)請(qǐng)求開一個(gè)線程,請(qǐng)求結(jié)束銷毀線程,這樣的開銷也有一點(diǎn)大,最好的方式就是用線程池。
網(wǎng)上很多線程池的實(shí)現(xiàn)代碼。主要是通過互斥鎖和條件變量的方式實(shí)現(xiàn),monkv中的線程池也是這樣實(shí)現(xiàn)的。有興趣可以研究一下。

下一步的工作

monkv只是一個(gè)非常mini的server,目前只能解析get方法,只能處理靜態(tài)資源,與其說是一個(gè)server,倒不如說是我目前的一個(gè)小玩具,離生產(chǎn)環(huán)境還有遙不可及的距離。其實(shí)寫monkv就是寫著玩,就是要做一個(gè)小模型玩具,只是說目前的monkv是一個(gè)粗糙的模型,我想把monkv細(xì)細(xì)打磨,通過寫著玩來提高自己的網(wǎng)絡(luò)編程能力。所以下一步想做以下工作

  • 替換monkv的http解析方法,使之能夠解析更多的http方法
  • 添加對(duì)php lua的支持,使之能夠處理動(dòng)態(tài)腳本
  • 如果一切順利,還希望能夠做成多進(jìn)程,類似nginx那種派生出多個(gè)子進(jìn)程的架構(gòu)。不過這個(gè)就更加復(fù)雜了,目前在想如何處理驚群效應(yīng),能力有限還是沒有太好的方案

想來想去,目前暫時(shí)就是這些問題。雖然monkv是我自己親手寫的,但我對(duì)monkv背后的技術(shù)真的理解嗎?我想我還是不理解的,很多東西就是這樣,你以為你明白了,再過些年回頭看,你還是沒明白,你之所以覺得自己明白,只是很巧合某些東西沒有被暴露出來而已。任何一個(gè)技術(shù)點(diǎn)背后都有很多很多的細(xì)節(jié)。所以還是那句話,紙上得來終覺淺,絕知此事要躬行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,694評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,026評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,193評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,668評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,846評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,394評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容