配置运行Nginx服务器用户(组)
用于配置运行Nginx服务器用户(组)的指令是user,其语法格式为:
user user [group];
- user,指定可以运行Nginx服务器的用户。
- group,可选项,指定可以运行Nginx服务器的用户组。
只有被设置的用户或者用户组成员才有权限启动Nginx进程,如果是其他用户(test_user)尝试启用Nginx进程,将会报错:
nginx: [emerg] getpwnam("test_user") failed (2:No such file or directory) in /Nginx/conf/nginx.conf:2
可以从错误信息中看到,Nginx无法运行的原因是查找test_user失败,引起错误的原因是nginx.conf的第二行内容,即配置Nginx服务器用户(组)的内容。
如果希望所有用户都可以启动Nginx进程,有两种办法:一是将此指令行注释掉:
#user [user] [group];
或者将用户(和用户组)设置为nobody:
user nobody nobody;
这也是user指令的默认配置。user指令只能在全局块中配置。
在Nginx配置文件中,每一条指令配置都必须以分号结束。
配置允许生成的worker process数
worker process是Nginx服务器实现病发处理的关键所在。从理论上来说,worker process的值越大,可以支持的支持的并发处理量也越多,但实际上它还要受到来自软件本身、操作系统本身资源和能力、硬件设备(如CPU和磁盘驱动器)等的制约。配置允许生成的worker process数的指令是worker_processes,其语法格式为:
worker_processes number | auto;
- number,指定Nginx进程最多可以产生的worker process数。
- auto,设置此值,nginx进程讲自动检测。
在默认的配置文件中,number = 1。启动Nginx服务器之后,使用一下命令可以看到Nginx服务器除了主进程master process ../sbin/nginx之外,还生成了一个worker process:
Jorys-MBP:~ jory$ ps ax | grep nginx
11743 ?? Ss 0:00.00 nginx: master process nginx
11744 ?? S 0:00.00 nginx: worker process
11747 s000 S+ 0:00.00 grep nginx
如果将number改为3,重新运行Nginx进程,再次使用以上命令,则可以看到此时的Nginx服务器除了主进程master process ../sbin/nginx之外,已经生成了3个worker process:
Jorys-MBP:nginx jory$ ps ax | grep nginx
11796 ?? Ss 0:00.00 nginx: master process nginx
11797 ?? S 0:00.00 nginx: worker process
11798 ?? S 0:00.00 nginx: worker process
11799 ?? S 0:00.00 nginx: worker process
11811 s000 S+ 0:00.00 grep nginx
此指令只能在全局块中设置。
配置Nginx进程PID存放路径
Nginx进程作为系统的守护进程运行,我们需要在某文件中保存当前运行程序的主进程号。Nginx支持对它的存放路径进行自定义配置,指令是pid,其语法格式为:
pid file;
其中,file指定存放路径和文件名称。
配置文件默认将此文件存放在Nginx安装目录logs下,名字为nginx.pid。path可以是绝对路径,也可以是以Nginx安装目录为根目录的相对路径。比如要把nginx.pid放置到Nginx安装目录sbin下,文件名为web_nginx,则可以使用一下配置:
pid sbin/web_nginx
注意
在指定[path]的时候,一定要包括文件名,如果只设置了路径,没有设置文件名,则会报一下错误:
nginx: [emerg] open() "/Nginx/logs/" failed (21: Is a directory)
此指令只能在全局块中进行配置。
配置错误日志的存放路径
在全局块、http块和server块中都可以对Nginx服务器的日志进行相关配置。全局块下日志的存放配置使用的指令是error_log,其语法结构是:
error_log file | stderr [debug | info | notice | warn | error | crit | alert | emerg];
Nginx服务器的日志支持输出到某一固定的文件file或者输出到标准错误输出stderr,日志的级别是可选项,由低到高分为debug(需要在编译时使用--with-debug开启debug开关)、info、notice、warn、error、crit、alert、emerg等。需要注意的是,设置某一级别后,比这一级别高的日志也会被记录。比如设置warn级别后,级别为warn以及error、crit、alert和emerg的日志都会被记录下来。
如下面Nginx默认的日志存放和级别设置:
error_log logs/error.log error;
注意
指定的文件对于运行Nginx进程的用户具有写权限,否则在启动Nginx进程的时候回出现以下报错信息:
nginx: [alter]: could not open error log file: open() "/Nginx/logs/error.log" failed
(13: Permission denied)
此指令可以在全局块、http块、server块以及location块中配置。
配置文件的引入
在一些情况下,我们能需要将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中。 Nginx提供了include指令来完成配置文件的引入,其语法格式为:
include file;
其中,file是要引入的配置文件,它支持相对路径。
注意
新引用进来的文件同样要求运行Nginx进程的用户对其具有写权限,并且符合Nginx配置文件规定的相关语法和结构。
此指令可以放在配置文件的任意地方。
设置网络连接的序列化
在《UNIX网络编程》第1卷里提到过一个叫“惊群”的问题(Thundering herd problem),大致意思是,当某一时刻只有一个网络连接到来时,多个睡眠进程会被同时叫醒,但只有一个进程可获得连接。如果每次唤醒的进程数目太多,会影响一部分系统性能。在Nginx服务器的多进程下,就有可能出现这样的问题。
为了解决这样的问题,Nginx配置中包含了这样一条指令accept_mutex,当其设置为开启的时候,将会对多个Nginx进程接收连接进行序列化,防止多个进程对连接的争抢。其语法结构为:
accept_mutex on | off;
此指令默认为开启(on)状态,其只能在events块中进行配置。
设置是否允许同时接收多个网络连接
每个Nginx服务器的worker process都有能力同时接收多个新到达的网络连接,但是这需要在配置文件中进行设置,其指令为multi_accept,语法结构为:
multi_accept on | off
此指令默认为关闭(off)状态,即每个worker process一次只能接收一个新到达的网络连接。此指令只能在events块中进行配置。
事件驱动模型的选择
Nginx服务器提供了多种事件驱动模型来处理网络消息。配置文件中为我们提供了相关的指令来强制Nginx服务器选择哪种事件驱动模型进行消息处理,指令为use,语法结构为:
use method;
其中,method可选择的内容有:select、poll、kqueue、epoll、rtsig、/dev/poll以及eventport,其中几种模型是比较常用的。
注意
可以在编译时使用--with-select_module和--without-select_module设置是否强制编译select模块到Nginx内核。使用--with-poll_module和--without-poll_module设置是否强制编译poll模块到Nginx内核。
此指令只能在event块中进行配置。
配置最大连接数
指令worker_connections主要用来设置允许每一个worker process同时开启的最大连接数。其语法结构为:
worker_connections number;
此指令的默认设置为512。
注意
这里的number不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number值不能大于操作系统支持的文件最大句柄数量。该指令在后边讨论Nginx服务器高级配置时还会再次提到。
此指令只能在events块中进行配置。
定义MIME-Type
我们知道,在常用的浏览器中,可以显示的内容是HMTL、XML、GIF及Flash等种类繁多的文本、媒体等资源,浏览器为区分这些资源,需要使用MIME Type。换言之,MIME Type是网络资源的媒体类型。Nginx服务器作为Web服务器,必须能够识别前端请求的资源类型。
在默认的Nginx配置文件中,我们看到在http全局块中有一下两行配置:
include mime.types;
default_type appliaction/octet-stream;
第一行从外部引用了mime_types文件,它的内容:
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
image/webp webp;
application/font-woff woff;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
从mime_types文件的内容片段可以看到,其中定义了一个types结构,结构中包含了浏览器能够识别的MIME类型以及对应于相关类型的文件后缀名。由于mime_types文件是主配置文件应用的第三方文件,因此,types也是Nginx配置文件中的一个配置块,我们可以称之为types块,其用于定义MIME类型。
第二行中使用指令default_type配置了用了处理前端请求的MIME类型,其语法结构为:
default_type mime-type;
其中,mime-type为types块中定义的MIME-type,如果不加此指令,默认值为text/plain。此指令还可以在http块、server块或者location块中进行配置。
自定义服务日志
在全局块中,我们介绍过error_log指令,其用于配置Nginx进程运行时的日志存放和级别,此处所指的日志与常规的不同,它是指记录Nginx服务器提供服务应答前端请求的日志,我们将其称为服务日志以示区分。
Nginx服务器支持对服务日志的格式、大小、输出等进行配置,需要使用两个指令,分别是access_log和log_format指令。
access_log指令的语法结构为:
access_log path [ format [buffer=size]];
- path,配置服务日志的文件存放的路径和名称。
- format,可选项,自定义服务日志的格式字符串,也可以通过“格式串的名称”使用log_format指令定义好的格式。“格式串的名称”在log_format指令中定义。
- size,配置临时存放日志的内存缓存区大小。
此指令可以在http块、server块或者location块中进行设置。默认的配置为:
access_log logs/access.log combined;
其中combined为log_format指令默认定义的日志格式字符串的名称。
如果要取消记录服务日志的功能,则使用:
access_log off;
和access_log联合使用的另一个指令是log_format,它专门用于定义服务日志的格式,并且可以为格式字符串定一个名字,以便access_log指令可以直接调用。其语法格式为:
log_format name string ...;
- name,格式字符串的名字,默认的名字为combined。
- string,服务日志的格式字符串。在定义的过程中,可以使用Nginx配置预设的一些变量获取相关的内容,变量的名称使用双括号括起来,string整体使用单引号括起来。如下例:
log_format exampleLog '$remote_addr - [$time_local] $request ' '$status $body_bytes_sent $http_referer ' '$http_user_agent';
这条配置定义了服务日志文件的名称为exampleLog。访问的日志内容如下:
127.0.0.1 - [12/Jun/2017:23:50:17 +0800] "GET /orm3 HTTP/1.1" 200 11 " " "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
该条日志的分析如下,$remote_addr获取到用户的IP地址为127.0.0.1,$time_local获取到本地时间为12/Jun/2017:23:50:17 +0800,$requst获取到的请求为GET /orm3 HTTP/1.1,$status获取到请求状态为200,$body_bytes_send获取到的请求体的大小为11B,$http_referer未获取到任何内容,$http_user_agent获取到用户使用Chrome浏览器。
在正常情况下,对于绝大多数的内置变量,Nginx服务器都能获取到相关内容,但也会出现控制的情况。
此指令只能在http块中进行配置。
配置允许sendfile方式传输文件
sendfile的语法结构:
sendfile on | off
sendfile用于开启或者关闭使用sendfile()传输文件,默认值为off,可以在http块,server块或者location块中进行配置。
sendfile_max_chunk的语法结构:
sendfile_max_chunk size;
其中,size值如果大于0,Nginx进程的每个worker process每次调用sendfile()传输的数据量最大不能超过这个值。如果设置为0,则无限制。默认为0。此指令可以再http块、server块或location块中配置。
配置示例:
sendfile_max_chunk 128k
配置连接超时时间
与用户建立会话连接后,Nginx服务器可以保持这些连接打开一段时间,指令keepalive_timeout就是设置此事件,其语法结构是:
keepalive_timeout timeout [header_timeout];
- timeout,服务器端对连接的保持时间。默认值为75s。
- header_timeout,可选项,在应答报文头部的Keep-Alive域设置超时时间:“Keep-Alive:timeout=header_timeout”。报文中的这个指令可以被Mozilla或者Konqueror识别。
此指令还可以出现在server块和location块中,如下是一个配置示例:
keepalive_timeout 120s 100s;
其含义是,在服务器端保持连接的时间设置为120s,发给用户端的应答报文头部中Keep-Alive域的超时时间设置为100s。
此指令可以在http块、server块或location块中配置。
单连接请求数上限
Nginx服务器端和用户端建立会话连接后,用户端通过此连接放请求。指令keepalive_requests用于限制用户通过某一连接向Nginx服务器发送请求的次数。其语法结构为:
keepalive_requests number;
此指令还可以出现在server块和location块中,默认设置为100.
配置网络监听
配置网络监听使用指令listen,其配置方法主要有三种。
- 第一种配置监听的IP地址,语法结构为:
listen address[:port] [default_server] [setfib=number] [backlog=number] [rcvbuf=size]
[sndbuf=size] [deferred] [accept_filter=filter] [bind] [ssl];
- 第二种配置监听端口,其语法结构是:
listen port[defalut_server] [setfib=number] [backlog=number] [rcvbuf=size]
[sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on | off ] | [ssl];
- 第三种配置UNIX Domain Socket(一种在原有Socket框架上发展起来的IPC机制,用于在单个主机上执行客户/服务器通信),其语法结构是:
listen unix:path [default_server] [baclog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ssl]
- address,IP地址,如果是IPv6的地址,需要使用中括号“[]”括起来,比如[fe80::1]等。
- port,端口号,如果只定义了IP地址没有定义端口号,就是用80端口。
- path,socket文件路径,如/var/run/nginx.sock等。
- default_server,标识符,将此虚拟机设置为address:port的默认主机。
注意 在Nginx-0.8.21之前的版本,使用的是default。
- setfib=number,Nginx-0.8.44中使用这个变量为监听socket关联路由表,目前只对FreeBSD起作用,不常用。
- backlog=number,设置监听函数listen()最多允许多少网络连接同时处于挂起状态,在FreeBSD中默认为-1,其他平台默认为511.
- rcvbuf=size,设置监听socket接收缓存区大小。
- sndbuf=size,设置监听socket发送缓存区大小。
- deferred,标识符,将accept()设置为Deferred模式。
- accept_flter=filter,设置监听端口对请求的过滤,被过滤的内容不能被接收和处理。本指令只在FreeBSD和NetBSD 5.0+平台下有效。filter可以设置为dataready或httpready。
- bind,标识符,使用独立的bind()处理此address:port。一般情况下,对于端口相同而IP地址不同的多个连接,Nginx服务器将只使用一个监听命令,并使用bind()处理端口相同的所有连接。
- ssl,标识符,设置会话连接使用SSL模式进行,此标识符和Nginx服务器提供的HTTPS服务有关。
listen指令的使用看起来比较复杂,但其实在一般的使用过程中,相对来说比较简单,默认的设置为:
listen *:80 | *:8080;
即监听所有80端口和8000端口。下面为用法示例:
listen 192.168.1.10:8000; #监听具体的IP和具体的端口上的连接
listen 192.168.1.10;#监听具体IP的所有端口上的连接
listen 8000; #监听具体端口上所有IP连接,等同于listen *:8000
listen 192.168.1.10 default_server backlog=1024; #设置192.168.1.10的连接请求默认由此虚拟主机处理,并且允许最多1024网络连接同时处于挂起状态。
基于名称的虚拟主机配置
这里的“主机”,就是指此server块对外提供的虚拟主机。设置了主机的名称并配置好DNS,用户就可以使用这个名称向此虚拟主机发送请求了。配置主机名称的指令为server_name,起语法结构为:
server_name name ...;
对于name来说,可以只有一个名称,也可以由多个名称并列,之间用空格隔开。每个名字就是一个域名,由两段或者三段组成,之间由点号“.”隔开。如下例:
server_name myserver.com www.myserver.com
在该例中,此虚拟机的名称设置为myserver.com或www.myserver.com。Nginx服务器规定,第一个名称作为此虚拟主机的主要名称。
在name中可以使用通配符“*”,但通配符只能用在由三段字符串组成的名称的首段或尾段,或者由连贯字符串组成的名称的尾段,如:
server_name *.myserver.com www.myserver.*
在name中还可以使用正则表达式,并使用波浪号“~”作为正则表达式字符串的开始标记,如:
server_name ~^www\d+\.myserver\.com$
在该例中,此虚拟主机的名称设置使用了正则表达式(使用“”标记),正则表达式的含义是:以www开头(使用“^”标记),紧跟一个或多个09的数字,(“\d+”的含义,其中“\d”代表0~9的某一个数字,“+”代表之前的一个字符出现一次或者多次),在紧跟.myserver.co(由于“.”在正则表达式中有特殊含义,因此需要使用“\”进行转义),最后以m结束(由“$”标记)。
上例的配置中,通过www1.myserver.com访问Nginx服务器的请求就可以使用此主机处理,而通过www.myserver.com的就不可以。因为“www”字符串之后必须有一个或者多个0~9的数字才能被正则表达式成功匹配。
注意
从Nginx-0.7.40开始,name中的正则表达式支持字符串捕获功能,即可以将正则表达式匹配成功的名称中的一部分字符串拾取出来,放在固定变量中供下文使用。拾取的标识为一对完整的小括号“()”且后面不紧跟其他的正则表达式字符,括号中的内容就是被拾取的内容。一个正则表达式中可以存在多对捕潜逃的小括号,这些内容会从左到右依次存放在变量$1、$2、$3......中。下文使用时,直接使用这些变量即可。这些变量的有效区域不超过本server块。
如下例,虚拟主机的名称设置如下:
server_name ~^www\.(.+)\.com$
当请求通过www.myserver.com到达Nginx服务器端时,其将会被上面的正则表达式匹配成功,其中的“myserver”将会被捕获,并记录到$1中。在本server块的下文配置中,当需要“myserver”时,就可以使用$1代替“myserver”了。
由于server_name指令支持使用通配符和正则表达式两种配置名称的方式,因此在包含有多个虚拟主机的配置文件中,可能回出现一个名称被多个虚拟主机的server_name匹配成功。那么,来自这个名称的请求到底要交给哪个虚拟主机处理呢?Nginx服务器做出如下规定:
- 1.对于匹配方式不同的,按照以下的优先级选择虚拟主机,排在前面的优先级处理请求。
- 精准匹配server_name
- 通配符在开始时匹配server_name成功
- 通配符在结尾时匹配server_name成功
- 正则表达式匹配server_name成功
- 2.在以上四种配置方式中,如果server_name被处于同一优先级的匹配方式多次匹配成功,则首次匹配成功的虚拟主机处理请求。
配置location块
在Nginx的官方文档中定义的location的语法结构为:
location [ = | ~ | ~* | ^~ ] uri { ... }
其中,uri变量是待匹配的请求字符串,可以是不含正则表达的字符串,如/myserver.php等。也可以是包含有正则表达的字符串,如果.php$(表示以.php结尾的URL)等。
不含正则表达式的uri -> 标准uri
使用整则表达式的uri -> 正则uri
其中方括号里的部分,是可选项,用来改变请求字符串与uri的匹配方式。在介绍四种标识的含义之前,需要先了解不添加此选项时,Nginx服务器是如何在server块中搜索并使用location块和uri和请求字符串匹配的。
在不添加此选项时,Nginx服务器首先在server块的多个location块中搜索是否有标准uri和请求字符串匹配,如果有多个可以匹配,就记录匹配度最高的一个。然后,服务器再用location块中的正则uri和请求字符串匹配,当第一正则uri匹配成功,结束搜索,并使用这个location块处理此请求。如果正则匹配全部失败,就使用刚才记录的匹配度最高的location块处理此请求。如果正则匹配全部失败,就使用刚才记录的匹配度最高的location块处理此请求。
- “=”,用于标准uri前,要求请求字符串与uri严格匹配。如果匹配成功,就停止继续向下搜索并立即处理此请求。
- “~”,用于表示uri包含正则表达式,并且区分大小写。
- “~*”,用于表示uri包含正则表达式,并且不区分大小写。
注意
如果uri包含正则表达式,就必须要使用“”或者“*”标识。
- “^~”,用于标准uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配。
注意
我们知道,在浏览器传送URI时对一部分字符进行URL编码,比如空格被编码为“%20”,问号被编码为“%3f”等。“^”有一个特点是,他对uri中的这些符号将会进行编码处理。比如,如果location块收到的URI为“/html/%20/data”,则当Nginx服务器搜索到配置为“ /html/ /data”的location时,可以匹配成功。
配置请求的根目录
Web服务器接收到网络请求之后,首先要在服务器端指定目录中寻找请求资源。在Nginx服务器中,指令root就是用来配置这个根目录的,其语法结构为:
root path;
其中,path为Nginx服务器接收到请求以后查找资源的根目录路径。path变量中可以包含Nginx服务器预设的大多数变量,只有$document_root和$realpath_root不可以使用。
此指令还可以再http块,server块或者location块中配置。由于使用Nginx服务器多数情况下要配置多个location块对于不同的请求分别作出处理,因此该指令通常在location块中进行设置。
这个指令的一个示例为:
location /data/
{
root /locationtest1;
}
当location块接收到“/data/index.htm”的请求时,将在/locationtest1/data/目录下找到Index.htm响应请求。
更改location的URI
在location块中,除了使用root指名请求处理根目录,还可以使用alias指令改变location接收到的URI的请求路径,其语法结构为:
alias path;
其中,path即为修改后的根路径。同样,此变量中也可以包含除了$document_root和$realpath_root之外的其他Nginx服务器预设变量。
示例如下:
location ~ ^/data/(.+\.(htm|htm))$
{
alias /locationtest1/other/$1;
}
当此location块接收到“/data/index.htm”的请求时,匹配成功,之后根据alias指令的配置,Nginx服务器找到/locationtest1/other目录下找到index.htm并响应请求。可以看到,通过alias指令的配置,根路径已经从/data更改为/locationtest1/other了。
设置网站的默认首页
指令index用于设置网站的默认首页,它一般可以有两个作用:一是,用户在发出请求访问网站时,请求地址可以不写首页名称。二是,可以对一个请求,根据其请求内容而设置不同的首页。该指令的语法结构为:
index file ...;
其中,file变量可以包括多个文件名,其间使用空格分隔,也可以包含其他变量。此变量默认为“index.html”。
看一个示例:
location ~ ^/data/(.+)/web/ $
{
index index.$1.html index.my1.html index.html;
}
当location块接收到“/data/locationtest/web/”时,匹配成功,它首先将预置变量$1置为“locationtest”,然后在/data/locationtest/web/路径下按照index的配置次序依次寻找index.lcoationtest.html页、index.my1.html页和index.html页,首先找到哪个页面,就是用哪个页面响应请求。
设置网站的错误页面
如果用户端尝试查看网页时遇到问题,服务器会将HTTP错误从网站发送到Web浏览器。如果无法显示网页,Web浏览器会显示网站发送的实际错误网页或Web浏览器内置的友好错误信息。Nginx服务器支持自定义错误网页的显示内容。可以通过这一功能在网站发生错误时为用户提供人性化的错误显示页面。
一般来说,HTTP 2XX代表请求正常完成,HTTP 3XX代表网站重定向,HTTP 4XX代表客户端出现错误,HTTP 5XX代表服务器端出现错误。
常见的错误如下表所示:
HTTP 消息 | 代码 | 含义 |
---|---|---|
已移动 | HTTP301 | 请求的数据具有新的位置,并且更改是永久的 |
已找到 | HTTP302 | 请求的数据临时具有不同的URI |
请参阅其他 | HTTP303 | 可在另一URI下找到请求的响应,并且应使用GET方法检索此响应 |
未修改 | HTTP304 | 未按照预期修改文档 |
使用代理 | HTTP305 | 必须通过位置字段中提供的代理来访问请求的资源 |
未使用 | HTTP306 | 不再使用,但保留此代码以便将来使用 |
无法找到网页 | HTTP400 | 可以连接到Web服务器,但是由于Web地址(URL)的问题,无法找到网页 |
网站拒绝显示此网页 | HTTP403 | 可以连接网站的,但Internet Explore没有显示网页的权限 |
无法找到网页 | HTTP404 | 可以连接到网站,但找不到网页。导致此错误的原因有时可能是网页暂时不可用或网页已被删除 |
网站无法显示该网页 | HTTP405 | 可以连接到网站,但网页内容无法下载到用户的计算机,这通常是由网页的编写方式问题引起的 |
无法读取此网页格式 | HTTP406 | 能够从网站接受信息,但是Internet Explore不能识别其格式,因而无法正确地显示消息。 |
该网站太忙,无法显示此网页 | HTTP408或409 | 服务器显示该网页的时间太长,或对同一网页的请求太多 |
网页不复存在 | HTTP410 | 可以连接到网站,但无法找到网页。与HTTP错误404不同,此错误是永久的,而且由网站管理员打开 |
网页无法显示该页面 | HTTP500 | 正在访问的网站出现了服务器问题,该问题阻止了此网页的显示。常见的原因是网站正在维护或使用脚本的交互网站上的程序出错 |
未执行 | HTTP501 | 没有将正在访问的网站设置为显示浏览器所请求的内容 |
不支持的版本 | HTTP505 | 该网站不支持浏览器用于请求网页的HTTP协议(最为常见的是HTTP/1.1) |
Nginx服务器设置网站错误页面的指令为error_page,语法结构为:
error_page code ... [=[response]] uri
- code,要处理的HTTP错误代码,常见的在上面表里面已经列出。
- response,可选项,将code制定的错误代码转化为新的错误代码response。
- uri,错误页面的路径或者网站地址。如果设置为路径,则是以Nginx服务器安装路径下的html目录为根路径的相对路径。如果设置为网址,则Nginx服务器会直接访问该网址获取错误页面,并返回给用户端。
几个示例如下:
error_page 404 /404.html;
设置Nginx服务器使用“Nginx安装路径/html/404.html”页面响应404错误(“无法找到网页”错误)。
error_page 403 http://somewebsite.com/forbidden.html;
设置Nginx服务器使用“http://somewebsite.com/forbidden.html”页面响应403错误(“拒绝显示网页”错误)。
error_page 401 =301 /empty.gif;
设置Nginx服务器产生410的HTTP消息时,使用“Nginx安装路径/html/empty.gif”返回给用户端301消息(“已移动”消息)
在前面对error_page指令的分析中可以看出,变量uri实际上是一个相对于Nginx服务器安装路径的相对路径。那么如果不想让错误页面放到Nginx服务器的安装路径下管理,该怎么做呢?
其实很简单,只需要使用另外一个location指令定向错误页面到新的路径下面就可以了。比如对于上面的第一个示例,我们希望Nginx服务器使用“/myserver/errorpages/404.html”页面响应404错误,那么在设置完:
error_page 404 /404.html
之后我们在添加这样一个location块:
location /404.html
{
root /myserver/errorpages/
}
首先捕获“/404.html”请求,然后将请求定向到新的路径下面即可。
error_page指令可以在http块、server块和location块中配置。
基于IP配置的Nginx的访问权限
Nginx配置通过两种途径支持基本访问权限的控制,其中一种是由HTTP标准模块ngx_http_access_module支持的,其通过IP来判断客户端是否拥有对Nginx的访问权限,这里由两个指令需要我们学习。
allow指令,用于设置允许访问Nginx的客户端IP,语法结构为:
allow address | CIDR | all;
- address,允许访问的客户端的IP,不支持同时设置多个。如果有多个IP需要设置,需要重复使用allow指令。
- CIDR,允许访问的客户端的CIDR地址,例如202.80.18.23/25,前面是32位IP地址,后面“/25”代表该IP地址中前25位是网络部分,其余位代表主机部分。
- all,代表允许所有客户端访问。
从Nginx 0.8.22版本之后,该命令也支持IPv6地址,比如:
allow 2620:100:e000:8001;
另一个指令是deny,作用刚好和allow指令指令相反,它用于设置禁止访问Nginx客户端IP,语法结构为:
deny address | CIDR | all;
- address,禁止访问的客户端的IP,不支持同时设置多个。如果有多个IP需要设置,需要重复使用deny指令。
- CIDR,禁止访问的客户端的CIDR地址。
- all,代表禁止所有客户端访问。
这两个指令可以在http块、server块或者location块中配置。在使用这两个指令时,要注意设置all的用法。请看下面的例子:
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
deny all;
}
在上面的配置示例中我们首先配置禁止192.168.1.1访问Nginx,然后配置允许192.168.1.0/24访问Nginx,最后又使用all配置禁止所有IP的访问。那么,192.168.1.0/24客户端到底可不可以访问呢?是可以的。Nginx配置在解析的过程中,遇到deny指令或者allow指令是按照顺序对当前客户端的连接进行访问权限检查的。如果遇到匹配的配置时,则停止继续向下搜索相关配置。因此,当192.168.1.0/24客户端访问时,Nginx在第3行解析配置发现允许该客户端访问,就不会继续向下解析第4行了。
基于密码配置Nginx的访问权限
Nginx还支持基于HTTP Basic Authentication协议的认证。该协议是一种HTTP性质的认证办法,需要识别用户名和密码,认证失败的客户端不拥有访问Nginx服务器的权限。该功能由HTTP标准模块ngx_http_auth_basic_module支持,这里由两个指令需要学习。
auth_basic指令,用于开启或者关闭认证功能,语法结构为:
auth_basic string | off;
- string,开启该认证功能,并配置验证时的指示信息。
- off,关闭该认证功能。
auth_basic_user_file指令,用于设置包含用户名和密码信息的文件路径,语法结构为:
auth_basic_user_file file;
其中,file为密码文件的绝对路径。
这里的密码文件支持明文或者密码加密后的文件。明文的格式如下所示:
name1:password1
name2:password2:comment
name3:password3
加密密码可以使用crypt()函数进行密码密码加密的格式,在Linux平台上可以使用htpasswd命令生成。在PHP和Perl等语言中,也提供crypt()函数。使用htpasswd命令的一个示例为:
htpasswd -c -d /nginx/conf/pass_file username
运行后输入密码即可。
Nginx服务器基础配置示例
下面是一个nginx.conf文件的配置内容:
#### 全局块 开始 ####
user nobody nobody; # 配置允许运行Nginx服务器的用户和用户组
worker_processes 3; # 配置允许Nginx进程生成的worker process数
error_log logs/error.log; # 配置Nginx服务器运行时错误日志存放路径
pid nginx.pid; # 配置Nginx服务器运行时的pid文件存放路径和名称
##### 全局块 结束 #####
#### events块 开始 ####
events
{
use epoll; # 配置事件驱动模型
worker_connections 1024; # 配置最大连接数
}
#### events块 结束 ####
#### http块 开始 ####
http{
include mime.types; #定义MIME-Type
default_type application/octet-stream;
sendfile on; #配置允许使用sendfile方式传输
keepalive_time 65; #配置连接超时时间
log_format access.log '$remote_addr-[$time_local]-"$request"-"$http_user_agent" '; #配置请求处理日志的格式
#### server块 开始 ####
## 配置虚拟主机 myServer1
server {
listen 8081; #配置监听端口和主机名称(基于名称)
server_name myServer1;
access_log /myweb/server1/log/access.log; #配置请求处理日志存放路径
error_page 404 /404.html; #配置错误页
# 配置处理/server1/location1请求的location
location /server1/location1 {
root /myweb;
index index.ser1-loc1.htm;
}
# 配置处理/server1/location2请求的location
location /server1/location2{
root /myweb;
index index.svr1-loc2.htm;
}
}
## 配置虚拟主机 myServer2
server {
listen 8082;
server_name 192.169.1.3;
access_log /myweb/server2/log/access.log;
error_page 404 /404.html; #对错误页面404.html做了定向配置
location /server2/location1 {
root /myweb;
index index.svr2-loc1.htm;
}
location /svr2/loc2 {
alias /myweb/server2/location2/; #对location的URI进行更改
index index.svr2-loc2.htm;
}
location = /404.html {
root /myweb/;
index 404.html;
}
}
#### server块 结束 ####
}
#### http块 结束 ####
在该实例中,配置了两个虚拟主机myServer1和myServer2,前者是基于名称的,后者是基于IP的。在每个虚拟主机里,有分别使用了location块对不同的请求进行处理。主机myServer2除了对一般的请求进行处理外,还对错误页面404.html做了定向配置,指向自定义的404处理页面。
为了测试此Nginx配置,构建了一个十分简单的静态网站站点。它的目录组织结构如下:
myweb
404.html
server1
location1
index.svr1-loc1.htm
location2
index.svr1-loc2.htm
log
access.log
server2
location1
index.svr2-loc1.htm
location2
index.svr2-loc2.htm
log
access.log
上面的目录结构是比较清晰的。在结构中的404.html这个文件,如果不适用myServer2中对错误页面定向的方法,而只是像myServer1那样简单设置错误页面的路径,那么Nginx服务器会在安装路径的html目录下的相关路径中寻找错误页面。
测试访问
首先测试myServer1,在用户端浏览器中输入“myserver1:8081/svr1/location1/”,可以看到网站页面的显示如图所示,这说明主机访问正常,也表明配置文件示例中配置正确。
同样,在用户端浏览器地址中输入“myserver1:8081/server1/location2/”,可以看到location指向的页面。
注意 为了能够以主机名的方式访问站点,我们需要配置自己的DNS服务器,使得浏览器能够根据输入的域名地址(myserver1)查找到对应的IP地址(192.168.1.3)。
测试myServer2的访问,在用户端浏览器中输入“192.168.1.3:8082/server2/location1”,可以看到页面显示正常,表明配置文件中配置正确。
在用户端浏览器地址中输入“192.168.1.3:8083/svr2/loc2”,则可以看到网站页面的显示。表明配置文件示例中对location块的URI路径有效。
如果在用户浏览器中输入“http://192.168.1.3:8082/server2/location2/”,由于使用location块对URL路径做了更改,导致无法找到网页,Nginx服务器返回404错误消息,而生效的是自定义的404错误页面的定向。