将NGINX和NGINX Plus配置为网站服务器
将NGINX和NGINX Plus配置为网站服务器
将NGINX和NGINX Plus配置为网站服务器,支持虚拟服务器多用户,URI和响应重写,变量和错误处理。
本文介绍了如何将NGINX Open Source和NGINX Plus配置为网站服务器,并包括以下部分:
设置虚拟服务器
配置位置
位置优先级
使用变量
返回特定状态代码
重写请求中的URI
重写HTTP响应
处理错误
有关如何调整NGINX Plus和NGINX开源的更多信息,请观看我们的免费网络研讨会按需安装和调整NGINX。
注意:本文中的信息适用于NGINX开源和NGINX Plus。为了便于阅读,本文的其余部分仅涉及NGINX Plus。
在高层次上,将NGINX Plus配置为Web服务器是一个定义它处理哪些URL以及如何处理这些URL上的资源的HTTP请求的问题。在较低级别,配置定义了一组虚拟服务器,这些服务器控制对特定域或IP地址的请求的处理。有关配置文件的更多信息,请参阅创建NGINX Plus配置文件。
每个用于HTTP流量的虚拟服务器都定义了称为位置的特殊配置实例,用于控制特定URI集的处理。每个位置都定义了映射到该位置的请求发生的情况。NGINX Plus可以完全控制这个过程。每个位置都可以代理请求或返回文件。此外,可以修改URI,以便将请求重定向到另一个位置或虚拟服务器。此外,还可以返回特定的错误代码,您可以配置特定的页面以对应每个错误代码。
设置虚拟服务器
NGINX Plus配置文件必须包含至少一个服务器指令来定义虚拟服务器。当NGINX Plus处理请求时,它首先选择将服务于请求的虚拟服务器。
虚拟服务器由server上下文中的http指令定义,例如:
http { server { # Server configuration }}
可以将多个server指令添加到http上下文中以定义多个虚拟服务器。
server配置块通常包括一个listen指令,用于指定服务器监听请求的IP地址和端口(或Unix域套接字和路径)。接受IPv4和IPv6地址;将IPv6地址括在方括号中。
下面的示例显示了侦听IP地址127.0.0.1和端口8080的服务器的配置:
server { listen 127.0.0.1:8080; # Additional server configuration}
如果省略某个端口,则使用标准端口。同样,如果省略了某个地址,服务器将侦听所有地址。如果根本没有包含listen指令,则“标准”端口为80/tcp,“默认”端口为8000/tcp,具体取决于超级用户权限。
如果有多个服务器与请求的IP地址和端口匹配,NGINX Plus会根据Host块中的server_name指令测试请求server的参数可以是一个完整的(确切的)名称,一个正则表达式或一个正则表达式。星号是一个字符串,它在开头、结尾或两者都包含星号(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文件中列出的第一个服务器,除非您在default_server指令中包含listen参数以显式指定服务器为默认服务器。
server { listen 80 default_server; #...}
配置位置
NGINX Plus可以根据请求URI将流量发送到不同的代理或服务不同的文件。这些块是使用server指令中的location指令定义的。
例如,您可以定义三个location块来指示虚拟服务器将一些请求发送到一个代理服务器,将其他请求发送到另一个代理服务器,并通过从本地文件系统传递文件来服务其余请求。
NGINX Plus针对所有location指令的参数测试请求URI,并应用在匹配位置定义的指令。在每个location块中,通常可以(除了少数例外)放置更多的location指令,以进一步细化特定请求组的处理。
注意:在本指南中,位置一词指的是单个位置上下文。
location指令有两种类型的参数:前缀字符串(路径名)和正则表达式。要使请求URI与前缀字符串匹配,它必须以前缀字符串开头。
以下带有路径名参数的示例位置匹配开始以/some/path/开头的请求URI,例如/some/path/document. html。(It与/my-site/some/path不匹配,因为/some/path不在该URI的开头。
location /some/path/ { #...}
正则表达式前面加波浪号(~)表示区分大小写的匹配,或加波浪号-星号(~*)表示不区分大小写的匹配。下面的示例匹配在任何位置包含字符串.html或.htm的URI。
location ~ \.html? { #...}
NGINX位置优先级
为了找到与URI最匹配的位置,NGINX Plus首先将URI与具有前缀字符串的位置进行比较。然后,它使用正则表达式搜索这些位置。
正则表达式优先级更高,除非使用了^~修饰符。在前缀字符串中,NGINX Plus选择最具体的一个(即最长和最完整的字符串)。下面给出了选择位置来处理请求的确切逻辑:
根据所有前缀字符串测试URI。
=(等号)修饰符定义URI和前缀字符串的精确匹配。如果找到完全匹配,则停止搜索。
如果^~(caret-tilde)修饰符前置最长匹配前缀字符串,则不检查正则表达式。
存储最长匹配前缀字符串。
根据正则表达式测试URI。
当找到第一个匹配的正则表达式时停止处理并使用相应的位置。
如果没有正则表达式匹配,则使用与存储的前缀字符串对应的位置。
=修饰符的典型用例是请求/(正斜杠)。如果频繁地请求/,则将= /指定为location指令的参数可以加快处理速度,因为在第一次比较之后,匹配的搜索就会停止。
location = / { #...}
一个location上下文可以包含定义如何解析请求的指令--要么提供静态文件,要么将请求传递给代理服务器。在下面的示例中,匹配第一个location上下文的请求将从/data目录中提供文件,而匹配第二个上下文的请求将被传递到托管www.example.com域内容的代理服务器。
server { location /images/ { root /data; } location / { proxy_pass http://www.example.com; }}
根指令指定了在其中搜索要提供的静态文件的文件系统路径。与该位置关联的请求URI被附加到路径中,以获得要提供服务的静态文件的全名。在上面的例子中,响应于对/images/example. png的请求,NGINX Plus提供了文件/data/images/example. png。
proxy_pass指令将请求传递给通过配置的URL访问的代理服务器。然后将来自代理服务器的响应传递回客户端。在上面的示例中,所有URI不是以/images/开头的请求都将被传递到代理服务器。
使用变量
您可以使用配置文件中的变量来让NGINX Plus根据定义的情况以不同的方式处理请求。变量是在运行时计算的命名值,用作指令的参数。变量在其名称的开头用$(美元)符号表示。变量根据NGINX的状态定义信息,例如当前正在处理的请求的属性。
有许多预定义的变量,例如核心HTTP变量,您可以使用set、map和geo指令定义自定义变量。大多数变量在运行时计算,包含与特定请求相关的信息。例如,$remote_addr包含客户端IP地址,$uri保存当前URI值。
返回特定状态代码
某些网站URI要求立即返回带有特定错误或重定向代码的响应,例如,当页面暂时或永久移动时。最简单的方法是使用return指令。举例来说:
location /wrong/url { return 404;}
return的第一个参数是响应代码。可选的第二个参数可以是重定向的URL(对于代码301、302、303和307),也可以是在响应正文中返回的文本。举例来说:
location /permanently/moved/url { return 301 http://www.example.com/moved/here;}
return指令可以包含在location和server上下文中。
重写请求中的URI
在请求处理过程中,可以通过使用rewrite指令多次修改请求URI,该指令有一个可选参数和两个必需参数。第一个(必需的)参数是请求URI必须匹配的正则表达式。第二个参数是要替换匹配URI的URI。可选的第三个参数是一个标志,它可以停止处理更多的rewrite指令或发送重定向(代码301或302)。举例来说:
location /users/ { rewrite ^/users/(.*)$ /show?user=$1 break;}
如本例所示,第二个参数users捕获正则表达式的匹配。
您可以在rewrite和server上下文中包含多个location指令。NGINX Plus按照指令出现的顺序一个接一个地执行。在rewrite上下文中的server指令在该上下文被选择时执行一次。
在NGINX处理了一组重写指令之后,它会根据新的URI选择location上下文。如果所选位置包含rewrite指令,则依次执行这些指令。如果URI与其中任何一个匹配,则在处理完所有定义的rewrite指令后开始搜索新位置。
下面的示例显示了rewrite指令与return指令的组合。
server { #... rewrite ^(/download/.*)/media/(\w+)\.?.*$ $1/mp3/$2.mp3 last; rewrite ^(/download/.*)/audio/(\w+)\.?.*$ $1/mp3/$2.ra last; return 403; #...}
此示例配置区分两组URI。URI(例如/download/some/media/file)更改为/download/some/mp3/file.mp3。由于last标志,后续指令(第二个rewrite和return指令)被跳过,但NGINX Plus继续处理请求,现在有不同的URI。类似地,URI(例如/download/some/audio/file)被替换为/download/some/mp3/file.ra。如果URI
有两个参数会中断rewrite指令的处理:
last
break新位置中的rewrite指令不会执行。
重写HTTP响应
有时你需要重写或更改HTTP响应中的内容,用一个字符串替换另一个。可以使用sub_filter指令定义要应用的重写。该指令支持变量和替换链,使更复杂的更改成为可能。
例如,您可以更改引用代理以外的服务器的绝对链接:
location / { sub_filter /blog/ /blog-staging/; sub_filter_once off;}
另一个示例将方案从http://更改为https://,并将localhost地址替换为请求报头字段中的主机名。sub_filter_once指令告诉NGINX在一个位置内连续应用sub_filter指令:
location / { sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/'; sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/'; sub_filter_once on;}
请注意,如果出现另一个sub_filter匹配,则不会再次替换已使用sub_filter修改的响应部分。
处理错误
使用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,并将客户端重定向到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/ { # Set the root directory to search for the file root /data/www; # Disable logging of errors related to file existence open_file_cache_errors off; # Make an internal redirect if the file is not found error_page 404 = /fetch$uri; } location /fetch/ { proxy_pass http://backend/; }}
error_page指令指示NGINX Plus在找不到文件时进行内部重定向。$uri指令的最后一个参数中的error_page变量保存当前请求的URI,该URI在重定向中传递。
例如,如果没有找到/images/some/file,它将被替换为/fetch/images/some/file,并开始新的位置搜索。结果,请求在第二个location上下文中结束,并被代理到http://backend/。
open_file_cache_errors指令防止在文件未找到时写入错误消息。这在这里是不必要的,因为丢失的文件会被正确处理。
我有话说: