书名:精通Nginx(第2版)
ISBN:978-7-115-45996-1
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
• 著 [瑞士] Dimitri Aivaliotis
译 李红军
责任编辑 陈冀康
• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
• 读者服务热线:(010)81055410
反盗版热线:(010)81055315
Copyright ©2017 Packt Publishing.
First published in the English language under the title Mastering NGINX,Second Edition.
All rights reserved.
本书由英国Packt Publishing公司授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。
版权所有,侵权必究。
Nginx是一个高性能的轻量级Web服务器,本书从配置文件的角度出发,介绍了多种关于Nginx配置的技巧。
本书以模块化风格写成,几乎每一章都是一个独立的模块,读者将能够自由地在各个模块间切换阅读。全书分两部分,第一部分用9章内容介绍了安装Nginx及第三方模块、配置向导、使用mail模块、Nginx作为反向代理、Nginx Http服务器、Nginx的开发、在Nginx中集成Lua以及故障排除技巧;第二部分用4个附录的形式介绍了指令参考、Rewrite规则指南、Nginx社区以及Solaris系统下的网络调优。
本书适合在安装和配置服务器方面有经验的系统管理员或系统工程师,阅读本书不需要任何Nginx使用经验,相信这本书会帮助读者更好地完成任务。
从构建基于Linux的计算机网络到为银行构建多数据中心的高可用性基础设施和流行的门户网站,他在解决客户问题上已经花费了10多年时间,并且在这条路上发现了Nginx。
Dimitri以最优异的成绩获得了伦斯勒理工学院的理科学士,并且获得了佛罗里达州立大学管理信息系统的理科硕士。
人们会认为第2版应该很容易撰写,纠正第1版的错误并更新其内容。一方面,这比从头开始撰写要少写很多,但另一方面,一切都必须重新评估。它不像起初看起来那么容易。
我要感谢所有审稿人,让我诚实,并指出阐述不清楚的内容。当然,剩下的任何错误是我自己的。
感谢Packt再次给我撰写这本书的机会。
感谢Nginx公司创建一个如此灵活和高效的产品,它在当今仍被广泛使用。
Markus Jelsma是Openindex私人有限公司的CTO与共同所有人,Openindex私人有限公司是一家专门从事开源搜索和爬虫解决方案的荷兰公司。作为Apache Nutch的提交者和PMC成员,他是搜索引擎技术和爬虫解决方案方面的专家。
Nginx是俄罗斯软件工程师Igor Sysoev开发的免费开源Web服务器软件。Nginx于2004年发布,聚焦于轻量级、高并发、高性能、高度模块化的设计与低内存消耗问题。它具有多种Web服务器功能特性:负载均衡、缓存、访问控制、带宽控制以及高效整合各种应用的能力,这些特性使得Nginx很适合于现代网站架构。目前,Nginx是互联网上仅次于Apache的第二流行的开源Web服务器软件。
《精通Nginx(第2版)》一书是艾维利的代表作,该书第1版于2013年3月出版,时隔3年,本书第2版于2016年7月出版。在《精通Nginx(第2版)》中,艾维利从配置文件的角度出发,介绍了多种关于Nginx的配置技巧。本书以模块化风格写成,几乎每一章都是一个独立的模块,读者将能够自由地在各个模块间切换阅读。全书分两部分,第一部分用9章内容介绍了安装Nginx及第三方模块、配置指南、使用mail模块、Nginx作为反向代理、反向代理高级话题、Nginx HTTP服务器、Nginx的开发、在Nginx中集成Lua以及故障排除技巧;第二部分用4个附录的形式介绍了指令参考、Rewrite规则指南、Nginx社区以及Solaries系统下的网络调优。了解Nginx新版本的新内容、熟练掌握Nginx的开发并将其灵活运用在工作环境中,这些都是Nginx用户和Web开发人员的迫切需求。
感谢原作者艾维利,感谢他为全球的Nginx开发者带来了这本充满智慧的Nginx图书。感谢本书第1版译者陶利军老师所做的工作。感谢人民邮电出版社信息技术分社引进如此高品质的图书,感谢人民邮电出版社的陈冀康老师对我的信任,把这本书交给了我翻译。他在本书编辑过程中所表现出来的热心、耐心和敬业精神令我十分感动,与陈冀康老师合作,让人非常愉快!人民邮电出版社的编辑们为本书的出版在幕后做了大量艰苦细致的工作,才让本书得以面世,译者谨向他们表示衷心的感谢。希望所有使用Nginx以及对Nginx开发感兴趣的读者都能从中获益。
译者也是抱着一颗炽热的学习之心在阅读和翻译本书的,并且希望把这本书推荐给身边更多的朋友。由于译者自身对本书内容的理解深度可能有所欠缺,在翻译的过程中难免出现一些不够准确或者不清楚的描述。读者若发现翻译处理不当之处,欢迎批评指正。
最后,需要深深感谢在翻译过程中给予我理解、支持、帮助的家人和朋友们。
李红军
2016年12月19日
hjliemail@yahoo.com
Nginx是一台高性能Web服务器,它使用了非常少的系统资源。在互联网上出现很多how-to和示例配置文件,这会澄清Nginx配置的浑水。这样做,你将会学到在各种环境中如何调整Nginx以及一些模糊的配置选项,以便设计一个符合你需求的配置文件。
在已经理解了如何根据自己的需求来构建一个配置文件后,你就不再需要复制、粘贴、配置片段了。这是一个过程,而且会有曲折。不过本书有关技巧的解释,会使你觉得手写配置文件是一件很舒服的事情。万一事情不像期望中的那样工作,你将能够独立地调试该问题,或者至少能够寻求帮助,而不会觉得自己好像都没有尝试过。
这是一本以现代风格所写的书,这种设计有助于你尽可能快地获取信息。几乎每一章都是一个独立模块,你可以根据需要自由地跳到任何地方来获取更深入的特定主题。如果觉得错过了某些主要的内容,那么你可以返回去读取前面的章节。它们在这种方式下构建,以帮助你的配置文件一步步成长。
第1章,安装Nginx及第三方模块。教你如何在选择的操作系统上安装Nginx以及在你的安装中如何包含第三方模块。
第2章,配置指南,讲解Nginx的配置文件格式,你将学到每一个不同区段的配置,如何配置全局参数以及location的用处。
第3章,使用mail模块,探索Nginx的邮件代理模块,详细介绍配置的方方面面。在本章中,还有一个认证服务的代码示例。
第4章,Nginx作为反向代理,介绍反向代理的概念,并且描述Nginx如何充当该角色。
第5章,反向代理高级话题,深入研究使用Nginx作为反向代理解决可伸缩及性能的问题。
第6章,Nginx HTTP服务器,描述如何使用各种模块,包括通过Nginx解决常见的Web服务问题。
第7章,Nginx的开发,展示Nginx如何与你的应用程序集成,以便更快速地把内容交付给你的用户。
第8章,在Nginx中集成Lua,对如何使用嵌入式脚本语言Lua扩展Nginx功能提供一个概览。
第9章,故障排除技巧,研究一些常见的配置文件,一旦出现问题如何调试,以及调优性能的一些建议。
附录A,指令参考,提供一个方便的配置指令参考,这些指令贯穿全书,也有一些以前未覆盖到的其他指令。
附录B,Rewrite规则指南,描述如何使用Nginx的Rewrite规则模块,并描述将Apache格式的rewrite规则转换为Nginx可处理的rewrite规则的一些步骤。
附录C,Nginx社区,介绍可以搜寻到的更多的线上资源。
附录D,Solaris系统下的网络调优,详述Solaris 10及以上版本系统下的网络调优的必要性。
任何现代Linux PC都能充分运行本书中的示例代码。示例代码在每一章都给定了安装操作指南。基本上可以归纳如下。
这本书适用有经验的系统管理员或者系统工程师,熟悉服务器的安装和配置以满足特定的需求。你不需要有使用Nginx的经验。
本书采用了一些不同风格的文本样式,便于区分不同的信息。这里有一些格式的示例,并有解释说明。
文本格式的代码字符、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟URL、用户输入和Twitter处理如下列格式显示:“This section will be placed at the top of the nginx.conf configuration file.”
代码块设置如下:
http {
include /opt/local/etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server_names_hash_max_size 1024;
}
任何命令行输入或者输出书写如下:
$ mkdir $HOME/build
$ cd $HOME/build && tar xzf nginx-.tar.gz
新术语与重要的字以粗体显示。你在屏幕上看到的字,例如,在菜单或者对话框中,会出现类似这样的版本:“Clicking theNext button moves you to the next screen.”
警告或者重要的事项出现在这样的框内。
提示和技巧以这种方式显示。
从读者获悉的反馈总是受欢迎的,它让我们知道你对本书的想法——什么是你喜欢的,什么是你不喜欢的。对于我们而言,读者反馈很重要,它使我们的课题发挥更大作用。
向我们发送一般的反馈,只需简单地发送电子邮件至feedback@packtpub.com,并且在邮件的主题部分提及本书名称就可以了。
如果有你擅长的主题,并且你对写作或者投稿感兴趣,那么你可以看看我们的作者向导www.packtpub.com/authors。
现在你自豪地成为Packt书的读者了。我们可以为你提供若干售后服务。
你可以从http://www.packtpub.com上用你的账号下载本书的示例代码,如果你从别的地方购买了这本书,你可以访问http://www.packtpub.com/support并注册,那么代码会以邮件的形式直接发送给你。
你可以通过如下步骤来下载代码文件。
1.使用你的电子邮件地址和密码登录或注册我们的网站。
2.鼠标指针悬浮在顶部的SUPPORT标签。
3.单击Code Downloads & Errata。
4.在Search框中,输入书名。
5.选择你要下载代码文件的图书。
6.从下拉菜单中选择你购买的图书。
7.单击Code Download。
下载完代码文件后,请确保你使用了如下最新版本的软件来解压或提取文件夹。
我们还为你提供了PDF文件,它载有本书使用到的截图。这些彩图可以更好地帮助你理解输出中的变化。你可以从http://www.packtpub.com/sites/default/files/downloads/Bookname_ ColorImages.pdf下载该文件。
尽管我们非常小心地确保图书内容的准确性,但是错误还是会发生。如果你在我们的任何一本图书中发现了错误——可能是文本错误,也可能是代码错误,并把它向我们报告,我们将非常感谢。通过这样做,你可以使其他读者免于阅读错误,并且帮助我们在本书的后续版本中更正。如果你想查找任何勘误表,请通过http://www.packtpub. com/submit-errata访问它们,选择你要找的图书,单击Errata Submission Form链接,就会进入本书的详细勘误表。一旦你的勘误表被校验,那么你的提交将会被接受,并且在我们网站上的勘误表将会被更新,或者添加到任何位于标题部分下的现有勘误表中。
进入https://www.packtpub.com/books/content/support,通过在搜索框输入图书名称,你都可以查看之前的勘误表。需要的信息会出现在Errata部分。
在互联网上,侵犯受版权保护资料的盗版行为,一直是一个持续的跨越全媒体的问题。在Packt,我们非常重视版权和许可。如果你在互联网上偶然发现以任何形式非法复制我们文字的地方,请立即提供给我们地址或者网站的名字,以便使我们能够追究补救办法。
请联系我们copyright@packtpub.com,并且附上涉嫌盗版的材料链接。
我们非常感谢你帮助保护我们的作者,并且我们有能力给读者带来有价值的内容。
如果有任何关于本书的问题,你可以联系我们questions@packtpub.com,我们将会尽量解决。
Nginx最初的设计,是成为一个HTTP服务器,一个能解决C10K问题的HTTP服务器。关于C10K这个问题,Daniel Kegel在http://www.kegel.com/c10k.html页面有具体描述,它旨在设计一个同时连接处理10000连接数的Web服务器。为了实现这个目标,Nginx通过基于事件的连接—处理机制,并且操作系统也要使用相应的事件机制,便可以解决C10K问题。
在我们开始探索如何配置Nginx之前,首先我们要安装它。这一章将详细讲述如何安装Nginx,以及如何获取正确的模块并安装与配置它们。Nginx是模块化设计的,并且有非常丰富的第三方模块开发者社区。它们的设计者通过创建这些模块为核心Nginx服务器增添了功能,我们可以在编译安装Nginx时将它们添加到Nginx服务器。
在这一章中,本书涉及如下内容。
使用包管理器安装Nginx的机会,是你所使用的操作系统己经提供了nginx的安装包。使用包管理器安装Nginx的方法很简单,只需要使用包管理器安装命令就可以了:
sudo apt-get install nginx
sudo yum install nginx
sudo pkg_install -r nginx
命令sudo表示的是通过操作系统中的超级用户(root)权限执行的命令。如果操作系统支持RBAC(role-based access control),那么可以用一个不同的命令,例如“pfexec”,来达到同样的目的。
通过上述命令,Nginx将会安装到操作系统的标准位置下。如果使用操作系统的安装包安装Nginx,那么通过上面的命令来安装是最佳方式。
Nginx核心团队也提供了稳定的二进制版本,可以从http://nginx.org/en/download.html页面下载可用的版本。未发布nginx安装包的系统用户(例如,CentOS),可以使用下面的指导来安装预测试、预编译二进制版本。
通过创建下面的文件,在系统中添加Nginx仓库的yum配置:
sudo vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
然后,通过执行如下命令来安装nginx:
sudo yum install nginx
也可以按照前面介绍的URL下载nginx发行版安装。
使用如下步骤在Debian上安装Nginx。
1.通过从http://nginx.org/keys/nginx_signing.key下载并安装Nginx签名key,将该签名key添加到系统的apt密钥中:
sudo apt-key add nginx_signing.key
2.将nginx.org仓库追加到/etc/apt/sources.list文件的末尾:
vi /etc/apt/sources.list
deb http://nginx.org/packages/debian/jessie nginx
deb-src http://nginx.org/packages/debian/jessie nginx
3.然后,通过执行如下命令来安装nginx:
sudo apt-get update
sudo apt-get install nginx
如果所使用的操作系统在它可用的安装包中未包含 nginx,或是所包含的版本太老不能满足需要,或是nginx.org并未提供所需要的安装包,或是你想使用“development”版本的Nginx,或者是你想启用或禁用特定的模块,那么从源代码编译的方法来安装Nginx是唯一可用的另外一个方法。
Nginx 代码提供了两种独立的下载分支——开发版与稳定版。开发分支是一个正处于积极开发状态的版本。在这个版本中,会有一些新功能被集成到其中,在稳定版中是找不到这些功能的。当发布一个“开发”版时,它会经历同样的QA和作为稳定版的一组类似功能测试。因此,无论哪一个分支都可以用于生产环境中。两者主要的不同,在于对第三方模块的支持。在开发版中,内部的API可能会发生改变,而稳定版则保持不变。因此,为了与第三方模块向下兼容,在稳定版中第三方模块都可以有效使用。
为了从源代码编译Nginx,系统需要满足某些必要条件。除了编译器之外,如果想分别启用SSL支持和使用rewrite模块,那么还需要提供相应的OpenSSL与PCRE(Perl Compatible Regular Expressions)库及开发头文件。rewrite模块是默认安装的。如果你没有PCRE库与开发头文件,你需要在配置阶段禁用rewrite模块。这依赖于系统,也有可能在系统中已经默认安装了这些必要条件。如果没有安装,则需要从其安装包安装或者从源码下载并解压安装,并在Nginx的配置脚本文件中指定它们在系统中的安装位置。
如果在配置文件中使用了--with-<library>=<path>选项,那么Nginx会试图建立一个静态依赖库。如果你想让Nginx不依赖于系统任何其他部分,或是想多获得些nginx的二进制额外性能,那么你可能会使用构建静态库的做法。如果你使用的外部库功能只能从某一个版本起有效(例如,NPN[Next Protocol Negotiation] TLS扩展从OpenSSL 1.0.1版有效),那么你就不得不将其指定到特定版本解压后的源代码路径中。
根据自己的喜好,你可能会提供其他的、可选安装包。你可以为这些安装包提供支持。它们包括MD5和SHA-1以支持散列算法、zip压缩库、libatomic库。在Nginx中,很多地方会用到散列算法,例如,为了计算URI散列进而计算缓存key。
zlib压缩库被用来投递gzip压缩内容。如果atomic_ops库有效,那么Nginx会用它来实现自动内存更新操作,以便实现高性能的内存锁定代码。
读者可以从http://nginx.org/en/download.html下载Nginx,在该页面找到.tar.gz或者.zip格式的源代码分支,按照如下步骤将下载的安装包解压到一个临时目录中:
$ mkdir $HOME/build
$ cd $HOME/build && tar xzf nginx-<version-number>.tar.gz
使用下面的命令配置Nginx:
$ cd $HOME/build/nginx-<version-number> && ./configure
然后,使用下面的命令进行编译安装:
$ make && sudo make install
在编译自己的二进制nginx时,你会有很大的灵活性来包含你仅使用的功能。你已经指定使用哪个用户运行Nginx了吗?你要使用默认的logfile位置,以便不用在Nginx的配置文件明确地说明它们吗?表1-1所示是配置选项列表,通过它来帮助你设计出自己的nginx命令。这些选项对Nginx都是有效的,模块可以被独立激活。
表1-1 通用配置选项
选项 |
解释 |
---|---|
|
|
|
指定 |
|
如果在命令行没有指定配置文件,那么将会通过这里指定的路径, |
|
指定错误文件的路径, |
|
指定的文件将会写入 |
|
共享存储器互斥锁文件的路径 |
|
|
|
|
|
为 |
|
这个选项用于启用调试日志。在生产环境的系统中不推荐使用该选项 |
如表 1-2 所示,你可以使用优化编译,但你可能无法在包管理器安装中获得优化。这正是表1-2中选项的用武之地。
表1-2 配置优化选项
选项 |
说明 |
---|---|
|
如果想设置一个不在默认 |
|
设置 |
|
指定必要的 |
|
包含连接器库的路径 |
|
通过该选项为特定的 |
Nginx是一个独一无二的高性能Web服务器,它也被设计成为一个邮件代理服务器。根据你构建Nginx的目标,可将其配置成一个Web加速器、Web服务器、邮件代理,或者是集三者为一体。你可以将任何服务安装在一个二进制文件中,这样做的好处是可以通过配置文件来设置Nginx服务器的角色,或者根据需要在高性能的环境中安装一个精简的二进制Nginx文件。
如表1-3所示,是邮件模块独有的配置选项。
表1-3 mail配置选项
选项 |
说明 |
---|---|
|
该选项用于启用 |
|
为了代理任何一种类型的使用 |
|
在启用 |
|
在启用 |
|
在启用 |
|
该选项将会完全禁用 |
对于典型的mail代理,我推荐将Nginx配置为:
$ ./configure --with-mail --with-mail_ssl_module --with-openssl=${BUILD_ DIR}/openssl-1.0.1p
对于邮件服务器来说,现在几乎每一个邮件服务器的安装都需要安装SSL/TLS,并且没有一个邮件代理启用了预期功能的劫持用户。我推荐静态编译OpenSSL,以便对操作系统中的OpenSSL库没有依赖性。不过,这确实意味着你必须保持警惕,确保你的静态编译的OpenSSL保持最新,并在必要时重建你的二进制文件。在前面命令中使用的变量BUILD_DIR需要提前设置。
表1-4显示了http模块有效的配置选项,从激活Perl模块到指定临时目录的位置。
表1-4 http配置选项
选项 |
说明 |
---|---|
|
在使用 |
|
|
|
对于额外嵌入的 |
|
如果在默认的路径中没有找到 |
|
|
|
从客户端收到请求后,该选项设置的目录用于作为请求体临时存放的目录。如果 |
|
在使用代理后,通过该选项设置存放临时文件路径 |
|
设置 |
|
设置 |
|
设置 |
对于TLS/SSL协议,Nginx使用OpenSSL项目。有关此开源工具包的更多信息,请访问https://www.openssl.org。你可以从操作系统或者直接从工具包的单独副本来获取对SSL的支持。如果使用不带--with-ssl
选项的--with-http_ssl_module
或者--with-mail_ssl_module
,你正在使用执行了configure命令的、安装在计算机上的OpenSSL库。如果你想要针对特定版本的OpenSSL进行编译,请下载该分发包,将其解压缩到一个目录中,然后将该目录的路径指定为--with-openssl的参数。使用--with-openssl-opt选项为OpenSSL本身指定额外的构建选项。
例如,为了使用具有优化椭圆曲线的OpenSSL来构建Nginx,您将使用如下的命令:
$ ./configure --with-http_ssl_module --with-openssl=${BUILD_DIR}/openssl- 1.0.1p --with-openssl-opt=enable-ec_nistp_64_gcc_128
在Nginx发布的版本中,除了http和mail模块之外,还有其他一些模块。这些模块并没有在默认安装中激活,但是可以在编译安装时适当地配置选项--with-<module-name>_module来启用相应的选项,如表1-5所示。
表1-5 http模块配置选项
选项 |
说明 |
---|---|
|
如果需要对流量进行加密,那么可以使用到这个选项,在 |
|
如果你的 |
|
这个模块作为一个输出过滤器,使你能够在请求经过一个 |
|
该模块用于处理 |
|
该模块被作为图像过滤器使用,在将图像投递到客户之前进行处理(需要 |
|
使用该模块,能够设置各种变量以便在配置文件中的区段使用,基于地理位置查找客户端 |
|
该模块实现了替代过滤,在响应中用一个字符串替代另一个字符串,提醒一句:使用该模块隐式禁用标头缓存 |
|
启用这个模块将激活使用 |
|
如果需要提供 |
|
这个模块支持 |
|
当被调用的资源没有 |
|
对于不支持 |
|
如果你想提供从一个目录中随机选择文件的索引文件,那么这个模块需要被激活 |
|
该模块提供了一种机制,它会将一个散列值链接到一个 |
|
启用这个模块后会收集 |
正如你所看到的,所有这些模块都是建立在http模块的基础之上,它们提供了额外的功能。在编译时启用这些模块根本不会影响到运行性能,以后在配置使用这些模块时性能会产生影响。
因此,对于网络加速器/代理,就配置选项来说,我想提出以下建议。
$ ./configure --with-http_ssl_module --with-http_realip_module --with- http_ geoip_module --with-http_stub_status_module --with-openssl=${BUILD_DIR}/ openssl-1.0.1p
下面是Web服务器的建议:
$ ./configure --with-http_stub_status_module
不同之处在于Nginx面对的客户,处于Web加速角色时,会考虑到SSL请求的终结,也包括处理代理客户和基于客户来源决策;处于Web服务角色时,则仅需要提供默认文件访问能力。
我总是推荐启用stub_status模块,这是因为它提供了收集Nginx如何执行、如何对其度量的一个方法。
有些http模块通常情况下是激活的,但是可以通过设置适当的--without-_module选项禁用它们。如果在配置中不使用这些模块,如表1-6所示,那么你可以禁用它们。
表1-6 禁用的配置选项
选项 |
说明 |
---|---|
|
该字符集模块负责设置 |
|
|
|
该模块是一个过滤器,用于处理 |
|
|
|
|
|
该模块通过 |
|
如果一个目录中没有 |
|
该模块能够让你基于客户端 |
|
|
|
该模块创建用于 |
|
该模块能够让 |
|
通过 |
|
使用 |
|
|
|
该模块能够让 |
|
|
|
该模块能够使得 |
|
该模块能够使得 |
|
通过该模块, |
|
在内存中空的 |
|
browser模块允许基于 |
|
该模块定义了一组可以与不同的代理模块结合使用的服务器 |
由于有多个开源项目,所以在Nginx周围就会有一个活跃的开发社区。由于Nginx的模块化特性,这个社区能够开发和发布模块,从而为Nginx提供额外的功能。它们涵盖了广泛的应用,所以着手开发自己的模块之前应该看看有什么可用模块。
安装第三方模块的过程相当简单,步骤如下。
1.定位你想要使用的模块(在https://github.com或者是http://wiki.nginx.org/3rdPartyModules查找)。
2.下载该模块。
3.解压缩源代码安装包。
4.如果有README文件,那么阅读README文件,查看在安装中是否有依赖安装。
5.通过./configure–add-module=<path>
选项配置使用该模块。
这个过程会给你的nginx二进制文件与模块附加这个功能。
需要注意的是,很多第三方模块是实验性质的。因此,在将这些模块用于生产系统之前,首先要测试使用这些模块。另外请记住,Nginx的开发版本中可能会有API的变化,会导致第三方模块出现问题。
特别应该提到的是ngx_lua这个第三方模块,ngx_lua模块提供了启用Lua的功能,而不是像Perl一样在配置时嵌入式脚本语言。该模块对于perl模块来说最大的优点就是它的无阻塞性,并与其他第三方模块紧密集成。对于它的安装说明的完整描述详见:https://github.com/ openresty/lua-nginx-module#installation。我们将以这个模块为例,在下一节中介绍如何安装第三方模块。
现在你已经大概了解了各种配置选项,接下来你可以根据自己的需要设计一个二进制文件。下面的例子中,指定了prefix、user、group,某些路径禁用了某些模块,启用了一些其他模块,并包括一些第三方模块。
$ export BUILD_DIR='pwd'
$ export NGINX_INSTALLDIR=/opt/nginx
$ export VAR_DIR=/home/www/tmp
$ export LUAJIT_LIB=/opt/luajit/lib
$ export LUAJIT_INC=/opt/luajit/include/luajit-2.0
$ ./configure \
--prefix=${NGINX_INSTALLDIR} \
--user=www \
--group=www \
--http-client-body-temp-path=${VAR_DIR}/client_body_temp \
--http-proxy-temp-path=${VAR_DIR}/proxy_temp \
--http-fastcgi-temp-path=${VAR_DIR}/fastcgi_temp \
--without-http_uwsgi_module \
--without-http_scgi_module \
--without-http_browser_module \
--with-openssl=${BUILD_DIR}/../openssl-1.0.1p \
--with-pcre=${BUILD_DIR}/../pcre-8.32 \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_sub_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--with-http_gunzip_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--add-module=${BUILD_DIR}/ngx_devel_kit-0.2.17 \
--add-module=${BUILD_DIR}/ngx_lua-0.7.9
接下来,跟随的大量输出显示了在你的系统上能找到什么样的配置,概要打印出来,配置如下所示。
Configuration summary
+ using PCRE library: /home/builder/build/pcre-8.32
+ using OpenSSL library: /home/builder/build/openssl-1.0.1p
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library
nginx path prefix: "/opt/nginx"
nginx binary file: "/opt/nginx/sbin/nginx"
nginx configuration prefix: "/ opt/nginx/conf"
nginx configuration file: "/opt/nginx/conf/nginx.conf"
nginx pid file: "/ opt/nginx/logs/nginx.pid"
nginx error log file: "/opt/nginx/logs/error.log"
nginx http access log file: "/opt/nginx/logs/access.log"
nginx http client request body temporary files: "/home/www/tmp/ client_ body_temp"
nginx http proxy temporary files: "/home/www/tmp/proxy_temp"
nginx http fastcgi temporary files: "/home/www/tmp/fastcgi_temp"
如上所示,configure找到了所有我们要查找的条目,并且按照我们的喜好设置了路径。现在,你可以构建你的nginx并安装它,正如本章一开始提到的。
本章介绍了各种Nginx的有效模块,通过编译你自己的二进制文件,你可以定制Nginx能够为你提供哪些功能。对于你来说,构建和安装软件应该不会陌生。所以,创造一个构建环境或者确保所有依赖关系都存在,这并不会花费你很多的时间。一个Nginx的安装应该是按照你的需要,能随时启用或禁用模块,正如你看到的,启用或者是禁用一个模块应该感到很容易。
接下来,我们将介绍基本的Nginx配置概述,以便感受一下在通常情况下Nginx是如何配置的。
Nginx 配置文件的格式非常合乎逻辑。学习这种格式以及如何使用每个部分是基础,这将有助于你手工创建一个配置文件。构造配置涉及为每个单独的段指定全局参数和指令。这些指令以及它们如何适应整个配置文件是本章的主要内容。目标是了解如何创建正确的配置文件以满足你的需求。
通过这一章的讨论话题,帮助你达到如下目标。
基本的Nginx配置文件由若干个部分组成,每一个部分都是通过下列方法定义的。
<section> {
<directive> <parameters>;
}
需要注意的是,每一个指令行都由分号结束(;),这标记着一行的结束。大括号({})实际上表示一个新配置的上下文(context),但是在大多数情况下,我们将它们作为“节、部分(section)”来读。
全局配置部分被用于配置对整个server都有效的参数和前一个章节中的例外格式。全局部分可能包含配置指令,例如,user和worker_processes,也包括“节、部分(section)”。例如,events,这里没有大括号({})包围全局部分。
在全局部分中,最重要的配置指令都在表 2-1 中,这些配置指令将会是你处理的最重要部分。
表2-1 全局配置指令
全局配置指令 |
说明 |
---|---|
|
使用这个参数来配置 |
|
指定 |
|
|
|
设置记录主进程 |
|
该指令用于指示使用什么样的连接方法。这个配置将会覆盖编译时的默认配置,如果配置该指令,那么需要一个 |
|
该指令配置一个工作进程能够接受并发连接的最大数。这个连接包括客户连接和向上游服务器的连接,但并不限于此。这对于反向代理服务器尤为重要,为了达到这个并发性连接数量,需要在操作系统层面进行一些额外调整 |
下面是一个使用这些指令的简短示例:
# we want nginx to run as user 'www'
user www;
# the load is CPU-bound and we have 12 cores
worker_processes 12;
# explicitly specifying the path to the mandatory error log
error_log /var/log/nginx/error.log;
# also explicitly specifying the path to the pid file
pid /var/run/nginx.pid;
# sets up a new configuration context for the 'events' module
events {
# we're on a Solaris-based system and have determined that
nginx
# will stop responding to new requests over time with the
default
# connection-processing mechanism, so we switch to the
second-best
use /dev/poll;
# the product of this number and the number of
worker_processes
# indicates how many simultaneous connections per IP:port pair
are
# accepted
worker_connections 2048;
}
这一部分应该放置在nginx.conf配置文件的顶部。
在Nginx的配置文件中,include文件可以在任何地方,以便增强配置文件的可读性,并且能够使得部分配置文件重新使用。使用include文件,要确保被包含的文件自身有正确的Nginx语法,即配置指令和块(blocks),然后指定这些文件的路径。
include /opt/local/etc/nginx/mime.types;
在路径中出现通配符,表示可以配置多个文件。
include /opt/local/etc/nginx/vhost/*.conf;
如果没有给定全路径,那么Nginx将会依据它的主配置文件路径进行搜索。Nginx测试配置文件很容易,通过下面的命令来完成。
nginx -t -c <path-to-nginx.conf>
该命令将测试Nginx的配置文件,包括include文件,但是它只检查语法错误。
在HTTP中,server部分或者HTTP配置context是可用的,除非在编译安装Nginx时没有包含HTTP模块(也就是使用了--without-http)。这部分控制了HTTP模块的方方面面,是使用最多的一个部分。
本部分的配置指令用于处理HTTP连接,因此,该模块提供了相当数量的指令。为了更容易理解这些指令,我们将它们划分为不同的类型来讲述。
如表2-2所示,这一组指令用于处理客户端连接本身的各个方面以及不同类型的客户端。
表2-2 http客户端指令
http客户端指令 |
说明 |
---|---|
|
在发送给客户端的响应中,该指令允许禁用 |
|
为了阻止临时文件写到磁盘,可以通过该指令为客户端请求体设置缓存大小,默认的缓存大小为两个内存页面 |
|
用于调试或者是进一步处理客户端请求体。该指令设置为“ |
|
为了减少复制的操作,使用该指令强制 |
|
该指令定义一个命令路径用于保存客户端请求体 |
|
该指令指定客户体成功读取的两个操作之间的时间间隔 |
|
该指令为客户端请求头指定一个缓存大小,当请求头大于 |
|
该超时是读取整个客户端头的时间长度 |
|
该指令定义允许最大的客户端请求头,如果大于这个设置,那么客户端将会是 |
|
该指令对某些类型的客户端禁用 |
|
该指令定义在一个 |
|
该指令指定 |
|
该指令定义最大数量和最大客户端请求头的大小 |
|
为了填充响应的大小至512字节,对于 |
|
对于 |
这些指令用于控制 Nginx如何投递静态文件以及如何管理文件描述符,如表 2-3所示。
表2-3 http文件I/O指令
http文件I/O指令 |
说明 |
---|---|
|
该指令启用异步文件 |
|
该指令用于启用操作系统特定的标志或者功能提供大于给定参数的文件。在 |
|
该指令设置 |
|
该指令配置一个缓存用于存储打开的文件描述符、目录查询和文件查询错误 |
|
该指令按照 |
|
|
|
该指令指定对 |
|
该指令指定 |
|
如果可能的话,内核将预读文件到设定的参数大小。目前支持 |
|
该指令使用 |
|
该指令设置在一个 |
如表2-4所示,这组hash指令控制Nginx分配给某些变量多大的静态内存。在启动和重新配置时,Nginx会计算需要的最小值。在Nginx发出警告时,只需要调整一个*_hash_max_size
指令的参数值就可以达到效果。*_hash_bucket_size
变量被设置了默认值,以便满足多处理器缓存行降低检索所需要的检索查找,因此基本不需要改变,额外更详细的内容参考http://nginx.org/en/docs/hash.html
。
表2-4 HTTP hash指令
HTTP hash指令 |
说明 |
---|---|
|
该指令指定用于保存 |
|
该指令指定 |
|
该指令指定用于存储散列表的“桶”的大小 |
|
该指令指定散列类型表的最大大小 |
|
该指令指定用于存储保留变量“桶”的大小 |
|
该指令指定存储保留变量最大散列值的大小 |
如表2-5所示,Socket指令描述了Nginx如何设置创建TCP套接字的变量选项。
表2-5 HTTP socket指令
HTTP socket指令 |
说明 |
---|---|
|
该指令指定如何保持客户端的连接,以便用于更多数据的传输 |
|
在使用 |
|
结合 |
|
使用这个指令之后,超时的连接将会被立即关闭,释放相关的内存。默认的状态是处于 |
|
如果非零, |
|
该指令在两次成功的客户端接收响应的写操作之间设置一个超时时间 |
|
启用或者禁用 |
|
仅依赖于 |
下面是一个http配置部分的例子。
http {
include /opt/local/etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server_names_hash_max_size 1024;
}
在nginx.conf文件中,上面这部分内容跟随在全局配置指令之后。
任何由关键字server开始的部分都被称作“虚拟服务器”部分。它描述的是一组根据不同的server_name指令逻辑分割的资源,这些虚拟服务器响应HTTP请求,因此它们都包含在http部分中。
一个虚拟服务器由listen和server_name指令组合定义,listen指令定义了一个IP地址/端口组合或者是UNIX域套接字路径。
listen address[:port];
listen port;
listen unix:path;
如表2-6所示,listen指令唯一地标识了在Nginx下的套接字绑定,此外还有一些其他的可选参数。
表2-6 Listen指令的参数
Listen指令的参数 |
说明 |
注解 |
---|---|---|
|
该参数定义这样一个组合: |
|
|
该参数为套接字监听设置相应的 |
该参数仅支持 |
|
该参数在 |
该参数在 |
|
在套接字监听中,该参数设置 |
|
|
在套接字监听中,该参数设置 |
|
|
该参数设置接受的过滤器: |
该参数仅支持 |
|
该参数使用延迟的 |
该参数仅支持 |
|
该参数为 |
如果任何其他特定套接字参数被使用,那么一个单独的 |
|
该参数设置 |
该参数只能在一个全新的开始设置,不支持 |
|
该参数表明该端口仅接受 |
该参数允许更紧凑的配置 |
|
该参数为 |
|
server_name指令是相当简单的,但可以用来解决一些配置问题。它的默认值为"",这意味着server部分没有server_name指令,对于没有设置Host头字段的请求,它将会匹配该server处理。这种情况可用于如丢弃这种缺乏Host头的请求。
server {
listen 80;
return 444;
}
在这个例子中,使用的HTTP非标准代码444将会使得Nginx立即关闭一个连接。
除了普通的字符串之外,Nginx也接受通配符作为server_name指令的参数。
通过在域名前面加上波浪号(~),正则表达式也可以被作为参数应用于server_name。
server_name ~^www\.example\.com$;
server_name ~^www(\d+).example\.(com)$;
后一种形式是利用捕获,可以在以后引用中进一步配置(用$1、$2等)指令中使用。
对于一个特定的请求,确定哪些虚拟服务器提供该请求的服务时,Nginx应该遵循下面的逻辑。
1.匹配IP地址和listen指令指定的端口。
2.将Host头字段作为一个字符串匹配server_name指令。
3.将Host头字段与server_name指令值字符串的开始部分做匹配。
4.将Host头字段与server_name指令值字符串的结尾部分做匹配。
5.将Host头字段与server_name指令值进行正则表达式匹配。
6.如果所有Host头匹配失败,那么将会转向listen指令标记的default_server。
7.如果所有的Host头匹配失败,并且没有default_server,那么将会转向第一个server的listen指令,以满足第1步。
这个逻辑体现在图2-1中。
图2-1 Host头匹配流程图
参数default_server被用于处理其他没有被处理的请求。因此,总是明确地推荐设置default_server,以便这些没有被处理的请求通过这种定义的方式处理。
除了这个用法外,default_server也可以使用同样的listen指令配置若干个虚拟服务器。这里设置的任何指令都将会在匹配的server区段有效。
location指令可以用在虚拟服务器server部分,并且意味着提供来自客户端的URI或者内部重定向访问。除少数情况外,location也可以被嵌套使用,它们被作为特定的配置尽可能地处理请求。
location定义如下。
location [modifier] uri {...}
或者是命名location。
location @name {…}
命名location仅对内部访问重定向,在进入一个location之前,它会保留被请求的URI部分。命名location只能够在server级别定义。
表2-7中的修饰符会影响location的处理。
表2-7 location修饰符
location修饰符 |
处理方式 |
---|---|
= |
该修饰符使用精确匹配并且终止搜索 |
~ |
该修饰符使用区分大小写的正则表达式匹配 |
~* |
该修饰符使用不区分大小写的正则表达式匹配 |
^~ |
如果该 |
当一个请求进入时,URI将会被检测匹配一个最佳的location。
这里比较匹配描述的是解码URI,例如,在URI中的 "%20",将会匹配location中的 " "(空格)。
命名location仅可以在内部重定向的请求中使用。表2-8中的指令仅在location中使用。
表2-8 仅用于location的指令
仅用于location的指令 |
说明 |
---|---|
|
该指令定义 |
|
该指令指定一个仅用于内部请求的 |
|
该指令限定一个 |
另外,http部分的其他指令也可以在location中指定,附录A指令参考有完整列表。
指令try_files在这里也值得一提,它也可以用在server部分,但是最常见的还是在location部分中。try_files指令将会按照给定它的参数列出顺序进行尝试,第一个被匹配的将会被使用。它经常被用于从一个变量去匹配一个可能的文件,然后将处理传递到一个命名location,如下面的示例所示。
location / {
try_files $uri $uri/ @mongrel;
}
location @mongrel {
proxy_pass http://appserver;
}
在这里有一个隐含的目录索引,如果给定的URI作为一个文件没有被找到,那么处理将会通过代理被传递到appserver。我们将会在本书的其他部分讨论如何最好地使用location、try_files和proxy_pass来解决特定的问题。
除以下前缀外,locations可以被嵌套。
最佳实践表明正则表达式location被嵌套在基于字符串的location内,如下面的示例所示。
# first, we enter through the root
location / {
# then we find a most-specific substring
# note that this is not a regular expression
location ^~ /css {
# here is the regular expression that then gets matched
location ~* /css/.*\.css$ {
}
}
}
下面是一个示例配置文件,它包括了本章讨论的各个不同方面。请注意,不要复制粘贴该示例配置文件。因为它很可能不是你需要的配置,该代码只是显示了一个完整配置文件的架构而已。
user www;
worker_processes 12;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
use /dev/poll;
worker_connections 2048;
}
http {
include /opt/local/etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
server_names_hash_max_size 1024;
server {
listen 80;
return 444;
}
server {
listen 80;
server_name www.example.com;
location / {
try_files $uri $uri/ @mongrel;
}
location @mongrel {
proxy_pass http://127.0.0.1:8080;
}
}
}
在本章,我们看到了如何构建Nginx的配置文件。模块化的本质值得思考,从某种意义上讲,Nginx本身也是模块化的。全局的配置区段负责各个方面,对于Nginx来说是一个整体。Nginx负责处理的每一种协议单独成为一个部分。我们还可以通过在这些协议配置内(http或者mail)指定server来定义每一个请求如何被处理,以便请求被路由到特定的IP地址和端口上。在http区段中,使用locations来匹配URI请求,这些locations可以被嵌套使用,或者按其他顺序使用,以确保请求被路由到正确的文件系统区域或者应用程序服务器。
本章没有涵盖编译到二进制nginx命令中各种模块提供的配置选项,这些额外的指令将会遍及本书的始终,因此特定的模块被用于解决一个问题。对于Nginx配置中的变量也没有解释,这些变量也将会在本书后边的内容中讨论。本章的焦点是基于Nginx的基本配置。
在下一章中,我们探讨配置Nginx的mail模块以启用电子邮件代理。