monkv开发笔记

前段时间又重新看了一遍socket编程,心血来潮写了一个mini型的HTTP服务器,这就是monkv。

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

古人说的好,纸上得来终觉浅,绝知此事要躬行。很多东西的原理,大家都能侃侃而谈,但具体操作起来,会面临各种各样棘手的小细节。真正的高手,讲起大道理来未必有什么过人之处,因为大的道理谁都会说,真正的高手体现在对具体细节的处理上。所以在这里我记录一下在monkv开发过程中出现的各种小问题,作为自己的一种技术积累,也分享给大家,权作交流。

如何设置epoll

epoll有两种模式,ET和LT模式。至于具体的区别,网上遍地都是讲解,这里不展开,这里为什么会专门提到epoll模式的问题,因为在开发过程中,面临一个小问题,就是如何保证一个请求只被一个线程或者进程解析。
就算没有看过monkv的源码,也能猜到monkv的大体架构,无非是主进程或者主线程监听epoll上的客户端socket可读事件,如果有新的客户端可读事件,就新开一个进程或者线程来处理,这是最传统的多路复用模型。那么问题来了,假设一个客户端上有一个可读事件,我们新开一个线程来处理。然后这个客户端上又发生了一个可读,如果我们再开一个线程,就意味着两个线程同时在处理一个请求,这就需要涉及到复杂的同步机制。所以最好的办法就是保证一个请求只能被一个线程来处理。
这种情况下怎么办?可能有人会说设置et模式呀,请注意,单纯设置et模式也无法解决这个问题,因为et模式下,客户端新的可读事件也会被监听到。
最后的解决方案就是设置EPOLLONESHOT。具体可以google一下EPOLLONESHOT的用法。

如何保存客户端的解析状态

网络传输是完全不可控的。什么情况都可能发送。正常情况下,http报文会及时完整的传输到server端。server端进行解析就可以了,但如果server端得到的http报文是残缺的,又该如何解析呢?
注意一个问题,这里的残缺不是指顺序紊乱或者缺失,tcp是可靠的,这里的残缺值得是在某个监听事件里面得到的数据是残缺的,比如说某个可读事件上的数据是"GET / HT",很明显,这是个残缺的请求报文。并且可以猜想,该socket上下一个监听事件读出来的数据肯定是"TP/1.1\r\n......."。这种情况该如何处理呢?
所以需要保存解析状态,需要搞一个类似状态机的东西。否则就像刚才的情况,明明是一段正确的报文,但两次监听解析都显示报文错误。
还有一个问题,是状态机该如何保存的问题。epoll_event结构体中标识socket的字段是data,而data是一个union,包含标识文件描述符的fd和标识指针的ptr。
指针是最方便的,可以指向一个自定义的request结构体,将读取的数据,解析的状态都保存在request中。
如果用fd也行,那么需要单独维护一个fd到状态机的映射关系,这样根据这个fd就能确定该socket上的数据解析到哪一步了。

线程池的实现

一般不建议用多进程,因为进程的开销太大。从效率角度来说,采用多线程比较好,但一个请求开一个线程,请求结束销毁线程,这样的开销也有一点大,最好的方式就是用线程池。
网上很多线程池的实现代码。主要是通过互斥锁和条件变量的方式实现,monkv中的线程池也是这样实现的。有兴趣可以研究一下。

下一步的工作

monkv只是一个非常mini的server,目前只能解析get方法,只能处理静态资源,与其说是一个server,倒不如说是我目前的一个小玩具,离生产环境还有遥不可及的距离。其实写monkv就是写着玩,就是要做一个小模型玩具,只是说目前的monkv是一个粗糙的模型,我想把monkv细细打磨,通过写着玩来提高自己的网络编程能力。所以下一步想做以下工作

  • 替换monkv的http解析方法,使之能够解析更多的http方法
  • 添加对php lua的支持,使之能够处理动态脚本
  • 如果一切顺利,还希望能够做成多进程,类似nginx那种派生出多个子进程的架构。不过这个就更加复杂了,目前在想如何处理惊群效应,能力有限还是没有太好的方案

想来想去,目前暂时就是这些问题。虽然monkv是我自己亲手写的,但我对monkv背后的技术真的理解吗?我想我还是不理解的,很多东西就是这样,你以为你明白了,再过些年回头看,你还是没明白,你之所以觉得自己明白,只是很巧合某些东西没有被暴露出来而已。任何一个技术点背后都有很多很多的细节。所以还是那句话,纸上得来终觉浅,绝知此事要躬行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容