公司使用goahead做为web服务器,在其基础上进行的二次开发,本来是给A产品做的定制的开发项目,后来移植到了B产品,添加了很多内容。A产品是嵌入式系统,B产品是运行在服务器上的,现在B产品对其性能不满意,上面就说要“优化”,要把一个单进程、单线程的轻量级服务器优化成一个高性能的并发服务器,所以想到了ngnix,故决定对其源码进行下研究,不过和公司的“优化”无关,纯属个人兴趣。
下面开始我的ngnix之旅。
阅读一个软件的代码,按照的我的习惯,都是按照下面的顺序开始阅读的:
1.读main函数,了解整个软件的组成结构,此时不要过于注重细节,知道每个函数是干什么的就可以了。
2 画一张结构体,免得忘了软件的结构
3 选择重要的模块一一开始阅读,对于web服务器,可以以一条http请求为例,看看程序在处理请求时,整个流程。
4.阅读其余模块:比如内存管理、数据结构、日志管理、配置管理等等
对于web服务器,事件处理肯定是最重要的,一般的事件处理机制:select 或者 epoll,后者性能要远好于前者,但是前者写出来的代码很容易移植,而后者就不容易了,windows上类似于epoll的机制为完成端口,在使用上还是有很大差别的。nginx使用的是epoll,而goahead使用的是select,这也是nginx性能好的原因之一。
下面以goahead为例讲解一下处理一条http请求的流程,有人问了,我们研究的不是nginx吗,为什么要讲另外的服务器呢,呵呵,所有的web服务器原理都是一样的,读进一条请求,处理请求,响应请求,不同的是如何读,如何处理,如何响应。先了解下原理,对研究一个较复杂的软件会有很大帮助的,如果你连这个软件是做什么的都不知道,肯定也无法读懂其源码。
1.事件处理:当有请求过来时,将请求读入系统。goahead使用的是经典的select模型,不停的做轮询判断,判断是否有socket可读/写,nginx使用epoll,当有请求时,系统主动通知服务器,如果你对网络编程不了解,或者只知道select,可以先不管如何读的,反正就是把http请求读进来了。
2.http解析模块:解析出当前请求是请求什么的
3.针对请求,做出响应处理,将结果放到发送缓冲区,等待发送
是不是觉得很简单呢,本来就不复杂嘛,下面我总结下,后面我们将要学习的内容:
1.nginx是怎么初始化的,初始化都做了什么
2.nginx的事件处理
3.nginx的http报文解析
学习了上面三点,就基本掌握了nginx的基础了,然后可再继续深入:
1.日志管理
2.内存管理,一个高性能的服务器和内存管理是分不开,这点非常重要,是值得深入学习的。
3.进程管理、线程管理,如何处理并发,一样很重要。
4.基本的数据结构,nginx实现了链表、队列、hash表、树等结构,原来很多书都讲了,不需要多说,不过可以研究下俄罗斯人怎么实现的
5 文件管理
6 模块管理
7 邮件管理
8 代理模块