澳门新葡萄京官网注册 1

原标题:nginx 1.17.7 主线版发布 来源:开源中国nginx
会同时维护着两个分支,分别为 mainline 主线版和 stable 稳定版。不过在
nginx
中,“稳定”指的是功能和更新频率,它与软件质量无关。稳定分支在其生命周期中从不接收新功能,并且通常仅接收一个或两个更新,用于修复严重的错误。nginx
1.17.7(mainline version)发布了,此版本主要是修复
bug,变更内容如下:Bugfix:如果在配置中使用了带有空替换字符串的”rewrite”指令,则可能在启动或重新配置期间发生分段错误Bugfix:如果将”break”指令与”alias”指令或带有
URI 的”proxy_pass”指令一起使用,则可能在 worker
进程中发生分段错误Bugfix:如果请求 URI 被重写为包含空字符的
URI,则”Location”的响应 header
行可能包含垃圾Bugfix:使用”error_page”指令返回重定向时,带有正文的请求会被错误处理;该错误在
0.7.12 中出现过Bugfix:使用 HTTP/2 时出现 socket 泄漏的情况Bugfix:在
SSL 连接中处理流水线请求时可能会发生超时; 该错误在 1.17.5
中出现过Bugfix: in the ngx_http_dav_module.下载地址 | 更新说明

编译自:
nginx-web-server

  • Bugfix:如果在配置中使用了带有空替换字符串的”rewrite”指令,则可能在启动或重新配置期间发生分段错误

  • Bugfix:如果将”break”指令与”alias”指令或带有 URI
    的”proxy_pass”指令一起使用,则可能在 worker 进程中发生分段错误

  • 澳门新葡萄京官网注册 ,Bugfix:如果请求 URI 被重写为包含空字符的 URI,则”Location”的响应
    header 行可能包含垃圾

  • Bugfix:使用”error_page”指令返回重定向时,带有正文的请求会被错误处理;该错误在
    0.7.12 中出现过

  • Bugfix:使用 HTTP/2 时出现 socket 泄漏的情况

  • Bugfix:在 SSL 连接中处理流水线请求时可能会发生超时; 该错误在
    1.17.5 中出现过

  • Bugfix: in the ngx_http_dav_module.

目录

下载地址 | 更新说明

  • 建立虚拟服务器
  • 配置 location
  • 使用变量
  • 返回指定的状态码
  • URI 重写
  • 对 HTTP Response 进行重写
  • 处理错误

这里有一个视频,有兴趣可以看看:nginx
安装与调优,其中讲述了以下主题:

  • nginx 怎样使你的应用能更快响应、具有更好的伸缩性、更快、更安全?
  • 如何安装 nginx
  • 为 nginx 调整操作系统参数

从高层次来说,配置 nginx 为一个 web 服务器,主要是定义:

  • 对哪些 URL 进行处理
  • 如何处理对于这些 URL 的 HTTP 请求

从较低层次来说,主要是定义一组 虚拟服务器 ,让这些 虚拟服务器
去处理对于 特定域名IP地址 的请求。

更多关于如何配置 nginx 的信息,可参考 Creating NGINX Plus Configuration
Files。

每个 虚拟服务器 都定义了 location 区块,location
区块定义了对于指定的一组 URI 是如何进行处理的。

在 location 中可作如下定义:

  • 转发请求到后端服务器(也就是将此 nginx
    服务器作为代理),或者返回一个文件;
  • 对 URI 进行重写,将请求重定向至其它的 location 或者其它虚拟服务器;
  • 返回指定的 error code,并且可以为每个 error code 配置一个指定的
    error page。

建立虚拟服务器


在 nginx 配置文件中,必须包含至少一个 server 指令,server
指令定义了一个虚拟服务器。当一个请求到来时,nginx
首先要决定选择哪一个虚拟服务器处理该请求。

server 指令在 http context 中进行定义,例如:

http {
    server {
        # Server configuration
    }
}

http context 中,可添加多个 server 指令以定义多个虚拟服务器。

