第1章 源码分析的准备工作
从Nginx(读作engine x)的官方网站,我们可以看到如下介绍:Nginx是Igor Sysoev编写的一款HTTP和反向代理服务器,另外它也可以当作邮件代理服务器。它一直被众多流量巨大的俄罗斯网站所使用,例如Yandex、Mail.Ru、VKontakte以及Rambler等。据Netcraft统计,截止到2012年8月份,世界上最繁忙的网站中有11.48%在使用Nginx作为其服务器或者代理服务器。部分典型成功案例有:Netflix、Wordpress.com和FastMail.FM。鉴于Nginx的强大性能与稳定性,在国内也有大量的高压力网站在使用Nginx,如新浪、网易、腾讯、CSDN、酷六、水木社区、豆瓣等。
1.1 主要特性
作为轻量级HTTP服务的典型代表,Nginx除了具备体积小、配置灵活、并发能力强、稳定等众所周知的特点以外,在官方网站还详细列出了Nginx的一些主要特性,我们来详细了解一下。
1. HTTP服务基本特性
● 处理静态页面请求;
● 处理index首页请求;
● 对请求目录进行列表显示;
● 支持多进程间的负载均衡;
● 对打开文件描述符进行缓存(提高性能);
● 对反向代理进行缓存(加速);
● 支持FastCGI、uwsgi、SCGI和memcached多种后端服务器;
● 支持gzip、ranges、chunked、XSLT、SSI以及图像缩放;
● 支持SSL、TLS SNI。
2. HTTP服务高级特性
● 基于名称的虚拟主机;
● 基于IP的虚拟主机;
● 支持Keep-alive和pipelined连接;
● 灵活和方便的配置;
● 在更新配置和升级执行程序时提供不间断服务;
● 可自定义客户端访问的日志格式;
● 带缓存的日志写操作(提高性能);
● 支持快速的日志文件切换;
● 支持对3xx-5xx错误代码进行重定向;
● URI重写支持正则表达式;
● 根据客户端地址执行不同的功能;
● 支持基于客户端IP地址的访问控制;
● 支持基于HTTP基本认证机制的访问控制;
● 支持HTTP referer验证;
● 支持HTTP协议的PUT、DELETE、MKCOL、COPY以及MOVE方法;
● 支持FLV流和MP4流;
● 支持限速机制;
● 支持单客户端的并发控制;
● 支持Perl脚本嵌入。
3. 邮件代理服务特性
● 使用外部HTTP认证服务器将用户重定向到IMAP/POP3服务器;
● 使用外部HTTP认证服务器将用户重定向到内部SMTP服务器;
● 支持的认证方式。
◆ POP3:USER/PASS、APOP、AUTH LOGIN/PLAIN/CRAM-MD5。
◆ IMAP:sLOGIN、AUTH LOGIN/PLAIN/CRAM-MD5。
◆ SMTP:AUTH LOGIN/PLAIN/CRAM-MD5。
● 支持SSL;
● 支持STARTTLS和STLS。
4. 架构和扩展性
● 一个主进程和多个工作进程配合服务的工作模型;
● 工作进程以非特权用户运行(安全性考虑);
● 支持的事件机制有:kqueue(FreeBSD 4.1+)、epoll(Linux 2.6+)、rt signals(Linux 2.2.19+)、/dev/poll(Solaris 7 11/99+)、event ports(Solaris 10)、select和poll;
● 支持kqueue的众多特性,包括EV_CLEAR、EV_DISABLE(临时禁止事件)、NOTE_LOWAT、EV_EOF等;
● 支持sendfile(FreeBSD 3.1+、Linux 2.2+、Mac OS X 10.5+)、sendfile64(Linux 2.4.21+)和sendfilev(Solaris 8 7/01+);
● 支持异步文件IO(FreeBSD 4.3+、Linux 2.6.22+);
● 支持DIRECTIO(FreeBSD 4.4+、Linux 2.4+、Solaris 2.6+、Mac OS X);
● 支持Accept-filters(FreeBSD 4.1+、NetBSD 5.0+)和TCP_DEFER_ACCEPT(Linux 2.4+);
● 10000个非活跃HTTP keep-alive连接仅占用约2.5MB内存;
● 最少程度的数据拷贝操作。
5. 已测试过的操作系统和平台
● FreeBSD 3~10/i386、FreeBSD 5~10/amd64;
● Linux 2.2~3/i386、Linux 2.6~3/amd64;
● Solaris 9/i386、sun4u、Solaris 10/i386、amd64、sun4v;
● AIX 7.1/powerpc;
● HP-UX 11.31/ia64;
● Mac OS X/ppc、i386;
● Windows XP、Windows Server 2003。
从上面列表可以看到Nginx功能的丰富与强悍。当然,这里给出的还只是Nginx功能的简单描述,而对于每项功能的具体使用以及是如何实现的,我们还不得而知,而这也正是本书将要展开叙述的全部内容。
1.2 源码下载
Nginx的源码可通过官网提供的下载地址找到,截止当前的最新版本是Nginx 1.2.0,也就是本书所针对的版本。虽然官网下载页没有提供Nginx旧版源码的下载链接,但Nginx的所有版本源码包都是放在目录http://nginx.org/download/下的,所以包括Nginx 0.1.0版本在内的Nginx源码都能下载到。
由于Nginx背后有公司运作,所以其更新速度比较快,相关资料也比较齐全,下面是一些有用的网址。
● 官方主页:http://nginx.org/。
● 使用手册:http://nginx.org/en/docs/。
● 配置指令:http://wiki.nginx.org/DirectiveIndex。
● 版本任务:http://trac.nginx.org/nginx/report/2。
● 开发路线图:http://trac.nginx.org/nginx/roadmap。
● 邮件讨论组:http://mailman.nginx.org/mailman/listinfo。
所有相关信息基本都能从官方主页链入,如果想找什么资料,建议先去官网看看。
1.3 源码目录结构
将Nginx源码包解压后,目录文件如下所示。
[root@localhost nginx-1.2.0]# ls -F auto/ CHANGES CHANGES.ru conf/ configure* contrib/ html/ LICENSE man/ README src/
其中
● auto/:包含了很多会在执行configure进行编译配置时调用的检测代码。
● CHANGES:Nginx的版本更新细节记录。英文版。
● CHANGES.ru:Nginx的版本更新细节记录。俄文版。
● conf/:Nginx提供的一些默认配置文件。
● configure*:根据系统环境设定Nginx编译选项的执行脚本。
● contrib/:网友贡献的一些有用脚本。
● html/:提供了两个默认html页面,比如index.html的Welcome to nginx!。
● LICENSE:声明的Nginx源码许可协议。
● man/:Nginx的Man手册,本文文件,可直接用vi或记事本打开。
● README:读我文件,内容很简单,通告一下官网地址。
● src/:Nginx源码,分门别类,比如实现事件的event等,很清晰。
执行configure脚本后将生成Makefile文件和objs目录,这是根据当前系统环境生成的相关编译配置。Nginx并没有使用Autoconf和Automake等这样的自动化工具来做这个工作,而都是手动编码实现的。比如当Nginx判断当前Linux系统是否支持epoll时,它采用的方法就是编写一款小应用程序,并在其中调用epoll_create()函数,然后再根据它是否可被正常编译执行来做这个判断。具体可参考文件nginx-1.2.0/auto/os/linux和nginx-1.2.0/auto/feature内相关代码。
1.4 源码分析工具
对于Windows平台,首选Source Insight源码阅读工具。该工具功能强大,根据其官方网介绍,Source Insight是一款面向项目开发的程序编辑器和代码浏览器,它拥有内置的对C/C++、C#和Java等程序的分析功能。Source Insight能自动分析和动态维护源码工程的符号数据库,并在用户查看代码时显示有用的对应上下文信息。
如果是在Linux平台下,则可以利用Vi、Taglist、Cscope以及Ctag这几个工具来组合成Nginx源码的环境。它们的组合也许要费一段功夫,但磨刀不误砍柴工,为了更方便快捷地阅读Nginx源码,花这点时间还是比较值得的。
当然,我们还有另外一个更方便简单的选择:Source Navigator 。Source Navigator(Sourcenav)是由Red Hat推出的一款查看和分析源代码的强大图形界面工具,可以与前面介绍的Source Insight相媲美,而且Sourcenav是开源的。除了提供源代码的编辑、查看功能,Sourcenav同时还支持编译器和调试器的集成,因此可以构建成一套完整的IDE开发环境。Sourcenav针对Windows和UNIX/Linux,提供两种版本,在Windows下的版本,解压即可以使用,但是要注意解压路径不能包含空格以及中文字符。图1-1所示是Sourcenav在Ubuntu 8.10平台下的运行界面。
图1-1 Sourcenav在Ubuntu 8.10平台下的运行界面
不管是在Windows平台下还是在Linux平台下,搭建一个得心应手的源码阅读环境,是我们阅读源码达到事半功倍效果的有力保证。
1.5 测试辅助工具
我们将在第2章里介绍如何对Nginx进行跟踪与调试,除了对Nginx进程进行直接的跟踪与调试的工具以外,还会用到另外两个HTTP测试工具:wget与curl。关于这两个工具的差别,可以看这里,要注意的主要是wget 1.12及以前的版本仅支持HTTP 1.0协议(虽然也包括部分HTTP 1.1的特性),所以在测试HTTP 1.1的相关特性时,最好使用wget-1.13以后版本或curl。另外,通过给wget加上--debug选项或给curl加上-v选项能看到它们请求的详细信息,这对我们的测试提供的帮助也非常大。
我用到的其他测试辅助工具主要还有如下几个。
● Wireshark:抓包使用。
● Nc:网络工具中的瑞士军刀,短小精悍,功能强大。
● Firefox:结合firebug看HTTP请求响应内容。
● Opera:浏览器,测试HTTP。
● Hexdump:看十六进制数据。
1.6 编译与执行
Nginx的编译安装很简单,使用Linux下通用的三板斧即可:./configure、make、make install。当然,这样做的话,那么一切都是使用的默认配置,如果要做修改,则必须在执行configure时指定,比如对Nginx加上调试功能。
[root@localhost nginx-1.2.0]# ./configure --with-debug
修改默认安装路径。
[root@localhost nginx-1.2.0]# ./configure --prefix=/usr/gqk/
所有这些配置选项可以通过命令查看。
[root@localhost nginx-1.2.0]# ./configure -help
在默认情况下,Nginx被安装在/usr/local/nginx/目录下,而其他目录也大都以此为父目录,比如Web根目录为/usr/local/nginx/html/,日志记录在文件/usr/local/nginx/logs/access.log和/usr/local/nginx/logs/error.log内。
编译好后的Nginx,执行它很简单,一般我们只需指定配置文件即可。
[root@localhost ~]# /home/gqk/nginx-1.2.0/objs/nginx -c /usr/local/nginx/conf/ nginx.conf.test
如果不指定配置文件,那么默认就是安装目录下的nginx.conf文件,比如:/usr/local/nginx/conf/nginx.conf。通过ps命令可以看到Nginx是否已正常执行。
[root@localhost ~]# ps auxf | grep nginx | grep -v grep root 3949 0.0 0.1 5216 572 ? Ss Oct05 0:00 nginx: master process /home/gqk/nginx-1.2.0/objs/nginx -c /usr/local/nginx/conf/nginx.conf.test nobody 3950 0.0 0.354041236 ? T Oct05 0:00 \_ nginx: worker process
查看Nginx对应的监听套接口。
[root@localhost ~]# netstat -natp | grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3949/nginx
1.7 其他准备
本书主要针对的是Nginx的Web服务器功能,这其中牵扯到很多的国际标准协议,比如说HTTP协议、URL标准、HTML标准等。因此,把与之相关的RFC文档准备好是必不可少的。这里列出几个站点,方便查阅。
http://www.rfc.net RFC的官方站点,可以检查RFC最及时的更新情况。
http://www.ietf.org 最重要的Internet组织之一。
http://sunsite.dk RFC查询非常强大(可以以FTP登录下载全部RFC文档)。
http://www.iso.ch ISO-国际标准化组织。
http://standards.ieee.org IEEE-电气与电子工程师协会。
http://web.ansi.org ANSI-美国国家标准化组织。
http://www.itu.int ITU-国际电信同盟。
http://www.rfc-editor.org/ RFC归档搜索网。
http://www.faqs.org/rfcs/ RFC归档搜索网。
http://www.cnpaf.net/ 中国协议分析网。