原文地址:https://docs.nginx.com/nginx/admin-guide/web-server/web-server/
这篇文章解释了如何配置NGINX Plus作为一个web 服务器,包括以下几个部分:
- 设置Virtual Server
- 配置Location
- 使用Variable
- 返回指定的Status Code
- 重写请求的URI
- 重写HTTP响应
- 异常处理
对于如何调企业版的NGINX Plus和开源的NGINX软件,可以查看我们的网络研讨直播Installing and Tuning NGINX.
从较高的一个层面来说,为NGINX配置web服务器,是为了定义它需要处理的URL集合,以及它如何处理与这些URL对应的资源的HTTP请求。
微观层面上来说,配置文件定义了一个控制特定域名或者特定IP地址的虚拟服务器集合。
想获取更多关于配置文件的信息,可以查看Creating NGINX Plus Configuration Files.
每一个HTTP 规则定义的虚拟服务器,都定义了一个location配置实例,这个实例控制着一个URI集合的处理。每一个location都定义了一个请求映射到location的场景。NGINX Plus提供了一个完全控制的方法。每一个location都可以代理请求或者返回一个文件。其次,URI可以被修改,这样请求会被重定向到另一location或者虚拟服务器。同样,一个指定的error code可以被返回,并且你可以配置一个指定页去响应每一个error code。
设置一个虚拟服务器
NGINX Plus配置文件必须包括至少一个server指令去定义虚拟服务器。在NGINX Plus处理请求时,它首先会选择虚拟服务器并且去处理请求。
一个虚拟服务器由一个server指令定义,这个server指令位于http客户端,例如:
http {
server {
# 服务器配置
}
}
可以在http里设置多个server,开启多个虚拟服务器。
server 配置块通常包括一个listen
指令,它定义了IP地址一个端口(或者是UNIX域名的socket和path)监听请求。IPv4和IPv6地址都可以接收;需要将IPv6的地址用(包裹起来。
下面的例子展示了监听了IP地址127.0.0.1:8080的服务。
server {
listen 127.0.0.1:8000;
# 其余的server配置项
}
如果端口号被省略,标准端口号会被使用。同样,如果一个地址被忽略,服务器将监听所有地址。如果listen指令没有被包括在内,"standard"端口将会是80/tcp,而且"default"端口是8000/tcp,这取决于超级用户的权限。
如果有多个服务器都匹配到了IP地址和端口,NGINX Plus根据server_name指令测试请求的Host报文头。server_name的参数可以是全名(精确),通配符和正则表达式。一个通配符是指一个字符串,它可以在开始,结束或者两边增加;星号匹配任何字符串序列。NGINX Plus使用Perl语法正则;需要加~。下面的例子解释了什么事精确名。
server {
listen 80;
server_name example.org www.example.org;
...
}
如果有几个名字匹配到Host报文头,NGINX Plus将通过下面的顺序以及规则去搜索。
- 精确名
- 长通配符以开头,例如.example.org
- 长通配符以结尾,例如mail.
- 首先匹配正则表达式 (按照配置文件的顺序)
如果Host头与服务器名不匹配,NGINX Plus路由请求到默认服务器的默认端口。默认服务器是nginx.conf文件的第一个监听的服务器,除非你显式地为listen指令的端口后面加上default_server。
server {
listen 80 default_server;
...
}
配置Locations
NGINX Plus可以发送traffic到不同的代理或者基于不同的请求URI返回不同的文件。这些块可以在server的location的指令中定义。
例如,你能定义3个location块,指明虚拟服务器发送请求到一个代理服务器,发送其他请求不同的代理服务器,然后从本地的文件系统处理其他的请求。
NGINX Plus根据location定义的URI去测试请求。在每一个location内部,它可以通常可以放置更多location指令去进一步细化特定的请求组的处理。
注意:location指定是location上下文。
location指令有2种类型的参数:prefix 字符串(路径名) 和 正则表达式。请求URI为了需要匹配字符串前缀,所有它必须以前缀字符串开头。
下面的带路径名参数的示例location与请求URI /some/path/ 匹配,例如/some/path/document.html。(不会匹配/my-site/some/path),因为/some/path没有出现在这个URI的起始位置。
location /some/path/ {
...
}
正则表达式需要在区分大小写的匹配前加一个~,或者tilde asterik(~*)做匹配。下面的例子会匹配任何位置的.html或者.htm URI。
location ~ \.html? {
...
}
为了找到最匹配的URI,NGINX Plus首先会与带着前缀字符串的location的URI做匹配。然后它会按照正则表达式做匹配。
如果不用^~,那么更高层级的正则规则需要使用。在所有前缀中,NGINX Plus会选择最匹配的一个。(也就是,最长并且最完整的字符串)。选择一个location的精确处理请求按照下面的逻辑:
- 根据所有前缀测试URI。
- = (相等操作符)定义了URI和前缀字符串的精确匹配。如果精确匹配到了,搜索停止。
- 如果^~修饰符预先匹配最长的匹配前缀字符串,不检查正则表达式。
- 存储最长的匹配前缀字符串
- 根据正则表达式测试URI
- 打破第一个匹配的正则表达式并使用相应的位置。
- 如果没有正则表达式匹配,请使用与存储的前缀字符串对应的位置。
一个典型的=的使用场景是对/。如果频繁请求/,可以使用 = / 作为location指令的参数加速处理,因为在第一次比较之后,匹配搜索就会停止。
location = / {
...
}
一个location上下文可以包含定义如何解析请求的指令--可以是静态文件,可以将请求转发到代理服务器。在下面的示例中,请求可以匹配到第一个location上下文的/data目录下的服务文件,以及匹配了第二个传递到代理服务器的参数可以获取到www.example.com域名下的内容。
server {
location /images/ {
root /data;
}
location / {
proxy_pass http://www.example.com;
}
}
-
root
root指令制定了文件系统的路径,这个路径是为了静态文件服务的。与location相关的请求URI需要添加上路径名从而获取完整的静态文件。在上面的例子中,在响应/images/example.png请求的时候,NGINX Plus将会获得/data/images/example.png. -
proxy_pass
proxy_pass 指令将传递请求到代理服务器,这个代理服务器可以通过配置的URL访问。从代理浏览器过来的响应之后可以传递回客户端。在上面的示例中,所有不以/images/开头的请求,会转发到代理服务器。
使用变量
可以在配置文件中使用变量,从而使NGINX Plus能够灵活处理各种各样的情况。变量在运行时会被赋值,可以作为指令的参数。一个变量在其名称的开头用$表示。变量基于NGINX状态定义信息,比如处理请求的属性。
还有一些预先定义的变量,例如core HTTP变量,而且你可以使用set,map,geo等指令定义常用变量。大多数变量会在运行时计算,而且可以包含相关的请求的信息。例如$remote_addr包含了client IP,$uri包含了当前的URI值。
返回指定的Status Code值
一些网站的URI需要带有具体错误或者重定向code响应的立即返回,例如当一个页面被暂时移动或者永久移动。最简单的方式就是return 指令。例如:
location /wrong/url {
return 404;
}
return的第一个参数是响应code。可选的第二个参数可以是用来重定向的URI,这些code包括301,302,303和307,或者是在响应body返回的文本内容。
location /permanently/moved/url {
return 301 http://www.example.com/moved/here;
}
return指令可以被包含在location和server上下文中。
在请求中重写URI
在通过rewrite指令处理请求的过程中,一个请求URI可以多次被修改,rewrite可以有一个或者两个参数。第一个参数是必须参数,是用来请求URI的正则匹配表达式。第二个参数是匹配URI的替代URI。第三个可选参数是一个flag,可以暂停进一步重写指令的处理或发送重定向(301 , 302)。
location /users/ {
rewrite ^/users/(.*)$ /show?user=$1 break;
}
在上面的示例中,第二个参数users通过正则表达式捕获。
在一个server和location上下文中,你可以包含多个rewrite指令。NGINX Plus可以按照顺序依次执行指令。server上下文中的rewrite指令仅仅在context被选中后执行一次。
在NGINX处理了一个rewriting操作集合后,它将根据新的URI去选择一个location上下文。如果选择的location包含rewrite指令,可以被执行。如果URI匹配其中的任何一个,则在处理完所有定义的重写指令后开始搜索新位置。
下面的例子中展示了rewrite指令与return指令联合起来使用的例子:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.mp3 last;
return 403;
...
}
这个例子配置区分了两个URI集合。像/download/some/media/file这样的集合将会匹配到/download/some/mp3/file.mp3。由于最后一个标志,后续指令(第二个重写和返回指令)被跳过,但NGINX Plus继续处理请求,该请求现在具有不同的URI。 /download/some/audio/file会被替换成/download/some/mp3/file.ra.若没有匹配到任何rewrite指令,NGINX Plus将返回403给客户端。
有2个指令中断rewrite指令:
- last
停止在当前server或location上下文中执行rewrite指令,但NGINX Plus搜索与重写的URI匹配的位置,并且应用新位置中的任何rewrite指令(意味着URI可以再次更改)。 - break
与break指令一样,停止在当前上下文中处理重写指令,并取消搜索与新URI匹配的位置。不执行新位置中的rewrite指令。
重写 HTTP 响应
有时你需要重写HTTP响应的内容,替代另一个字符串。你可以使用sub_filter指令定义rewrite将应用的。指令支持supports变量和替代链,以应对更加复杂匹配。
例如,你可以修改到绝对路径链接服务,而不是proxy。
location / {
sub_filter /blog/ /blog-staging/;
sub_filter_once off;
}
另一个例子可以将http://改变到http_s_://,并将localhost地址替换为请求标头字段中的主机名。sub_filter_once指令会使得NGINX连续应用同一个location下的sub_filter指令。
location / {
sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/';
sub_filter 'img href="http://127.0.0.1:8080/' img 'src="https://$host/';
sub_filter_once on;
}
请注意,如果发生另一个sub_filter匹配,则不会再次替换已使用sub_filter修改的响应部分。
Handling Errors
使用error_page指令,您可以配置NGINX Plus以返回自定义页面以及错误代码,在响应中替换不同的错误代码,或将浏览器重定向到其他URI。在以下示例中,error_page指令指定要返回404错误代码的页面(/404.html)。
error_page 404 /404.html;
请注意,此指令并不意味着立即返回错误(return指令执行此操作),而只是指定在错误发生时如何处理错误。错误代码可以来自代理服务器,也可以在NGINX Plus处理期间发生(例如,当NGINX Plus无法找到客户端请求的文件时,404结果)。 在以下示例中,当NGINX Plus无法找到页面时,它会将代码301替换为代码404,并将客户端重定向到http:/example.com/new/path.html。当客户端仍在尝试以旧URI访问页面时,此配置很有用。 301代码通知浏览器该页面已永久移动,并且需要在返回时自动将旧地址替换为新地址。
location /old/path.html {
error_page 404 =301 http:/example.com/new/path.html;
}
以下配置是在未找到文件时将请求传递到后端的示例。因为在error_page指令中的等号后面没有指定状态代码,所以对客户端的响应具有代理服务器返回的状态代码(不一定是404)。
server {
...
location /images/ {
# 设置root目录搜索资源
root /data/www;
# 禁用与文件相关的错误日志
open_file_cache_errors off;
# 如果文件未找到做内部重定向
error_page 404 = /fetch$uri;
}
location /fetch/ {
proxy_pass http://backend/;
}
}
error_page指令指示NGINX Plus在找不到文件时进行内部重定向。 error_page指令的final参数中的$ uri变量包含当前请求的URI,该URI在重定向中传递。 例如,如果未找到/ images / some / file,则将其替换为/ fetch / images / some / file,并开始新的位置搜索。结果,请求在第二个位置上下文中结束,并被代理到http:// backend /。 如果找不到文件,open_file_cache_errors指令将阻止写入错误消息。这不是必需的,因为正确处理丢失的文件。
网友评论