server 区块中,一般会包含一个
listen
指令。listen 指令是用于定义该虚拟服务器监听于哪个 IP地址
端口(或者定义一个 Unix socket 文件及路径)。IP地址可为 IPv4 或 IPv6
地址;IPv6 地址应放入方括号中。

以下是一个例子,该服务器监听于 127.0.0.1 和 8080 端口:

server {
    listen 127.0.0.1:8080;
    # The rest of server configuration
}

如果不指定端口地址,将使用标准的端口地址,即 80 端口。如果不指定 IP
地址,将监听于所有 IP 地址之上。如果 server 区块中没有包含 listen
指令,根据超级用户的权限,将使用 标准的 80/tcp 端口或者 默认的
8000/tcp 端口。

如果同时有多个 虚拟主机 匹配了请求的IP地址和端口,nginx 将测试请求的
Host 首部字段,将它与 server 区块中的
server_name
指令的配置进行对比。server_name
指令的值有三种:准确的主机名通配主机名正则表达式主机名。通配主机名在其起始、或末尾有一个
* 符号,或者起始和末尾都有一个 * 符号,*
可匹配任意长度的字符串;nginx 的正则表达式兼容 Perl
的正则语法,在正则表达式之前需有~前缀。

以下是关于 准确的主机名 的例子:

server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

如果有多个 server_name 指定的主机名与请求首部的 Host
字段匹配,nginx 按如下的优先次序选择,当找到第一个能匹配的 server name
就终止查找:

  1. 准确的主机名
  2. 以 “*” 起始的最长的通配主机名,比如 *.example.org
  3. 以 “*” 结尾的最长的通配主机名,比如 mail.*
  4. 第一个匹配的正则表达式(按照配置文件中的顺序)

如果没有找到与 Host 字段匹配的 server name,nginx
将把请求路由到该端口地址的 默认的虚拟主机
如果没有特别指定,默认的虚拟主机 就是 nginx.conf
文件中的第一个定义的 虚拟主机。也可以使用 listen 指令的
default_server 参数显式地指定一个虚拟主机为 默认的虚拟主机

server {
    listen      80 default_server;
    ...
}

配置 location


nginx 可基于请求的
URI,将访问流量转发给不同的后端服务器,或者将不同的文件提供给客户端。这个功能由
location
指令定义,location 指令在 server 区块中定义。

举个例子,你可以定义三个 location
区块,将一些请求转发给一个后端服务器,将另一些请求转发给另一个不同的后端服务器,余下的请求从本地的文件系统中提供客户端所请求的文件。

当一个请求交给了某个虚拟主机之后,nginx 将请求的 URI
与该虚拟主机内所有的 location 指令的定义进行对比,然后将请求映射到匹配的
location 之中。

在每个 location 区块中,一般可以放置更多的 location
指令(有少数例外),用于进一步对请求进行分组处理。

Note: 在本文中,location 这个词只表示一个单独的 location
上下文。

location 指令可定义两种参数:

  • 前缀字符串(路径名)
  • 正则表达式

如果一个请求的 URI 以某个 前缀字符串 为起始,则与该 location 匹配。

下面举一个 前缀字符串 的例子,在下面的例子中,该 location 的参数为
/some/path/ ,它能匹配类似于 URI 为 /some/path/document.html
的请求:

location /some/path/ {
    ...
}

正则表达式必须带有前缀 ~~*(忽略大小写)。在下面的例子中,该
location 可匹配包含 .html 或者 .htm 的请求:

location ~ .html? {
    ...
}

为了找到某个 URI 的最佳匹配,nginx 首先比较 URI 和 前缀字符串,然后比较
URI 和 正则表达式。

正则表达式拥有更高的优先级,除非正则表达式使用了 ^~ 修饰符。

在所有匹配的 前缀字符串 中,nginx
选择其中最长及最完整的前缀字符串所对应的 location。

下面是准确的查找 loction 的过程:

  1. 将 URI 与所有的 前缀字符串 进行比较
  2. 修饰符 = 表示 URI 与 前缀字符串
    必须精确匹配。如果能够精确匹配,则结束查找
  3. 如果在匹配的最长的 前缀字符串 前添加了 ^~
    修饰符,则不会再检查正则表达式
  4. 保存匹配的最长的 前缀字符串
  5. 测试 URI 和 正则表达式的匹配情况
  6. 一旦找到匹配的正则表达式,则终止查找,并使用对应的 location
  7. 如果没有匹配的正则表达式,使用保存匹配的最长的 前缀字符串

如果对于 / 的请求很频繁,可为 location / 添加 =
修饰符,这样可以加速处理过程,因为一次匹配查找即可结束:

location = / {
    ...
}

在 location
区块中,可匹配将请求转发给后端服务器。在下面的例子中,对于匹配第二个
location 的请求,将被转发给
www.example.com

server {
    location  {
        root /data;
    }

    location / {
        proxy_pass http://www.example.com;
    }
}

root
指令指定了提供静态文件的本地路径。如果请求的 URI 匹配第一个 location,将
URI 追加到 /data
之后即可得到文件的访问路径:/data/URI。比如请求的 URI 为
xample.png,nginx 将 /dataxample.png
文件返回给客户端。

proxy_pass
指令用于将请求转发给后端服务器,参数值即为后端服务器的访问路径
URL。从后端服务器取回响应之后,nginx
再转发给客户端。在上面的例子中,所有不以 ** 起始的
URI,对应的请求将被转发给后端服务器。

使用变量


nginx.conf
中可使用变量。变量的值在运行时进行计算,可作为指令的参数使用。引用变量,使用
$ 符号,比如 $remote_addr。变量的定义信息依赖于 nginx
当前的状态,比如当前被处理的请求的属性等。

有许多变量是预定义的,比如 core
HTTP
定义的变量;另外你也可以自定义变量,使用
set,map,或
geo
指令进行自定义。

大多数变量的值是在运行时计算出来的,其中包含特定请求的信息。比如
$remote_addr 包含客户端的 IP地址 信息,而 $uri 包含当前的 URI 值。

返回指定的状态码


在有些情况下,比如当一个页面已经被临时或永久地移动到其他位置,访问这种
web 站点的 URI 时需要立即返回一个错误码或者重定向码。最容易的方法是使用
return
指令:

location /wrong/url {
    return 404;
}

return
指令的第一个参数是响应状态码。第二参数是可选的,可以是一个重定向的
URL(for codes 301, 302, 303, and 307),或者是放入响应 body
的一段文本。比如:

location /permanently/moved/url {
    return 301 http://www.example.com/moved/here;
}

return 指令可放入 location 和 server 上下文中。

URI 重写


在处理请求的过程中,使用
rewrite
指令可对 URI 进行多次修改。

rewrite 指令的语法为:

rewrite regex replacement [flag]

regex 是用于匹配 URI 的正则表达式,replacement 参数用于替换匹配的
URI。flag 参数是可选的,可用于终止进一步的 rewrite
指令操作,或者发送重定向(301 或 302)给客户端,例如:

location /users/ {
    rewrite ^/users/(.*)$ /show?user=$1 break;
}

server 上下文和 location 上下文中,都可包含多个 rewrite
指令。nginx 按照 rewrite 指令出现的顺序依次进行处理。当一个 server
上下文被选择用于处理请求时,在 server 上下文中的 rewirte
指令被执行一次。

当 nginx 对一组 rewrite 指令进行处理之后,它根据新的 URI 选择匹配的
location 上下文。如果在选择的 location 中也包含 rewrite
指令,它们将被依次执行。如果 URI 匹配其中任意一个,当所有定义的 rewrite
指令被处理之后,开始对新的 URI 进行查找。

如下例子中,rewrite 指令和 return 指令联合使用:

