深入理解Nginx:模块开发与架构解析(第2版)
上QQ阅读APP看书,第一时间看更新

前言

为什么要写这本书

自第1版发行以来,笔者很欣慰得到了广大读者的认可。本书一直致力于说明开发Nginx模块的必备知识,然而由于Nginx功能繁多且性能强大,以致必须要了解的基本技能也很庞杂,而第1版成书匆忙,缺失了几个进阶的技巧描述(例如如何使用变量、slab共享内存等),因此决定在第1版的基础上进一步完善。

事实上,我们总能在nginx.conf配置文件中看到各种带着$符号的变量,只要修改带着变量的这一行行配置,就可以不用编译、部署而使得Nginx具备新功能,这些支持变量的Nginx模块提供了极为灵活的功能,第2版通过新增的第15章详细介绍了如何在模块中支持HTTP变量,包括如何在代码中使用其他Nginx模块提供的变量,以及如何定义新的变量供nginx.conf和其他第三方模块使用等。第16章介绍了slab共享内存,这是一套适用于小块内存快速分配释放的内存管理方式,它非常高效,分配与释放速度都是以纳秒计算的,常用于多个worker进程之间的通信,这比第14章介绍的原始的共享内存通信方式要先进很多。第16章不仅详细介绍了它的实现方式,也探讨了它的优缺点,比如,如果模块间要共享的单个对象常常要消耗数KB的空间,这时就需要修改它的实现(例如增大定义的slab页大小),以避免内存的浪费等。

Nginx内存池在第1版中只是简单带过,第2版中新增了8.7节介绍了内存池的实现细节,以帮助读者用好最基础的内存池功能。

此外,很多读者反馈需要结合TCP来谈谈Nginx,因此在9.10节中笔者试图在不陷入Linux内核细节的情况下,简要介绍了TCP以清晰了解Nginx的事件框架,了解Nginx的高并发能力。

这一版新增的第15章的样例代码可以从http://nginx.taohui.org.cn站点上下载。

因笔者工作繁忙,以致第2版拖稿严重,读者的邮件也无法及时回复,非常抱歉。从这版开始会把曾经的回复整理后放在网站上,想必这比回复邮件要更有效率些。

读者对象

本书适合以下读者阅读。

❑ 对Nginx及如何将它搭建成一个高性能的Web服务器感兴趣的读者。

❑ 希望通过开发特定的HTTP模块实现高性能Web服务器的读者。

❑ 希望了解Nginx的架构设计,学习其怎样充分使用服务器上的硬件资源的读者。

❑ 了解如何快速定位、修复Nginx中深层次Bug的读者。

❑ 希望利用Nginx提供的框架,设计出任何基于TCP的、无阻塞的、易于扩展的服务器的读者。

背景知识

如果仅希望了解怎样使用已有的Nginx功能搭建服务器,那么阅读本书不需要什么先决条件。但如果希望通过阅读本书的第二、第三两部分,来学习Nginx的模块开发和架构设计技巧时,则必须了解C语言的基本语法。在阅读本书第三部分时,需要读者对TCP有一个基本的了解,同时对Linux操作系统也应该有简单的了解。

如何阅读本书

我很希望将本书写成一本“step by step”式(循序渐进式)的书籍,因为这样最能节省读者的时间,然而,由于3个主要写作目的想解决的问题都不是那么简单,所以这本书只能做一个折中的处理。

在第一部分的前两章中,将只探讨如何使用Nginx这一个问题。阅读这一部分的读者不需要了解C语言,就可以学习如何部署Nginx,学习如何向其中添加各种官方、第三方的功能模块,如何通过修改配置文件来更改Nginx及各模块的功能,如何修改Linux操作系统上的参数来优化服务器性能,最终向用户提供企业级的Web服务器。这一部分介绍配置项的方式,更偏重于领着对Nginx还比较陌生的读者熟悉它,通过了解几个基本Nginx模块的配置修改方式,进而使读者可以通过查询官网、第三方网站来了解如何使用所有Nginx模块的用法。

在第二部分的第3章~第7章中,都是以例子来介绍HTTP模块的开发方式的,这里有些接近于“step by step”的学习方式,我在写作这一部分时,会通过循序渐进的方式使读者能够快速上手,同时会穿插着介绍其常见用法的基本原理。

在第三部分,将开始介绍Nginx的完整框架,阅读到这里将会了解第二部分中HTTP模块为何以此种方式开发,同时将可以轻易地开发Nginx模块。这一部分并不仅仅满足于阐述Nginx架构,而是会探讨其为何如此设计,只有这样才能抛开HTTP框架、邮件代理框架,实现一种新的业务框架、一种新的模块类型。

对于Nginx的使用还不熟悉的读者应当从第1章开始学习,前两章将帮助你快速了解Nginx。

使用过Nginx,但对如何开发Nginx的HTTP模块不太了解的读者可以直接从第3章开始学习,在这一章阅读完后,即可编写一个功能大致完整的HTTP模块。然而,编写企业级的模块必须阅读完第4章才能做到,这一章将会介绍编写产品线上服务器程序时必备的3个手段。第5章举例说明了两种编写复杂HTTP模块的方式,在第三部分会对这两个方式有进一步的说明。第6章介绍一种特殊的HTTP模块——HTTP过滤模块的编写方法。第7章探讨基础容器的用法,这同样是复杂模块的必备工具。

如果读者对于普通HTTP模块的编写已经很熟悉,想深入地实现更为复杂的HTTP模块,或者想了解邮件代理服务器的设计与实现,或者希望编写一种新的处理其他协议的模块,或者仅仅想了解Nginx的架构设计,都可以直接从第8章开始学习,这一章会从整体上系统介绍Nginx的模块式设计。第9章的事件框架是Nginx处理TCP的基础,这一章无法跳过。阅读第8章、第9章时可能会遇到许多第7章介绍过的容器,这时可以回到第7章查询其用法和意义。第10章~第12章在介绍HTTP框架,通过这3章的学习会对HTTP模块的开发有深入的了解,同时可以学习HTTP框架的优秀设计。第13章简单介绍了邮件代理服务器的设计,它近似于简化版的HTTP框架。第14章介绍了进程间同步的工具。第15章介绍了HTTP变量,包括如何使用已有变量、支持用户在nginx.conf中修改变量的值、支持其他模块开发者使用自己定义的变量等。第16章介绍了slab共享内存,该内存极为高效,可用于多个worker进程间的通信。

为了不让读者陷入代码的“汪洋大海”中,在本书中大量使用了图表,这样可以使读者快速、大体地了解流程和原理,在这基础上,如果读者还希望了解代码是如何实现的,可以针对性地阅读源代码中的相应方法。在代码的关键地方会通过添加注释的方式加以说明。希望这种方式能够帮助读者减少阅读花费的时间,更快、更好地把握住Nginx,同时深入到细节中。

写作本书第1版时,Nginx的最新稳定版本是1.0.14,所以当时是基于此版本来写作的。截止到第2版完成时,Nginx的稳定版本已经上升到了1.8.0。但这不会对本书的阅读造成困惑,笔者验证过示例代码,均可以运行在最新版本的Nginx中,这是因为本书主要是在介绍Nginx的基本框架代码,以及怎样使用这些框架代码开发新的Nginx模块。在这些基本框架代码中,Nginx一般不会做任何改变,否则已有的大量Nginx模块将无法工作,这种损失是不可承受的。而且Nginx框架为具体的功能模块提供了足够的灵活性,修改功能时很少需要修改框架代码。

Nginx是跨平台的服务器,然而这本书将只针对于最常见的Linux操作系统进行分析,这样做一方面是篇幅所限,另一方面则是本书的写作目的主要在于告诉大家如何基于Nginx编写代码,而不是怎样在一个具体的操作系统上修改配置使用Nginx。因此,即使本书以Linux系统为代表讲述Nginx,也不会影响使用其他操作系统的读者阅读,操作系统的差别相对于本书内容的影响实在是非常小。

勘误和支持

由于作者的水平有限,加之编写的时间也很仓促,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。为此,我特意创建了一个在线支持与应急方案的二级站点:http://nginx.weebly.com。读者可以将书中的错误发布在Bug勘误表页面中,同时如果读者遇到任何问题,也可以访问Q&A页面,我将尽量在线上为读者提供最满意的解答。书中的全部源文件都将发布在这个网站上,我也会将相应的功能更新及时发布出来。如果你有更多的宝贵意见,也欢迎你发送邮件至我的邮箱russelltao@foxmail.com,期待能够听到读者的真挚反馈。

致谢

我首先要感谢Igor Sysoev,他在Nginx设计上展现的功力令人折服,正是他的工作成果才有了本书诞生的意义。

lisa是机械工业出版社华章公司的优秀编辑,非常值得信任。在这半年的写作过程中,她花费了很多时间、精力来阅读我的书稿,指出了许多文字上和格式上的错误,她提出的建议都大大提高了本书的可读性。

在这半年时间里,一边工作一边写作给我带来了很大的压力,所以我要感谢我的父母在生活上对我无微不至的照顾,使我可以全力投入到写作中。繁忙的工作之余,写作又占用了休息时间的绝大部分,感谢我的太太毛业勤对我的体谅和鼓励,让我始终以高昂的斗志投入到本书的写作中。

感谢我工作中的同事们,正是在与他们一起战斗在一线的日子里,我才不断地对技术有新地感悟;正是那些充满激情的岁月,才使得我越来越热爱服务器技术的开发。

谨以此书,献给我最亲爱的家人,以及众多热爱Nginx的朋友。

陶辉

2015年10月