[原创]nginx等web 服务器设计中关于相关注意事项与心得

最近在开发一个类似于nginx的web server,前面也做了几篇文章来阐述相关问题,现在就近期遇到的几个新问题以及注意事项记录下来。
1、sokcet和文件fd的关闭问题:看起来这是个简单的问题,但是正如内存分配和释放一样,这里也是很容易发生问题的一个地方,在做到反向代理的时候 遇到了一个新的问题,一个fd会伴随这另外的socket fd,或者会产生一个文件fd,这些描述服在一次服务结尾的时候进行释放是理所当然的,但是是程序就会有异常,这些fd很容一在异常处理中被忽略,举例来 说,我在处理keep-alive的长链接的时候就发生了问题,事情是这样的:
一方面不知道用户什么时候关闭连接,第二方面对于一个连接的重用会进行有异于关闭的相关操作,第三方面,如果在接收或者发送的时候数据没有发送接收完全, 那么在socket buff里面的残余数据就会造成下一次epool事件的混淆,但绝大多时候我们无法在server层面一次性接收所有的数据,比如一个post,或者一次 文件上传,需要特殊的处理过程产生容器以及对接收到的数据进行存储处理等等,这些操作需要server将请求转向给目标处理器,sever要做的是处理协 议头部,所以一般来讲首次只会接收很少两的部分,那么剩余的部分就会对下一次连续请求造成影响。
在这个问题的处理过程上我一开始就对于请求相关的文件fd没有处理好,导致在测试的时候看到fd直线上升,本来keep-alive就是为了减少fd,这 种问题开始检查了半天都没有检查出个所以然,然后buff而的数据也是如此,所以我现在的对于buff的处理是这样的,如果数据不包含协议,就说明数据有 问题,直接断掉连接,新的数据会用新的连接来连接,不然就会为了大量无用的数据进行更多的读操作。
所有我的设计核心也就是尽量减少制程的长度server层面能解决的就在server层解决。
资源的释放是一个很复杂的综合能力,既需要设计着的细心,也需要一定的技巧,现在感觉一个好的设计模式是很重要的,为了功能而使设计简化是应该做得,但是 没有任何设计模式,只是简单的流水执行的方法对于复杂一些的工程是行不通的,随着工程的复杂度增加,前面省下来的时间就全都用在了调试和维护上,工程大到 最后肯定是要流产的,对于c语言我要说的就是合理利用指针,特别是函数指针对于模式的改进是很有用的。
2、还有一个两好的log系统是很有用的,初步用c的用户都会直接用printf进行调试,倒是简单明了,但是很难对于整个工程进行这样的调试,我以前的 做法也是printf,结果调试完了一块就把他注释起来,防止影响剩下的部分,结果当不知道问题发生在那个模块的时候,printf调试就显得笨拙了,调 试信息多到你自己都没法看懂,但是log系统的好处就是方便查阅问题的出处,可以用一个控制函数对所有的调试信息进行屏蔽,这样往往能收到意想不到的效 果,另外,建议将Error和Debug分开两个log文件来存储,最好将Recode/log也分开存储,因为这三个功能的还是有一定的差别的,一般来 讲Error是一定要记录的,Debug用于调试,Log用于记录正常访问,但是开启log系统对于系统的性能影响还是满大的,特别对于单机测试的时候发 现log影响大到了50%的将速,对于公网影响小一些,毕竟访问没有那么快,瓶颈还是在网络上。
3、做起来比想象的容易。理解了架构其实写一个server的时候难点就在于调试,而不在于实现具体功能,特别是对于c的程序,调试是很麻烦的,在 windows上还好,vs2008的调试功能还是超级一流的,他能在调试中将链表层层显示出来,感觉非常好,但是对于linux下的用户还是没有那么幸 运。
4、我现在用的是netbeans,感觉还凑活,只是比很多人推荐的c专业编辑器要好,不要相信那个邪,写c代码一定要用文本编辑器或者最基本的代码编辑 器,那是骗人的,我们需要的是产品,任何有利于产品迅速成形的方法和工具都是可以利用的,文言文中有篇文章的中心思想是这样的:君子就是善于利用工具的 人;把自己折腾的头昏眼花不是一个好习惯,耍酷更是没有必要,我到现在还不会手动写make文件,因为我把精力全部放在了架构和模式上了,再有点精力就优 化一下功能函数,但我没有精力向大姑娘绣花一样。
5、写好注释。不管你对架构有多熟悉,哪怕你的代码永远也打算对第三方开放,只要你还会维护这段代代码,就尽量做好注释,月详细越好,因为总有一天你会记不住那么多东西的,等你拿到一段没有注释的代码你自己都会对他实现的公能没有信息。
6、做好测试。如果是一个人写代码很容一忽略测试这一块,只要调试通了就可以了,其实对于c这样的语言很容一出问题的,又没有try catch可用,所以需要对于每一块的功能都要有强力的测试,使用起来才会有信心,测试要用最为极端的调试。另外还有一个好习惯是做好测试输出,比如 hashtable和string函数,他们的测试是有很大的区别的,以后发生了问题每次都重复来测试既伤神又耗力,做好一个输出,比如在web系统中这 种输出就可以在web页面中看到调试,这种灵活的调试有利于稳定的工程进行,nginx就可以对于单独的一个请求进行调试,只有对于内部的运行料如执掌才 会有优秀的产品。
以上建议仅供参考,如果引用请著名出处 netpet csdn致谢!

你可能感兴趣的:(设计模式,Web,nginx,socket,Netbeans)