server {
    ...
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

上例中,对两组 URI 进行了区分。

  • 类似于 /download/some/media/file 的 URI 请求被替换为
    /download/some/mp3/file.mp3。因为该 rewrite 指令添加了 last
    flag,它将跳过后面的指令(第二个 rewrite 指令和 return 指令)。然后
    nginx 开始处理新的 URI。

  • 类似于 /download/some/audio/file 的 URI 请求被替换为
    /download/some/mp3/file.ra。因为该 rewrite 指令添加了 last
    flag,它将跳过后面的指令(return 指令)。

  • 如果 URI 不匹配 location 中的任何一个 rewrite 指令,nginx 返回 403
    状态码给客户端。

rewrite 指令有两个参数可以终止 rewrite 指令集的处理:

  • last – 停止当前 server 或 location 上下文中的 rewrite
    指令集的执行,nginx 对修改后的 URI 进行匹配查找。如果新匹配的
    location 中包含 rewrite 指令,URI 有可能被再次修改。

  • break – 如同
    break
    指令,终止当前上下文中的 rewrite 指令集的执行,nginx 对修改后的 URI
    进行匹配查找,在新匹配的 location 中如果包含 rewrite
    指令,它们不会被执行。

对 HTTP Response 进行重写


有时你需要对 HTTP 响应报文的内容进行重写或修改。你可以使用
sub_filter
指令来定义重写操作。该指令支持变量和链式替换,可作复杂的修改:

举个例子,你可以对指向一个服务器的绝对链接进行修改:

location / {
    sub_filter      /blog/ /blog-staging/;
    sub_filter_once off;
}

另一个例子,修改 http://https:// ,并且将 localhost
地址修改为请求首部中的 host
字段的值。sub_filter_once
指令告诉 nginx
是否对所有匹配的字符串重复地执行替换操作,还是只在第一次遇到匹配的字符串时,执行一次替换操作(只替换一次)。sub_filter_once
默认为 on,表示只在第一次遇到匹配的字符串时,替换一次:

location / {
    sub_filter     'href="http://127.0.0.1:8080/'%20%20%20%20'href="https://$host/';
    sub_filter     'img src="http://127.0.0.1:8080/'%20'img%20src="https://$host/';
    sub_filter_once on;
}

注意,如果响应报文的一部分已经被一个 sub_filter 指令所修改,当另一个
sub_filter 也匹配该部分时,不会再进行修改。

处理错误


使用
error_page
指令,你可以配置 nginx :

  • 返回一个 error code 以及一个自定制的页面;
  • 在响应报文中,替换一个不同的 error code
  • 发送重定向指令给浏览器,指向不同的 URI

在下面的例子中,error_page 指令指定了 /404.html
页面,这个页面在返回 404 code 时会一并返回给客户端:

error_page 404 /404.html;

要注意的是,这个指令不是立即返回该错误给客户端(这是 return
指令做的事),这只是定义了如果处理该错误。该 error code
可来自于一个后端服务器,或者在 nginx 做一些处理时出现(例如,当 nginx
不能找到请求的文件时,将返回 404 错误)。

下面的例子中,当 nginx 找不到请求的页面时,它将 code 404 替换为了 code
301,并将返回一个重定向给客户端:http:/example.com/new/path.html

这个配置是很有用的,当客户端尝试以一个老旧的 URI
请求页面时,可返回重定向指令,令其访问在新路径下的文件。

code 301
告诉浏览器,该页面已经被永久地转移到了其他地方,它需要将返回的新的地址替换原来的老的地址:

location /old/path.html {
    error_page 404 =301 http:/example.com/new/path.html;
}

下面的例子中,当请求
路径下的文件发生文件未找到的错误时,通过内部重定向转发到后端服务器。因为在
error_page 指令中,在 =
后面没有定义替换的状态码,所以返回给客户端的状态码由后端服务器指定(不一定是
404):

server {
    ...
    location  {
        # 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 ,当发生 file not found
错误时,做一个内部的重定向。$uri 变量的值为当前请求的
URI,在重定向中被转发给了后端服务器。

例如,如果 some/file 未找到,它被替换为
/fetchsome/file,对这个新 URI,nginx 会查找与其匹配的
location,这里就是 location /fetch/,然后就被转发给后端服务器了。
(可参考
反向代理)

当发送 file not found
错误时,open_file_cache_errors
指令在这里用于防止记录错误日志。因为请求已经被转发给后端,所以不应该记录错误日志。


版权信息
*本文编译自
nginx.com