虚拟主机配置段
这里我的虚拟主机配置段(server{}段)独立了一个配置文件,在/etc/nginx/conf.d/目录下,然后包含进主配置文件中了。如果想定义多个虚拟主机,只需要定义多个server段的配置文件即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } |
http模块(ngx_http_core_module)
1)server
1 2 3 |
Syntax: server { ... } Default:— Context:http |
用于定义虚拟主机,可以有多个server 。每个server可以定义在一个配置文件中,但此配置文件必须要被nginx.conf文件包含。
2)listen
1 2 3 4 5 6 7 8 9 10 |
Syntax: listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]]; listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off| [keepidle]:[keepintvl]:[keepcnt]]; listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]]; Default: listen *:80 | *:8000; Context: server |
此虚拟主机监听的地址及端口,有三种语法格式:第一种可以写成监听listen IP:PORT,表示只监听在特定的IP地址及端口上;第二种是listen PORT,表示监听所有地址及特定端口,如下示例:
1 2 3 4 5 |
listen 127.0.0.1:8000; listen 127.0.0.1; listen 8000; listen *:8000; listen localhost:8000; |
第三种是监听在UNIX SOCK上,这种监听方式只能在本地访问,无法对外提供访问,一般不用。
1 |
listen unix:/var/run/nginx.sock; |
这三种格式,不管哪种都可以带上一堆参数,对我们而言一般使用到的不多,了解就行;比如:
default_server – 用于设定此虚拟主机为默认虚拟主机,如果访问一个域名可以解析到我们的主机上,但没有此域名对应的主机,就返回默认主机;
ssl – 表示此虚拟主机开启ssl功能,必须基于ssl协议建立连接;
spdy – 允许接收spdy协议发送的请求,据说比http/1.1性能好很多,这是Google开发的协议,编译时必须要编译spdy协议;
http2 – 表示是否使用http2协议,nginx已经支持http2协议,目前使用较多的还是http1.1版本,http2就是在spdy协议基础上做了规范;
setfib=number – 这个参数为监听套接字设置关联路由表FIB(SO_SETFIB选项),当前这个参数仅工作在FreeBSD上;
backlog=number – 为系统调用listen()设置backlog参数,用以限制未接受(Accept)连接的队列的最大长度。 FreeBSD和Mac OS X下,backlog的默认值是-1,在其他系统中,默认值是511;
rcvbuf=size – 为监听套接字设置接收缓冲区大小(SO_RCVBUF参数);
sndbuf=size – 为监听套接字设置发送缓冲区大小(SO_SNDBUF参数);
accept_filter=filter – 为监听套接字设置接受过滤器的名称(SO_ACCEPTFILTER选项)。对每个到来的连接,接受过滤器先进行过滤,然后才将它们呈现给accept()。本特性仅工作在FreeBSD系统和NetBSD 5.0+系统下;
deferred – 指示在Linux系统使用延迟的accept()(TCP_DEFER_ACCEPT选项)。
bind – 指示nginx为设置的address:port单独调用一次bind()。 这是因为当有多条listen指令监听不同地址下的相同端口, 而其中一条listen指令监听了这个端口的所有地址(*:port)时, nginx只会为*:port调用一次bind()绑定套接字。 需要留意的是,这种情况下,nginx会调用getsockname()系统调用来确定接受请求的套接字地址。 如果为某个address:port定义了参数backlog、rcvbuf、 sndbuf、accept_filter、deferred或者so_keepalive, nginx总会为这个地址单独调用一次bind()绑定套接字。
ipv6only=on|off – 这个参数(通过IPV6_V6ONLY选项)决定监听在通配地址[::]上的IPv6套接字是只支持IPv6连接,还是同时支持IPv6和IPv4连接。 这个参数默认打开,并且只能在nginx启动时设置。
reuseport – 这个参数是Nginx 1.9.1增加的一个对性能提升的特性,该套接字选项允许多个套接字监听同一IP和端口的组合;详情看这里:Nginx listen reuseport参数带来的性能提升;
so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt] – 这个参数为监听套接字配置“TCP keepalive”行为。 如果省略此参数,操作系统默认的设置将对此端口生效。 如果参数值设置为“on”,监听套接字的SO_KEEPALIVE属性将被开启。 如果参数值设置为“off”,监听套接字的SO_KEEPALIVE属性将被关闭。可以使用keepidle,keepintvl和keepcnt参数来配置。 省略一到两个参数的话,对应套接字属性的系统默认设置将生效。 比如:so_keepalive=30m::10,将设置空闲超时(TCP_KEEPIDLE)为30分钟, 设置探测次数(TCP_KEEPCNT)为10次, 保留探测时间间隔(TCP_KEEPINTVL)为系统默认值。另外需要知道的是TCP长连接跟Nginx长连接本质上不是一回事,而so_keepalive就是用来控制nginx服务器使用的tcp长连接相关参数。
3)server_name
1 2 3 |
Syntax: server_name name ...; Default:server_name ""; Context:server |
用于设置虚拟主机的主机名,server_name后面可以定义多个主机名,且主机名还可以使用通配符和正则表达式匹配。如下所示:
1 2 3 |
server { server_name www.example.com *.example.com ~^www\d+\.example\.com$; } |
那么当有多个主机名时,其匹配方式为先精确匹配,然后匹配左侧通配符,然后是右侧通配符,最后是正则表达式。
4)root
1 2 3 |
Syntax: root path; Default:root html; Context:http, server, location, if in location |
Web服务器接收到网络请求之后,首先要在服务器端指定目录中寻找请求资源,在Nginx服务器中,指令root就是用来设置用户请求根目录。其中path为根目录路径,path的值中可以包含除$document_root和$realpath_root以外的变量。示例为:
1 2 3 4 5 6 |
server { listen 80; servername www.ywnds.com; root /usr/local/nginx/html; index index.html index.htm; } |
上面是定义在server配置段中,更多时候是直接定义在server下的一个location中。
1 2 3 4 |
location / { root /usr/local/nginx/html; index index.html index.htm; } |
当用户请求server_name定义的域名时,nginx就会找根目录,这个location包含了一个root指定了根目录的位置。然后给了一个index指令,index就是指定根目录下的一个默认文件。root指令通常可以在http段、server段、或者location段配置,每个地方配置root生效的作用域就不同了。由于使用nginx服务器多数情况下要配置多个location段对不同的请求分别做出处理,因此该指令通常在location配置段中设置。
另外,如果location配置成以下格式:
1 2 3 |
location /image/ { root /data/nginx ; } |
如果访问http://127.0.0.1/image/top.gif,那么nginx将使用文件”/data/nginx/image/top.gif”响应请求”/i/top.gif”。
5)index
1 2 3 |
Syntax: index file ...; Default:index index.html; Context:http, server, location |
index指令由ngx_http_index_module模块引入,其作用就是用来指定默认主页的,默认使用的主页为index.html。如果想让默认主页为其他文件,添加进index指令后面即可,如下代码:
1 |
index index.html index.htm index.php |
6)location
1 2 3 4 |
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } Default:— Context:server |
location在Nginx中是一个独立配置段,可以在server段中使用,其功能是允许根据用户请求的URI来匹配定义的各个location。当被location匹配到时,此请求将被此location所定义的规则进行处理。简而言之,location即用于为需要用到专用配置的URI提供特定配置。
如下示例:
1 2 3 4 5 6 7 |
location / { root /usr/local/nginx/html; index index.html index.htm; } location /admin { } |
我们看location的语法,location [ = | ~ | ~* | ^~ ] uri {…..}用于定义一个server下的多个location定义的不同路径访问的不同属性。其中:
localtion URI {…} – 对当前路径及子路径下的所有对象都生效;
location = URI {…} – 精确匹配指定的路径,不包括子路经、因此只对当前路径生效;
location ~ URI {…} – 做正则表达式匹配,此处的URI可使用正则表达式匹配,区分字符大小写;
location ~* URI {…} – 做正则表达式匹配,此处的URI可使用正则表达式匹配,不区分字符大小写;
Location ^~ URI {} – 做URI左半部分匹配,不区分字符大小写,且不适用正则表达式;
具体这些符号在location中的意义是什么呢?下面看一个官方给的使用案例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
location = / { #location = /,匹配A [ configuration A ] } location / { #location /,匹配B [ configuration B ] } location /documents/ { #location /documents/,匹配C [ configuration C ] } location ^~ /images/ { #location /images,使用左半部分匹配,匹配D [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { #location \.(git|jpg|jpeg)$,使用正则表达式匹配,匹配E [ configuration E ] } |
现在假设,用户对我们这个server进行访问,访问的URL为http://www.ywnds.com,那么此时将会被A规则匹配,因为此时访问的URI就是/,location = /将会做精准匹配。
如果用户访问的是http://www.ywnds.com/index.html,那么此时将会被B规则匹配,因为此时访问的URI对于location = /来说就不是精准匹配了,因为此时的URI为/index.html,虽然访问的都是同一个主页。那么此访问就会到下一个location了,而location /表示匹配/下的所有,一般是提供默认配置的,所以直接匹配到了。
如果用户访问的是http://www.ywnds.com/documents/index.html,那么此时将会被C匹配。首先location = /肯定匹配不到了,而location /虽然可以匹配到,但是location /documents/更加精确,比location /优先级高,所以被C规则匹配到了。
如果用户访问的是http://www.ywnds.com/images/1.gif,那么此时将会被D匹配。首先location = /肯定匹配不到了,而location /虽然可以匹配到,location ^~ /images/也能匹配到,location ~* \.(gif|jpg|jpeg)$也能匹配到,但是为什么会被location ^~ /images/匹配处理呢?这就要说到优先级问题了。
当一个URI被多个location匹配到时,那么其优先级为:第一优先级为”=”符号,第二优先级为”^~”,第三优先级为”~”或”~*”,第四优先级为”/document”,第五优先级为”/”。其实”/documents”和”/”匹配方式就是谁能匹配到的URI字符多谁优先级就高,另外如果当一个URI同时被多个相同优先级的location匹配到了,那么此时匹配规则就是至上而下匹配了,谁先匹配到就以谁为准。
最后如果用户访问的是http://www.ywnds.com/documents/1.gif,那么此时将会被E匹配。知道了优先级就清楚这个问题了,首先B、C、E都是能够匹配到的,而location ~* \.(gif|jpg|jpeg)$优先级比location /documents/和location /都要高,所以就被E规则所匹配了。
7)alias
1 2 3 |
Syntax: alias path; Default:— Context:location |
alias指令只能够用在location配置段,其作用是定义路径别名的。如下示例:
1 2 3 |
location /images/ { alias /data/w3/img/; } |
当我们请求/images/top.jpg时,其对应的物理路径为/data/w3/img/top.jpg。这里要区分开root跟alias的不同之处,如果root指令这么使用:
1 2 3 |
location /images/ { alias /data/w3/img/; } |
那么当我们请求/images/top.jpg时,其对应的物理路径为/data/w3/img/images/top.jpg。跟alias使用时比较一下看看其不同之处。
8)error_page
1 2 3 |
Syntax: error_page code ... [=[response]] uri; Default:— Context:http, server, location, if in location |
作用就是用来根据http错误代码,指定返回的错误页面的给客户端。使用样例如下:
1 2 |
error_page 404 /404.html; error_page 500 502 503 504 /50x.html; |
对于404的错误代码,返回一个/目录下的404.html页面给客户端;对于500、501、502、503、504的错误返回一个/目录下的50x.html页面给客户端。这样一来就可以给用户一些友好的提供页面了,但是客户端看到的http code并不会改变(使用Google浏览器开发者工具可以看到http code),这个时候就可以使用error_page code = response了,比如对于一个404的错误,返回一个200的状态码。
1 |
error_page 404 =200 /404.html; |
同时这个error_page还可以把错误页面重定向到其他URL。
1 2 |
error_page 403 http://example.com/forbidden.html; error_page 404 =301 http://example.com/notfound.html; |
9)try_files
1 2 3 4 |
Syntax: try_files file ... uri; try_files file ... =code; Default:— Context:server, location |
try_files就是以指定的顺序去检查各文件的存在性,类似index指令。如果try_files指定的第一个文件存在就立即响应给用户,如果不存在就找第二个,以此类推,如果都找不到就返回给用户一个uri或者一个code,避免出现死循环。务必确认只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则将会出现内部500错误。
使用示例
1 2 3 4 5 6 7 8 |
location /doc { try_files /one.html /tow.html @tz; #try_files /one.html /tow.html =404; } location @tz { rewrite ^/(.*)$ http://www.ywnds.com; #proxy_pass http://www.ywnds.com; } |
当我们访问/doc目录时,如果此URI路径下有one.html这个文件,就直接返回,如果没有就找tow.html文件返回,如果都没有调用@tz这个代码块(或者直接返回一个404)。这个时候我们就需要提前定义一个location @tz了,此location内部可以使用rewrite进行跳转,也可以使用 proxy_pass http://www.ywnds.com;代理到后端。
官方示例中还有这种使用方法
1 2 3 4 5 6 |
location /images { try_files $uri $uri/ /images/default.gif; } location = /images/default.gif { expires 30s; } |
意思是如果客户端请求/images,$uri变量就是表示此目录下是否有次文件,而$uri/表示是否有此目录。如果不存在就返回最后一个参数给客户端进行跳转。上面这个例子中把最后一个参数定义了一个location,随便给了一个缓存30s的参数,避免死循环。
10)internal
1 2 3 |
Syntax: internal; Default:no Context:location |
internal指令指定某个location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)“内部的”是指下列类型:
指令error_page重定向的请求。
ngx_http_ssi_module模块中使用include virtual指令创建的某些子请求。
ngx_http_rewrite_module模块中使用rewrite指令修改的请求。
一个防止错误页面被用户直接访问的例子:
1 2 3 4 |
error_page 404 /404.html; location /404.html { internal; } |