NGINX Web Server Nginx web 服务器

原文地址:http://nginx.com/resources/admin-guide/web-server/

NGINX Web Server

Nginx web 服务器


This section describes:

  • the most common configuration of a web server
  • how to set up virtual servers and define locations for request processing
  • how to use variables
  • how to return specific status codes
  • how to rewrite the URI of a request
  • how to configure HTTP error pages

本章讨论:

  • 最常用的 web 服务器的配置
  • 如何搭建虚拟主机以及定义请求过程的位置
  • 如何使用变量
  • 如何设定返回状态码
  • 如何重写一个请求的URL
  • 如何配置HTTP错误页

Overall, the configuration of NGINX as a web server is a matter of defining which URLs it can process and how it processes them. On a lower level, the configuration consists of a set of virtual servers that are responsible for processing requests for particular domains or IP addresses.

Each virtual server defines special configuration instances called locations that control processing of specific sets of URIs. Each location defines its own scenario of what happens to requests that are mapped to this location. NGINX provides full control over this process. Each location can proxy the request or return a file. In addition, the URI can be modified, so that the request is redirected to another location or virtual server. Also, a specific error code can be returned and you can configure a specific page to corresponds to each error code.

总的来说,Nginx 作为一个Web服务器的配置差不多就是定义哪些URL能处理和如何处理。底层点说,这个配置由一组负责处理特定域名或者IP地址的请求的虚拟服务器。

每一个虚拟服务器定义了一个称为locations的特有的配置实例来控制能处理的指定的URL。每一个location定义了对映射到本location的URL处理方式。Nginx通过这个过程提供全局控制。每个location能代理这个请求或者返回一个文件。另外,这个URL还可以被修改,把这个请求重定向到别的location或者虚拟服务器。同样,可以返回特定的错误码,并且你可以为每一个错误码配置一个相应的页面。

Configuration File

配置文件

Configuring NGINX is similar to other services in that it has a text-based configuration file written in a particular format. By default this file is named nginx.conf. The location of your nginx.conf depends on the package system used to install NGINX and the operating system. Typically, it is one of /usr/local/nginx/conf/etc/nginx, or /usr/local/etc/nginx directories.

配置Nginx类似于其他的服务,它有一个基于文本的有着特殊格式的配置文件。默认情况下这个文件名为nginx.conf。你的nginx.conf的位置取决于安装Nginx使用的包管理系统和操作系统。通常在/usr/local/nginx/conf, /etc/nginx 或者 /usr/local/etc/nginx 其中一个目录中。

The configuration file is created using directives and parameters. Each directive ends with a semicolon. You may also add additional instructions within 大braces. Below are some examples.

配置文件是使用指令和参数来创建的。每个指令以分号结束。也可以在括号内添加其他说明,看下面示例:

user             nobody;
error_log        logs/error.log notice;
worker_processes 1;

Using include, you can also split configuration into a hierarchy of files, including file contents:

使用include,可以把配置分散到不同层级的文件中,包含文件内容:

include mime.types;

There are a few special directives referred to as contexts. These contexts are eventshttp,server, and location.

有几个特殊的指令被称为上下文环境,这些上下文环境有 eventshttp,server, 和 location.。

Any directives placed outside of the contexts are considered to be in the main context. The example below shows a full configuration file using contexts.


任务一个在上下文环境之外的指令被当作主环境。下面这个例子采用上下文环境展示了一个完事的配置文件。

user nobody; # a directive in the 'main' context

events {
    # configuration of events
}

http {

    # Configuration specific to HTTP and affecting all virtual servers

    server {
        # configuration of virtual server 1

        location /one {
            # configuration for processing URIs with '/one'
        }

        location /two {
            # configuration for processing URIs with '/two'
        }
    }

    server {
        # configuration of virtual server 2
    }
}


As you might guess, configuration related to HTTP resides within the http context. The server context configures a specific virtual server within the http context. Finally, the location context is used within the server contect to instruct NGINX to process a particular set of URIs.

你可能会想,跟HTTP有关的配置放在http上下文环境中。server 这个上下文环境在http上下文中配置一个指定的虚拟服务器。最后,location上下文环境在server上下文中用以指导Nginx去处理特定一些的URL。

In most cases, a context that is defined inside another context will inherits its directives. When that happens, and you then declare the the same directive on the current level, the directive on the current level will override the inherited one. For more information on context inheritence see the proxy_set_header documentation.

多数情况下,定义在另一个上下文环境里的上下文将继承所有指令。在这种情况下,如果你在当前层里声明了同样的指令,当前层的指令将会覆盖继承下来的。有关上下文继承更多信息请看:proxy_set_header documentation

For the changes in the configuration file to take effect you have two options. First you can simply restart nginx. Alternatively, you can send the reload signal to upgrade the configuration without interrupting the processing of current requests.

有两种办法可以使配置文件的更改生效。第一种是简单粗暴的重启Nginx。另一种,你可以发送一个重载信号以更新配置而不用打断当前请求处理进程。

Setting Up a Virtual Server

搭建虚拟服务器

To process HTTP requests, your NGINX configuration file should define at least one virtual server. When NGINX processes a request, it will first select the virtual server that will serve the request.

为了处理HTTP请求,你的Nginx配置文的应该定义至少一个虚拟服务器。当Nginx要处理一个请求时,首选虚拟服务器来处理该请求。


Servers are defined using the server directive, which is placed in the http context, for example:

定义服务器使用 server 指令,放在 http 上下文环境中,例如:

http {
    server {
        # Server configuration
    }
}

It is possible to add multiple server directives into the http context to define multiple virtual servers.

在http上下文中可以添加多个server指令来定义多个虚拟服务器;

The server directive should also include a listen directive. This directive specifies the IP address and port (or Unix domain socket and path) which the server will listen. The IP address can be either IPv4 or IPv6. Keep in mind that IPv6 must be specified in the square brackets.

server 指令还应该包含一个 listen 指令。这个指令指定服务器监听的IP地址和端口(或者Unix域套接字和路径)。IP 地址可以是IPv4或IPv6的。记住IPv6必须要使用方括号指定。

The example below shows configuration of a server that listens on the 127.0.0.1 address and8080 port:

下面这个例子配置了一个服务器监听127.0.0.1这个地址和8080端口:

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

If a port is omitted, the standard port will be used. Likewise, if an address is omitted, the server will listen on all addresses. Note that if the listen directive is not specified, the “standard” port is 80/tcp and the “default” port is 8000/tcp, depending on superuser privileges.

如果端口参数省略了,就使标准端口。还有,如果地址省略了,服务器就监听所有地址。注意如果listen 指令没有设置,那么“标准”端口为 80/tcp 和 默认“端口”为 8000/tcp,使用哪个取决于超级管理员权限。

If there are several servers that match the IP address and port of the request, NGINX tests the request’s “Host” header field against the server_name directives of the server blocks. The parameter of this directive can be an exact name, a wildcard, or a regular expression. A wildcard name includes an asterisk that starts or finishes the name and will match any string. A regular expression should be preceded with a tilde (~). The example below illustrates the case of an exact name.

如果一个请求匹配上多个服务器的IP地址和端口,那么NGINX查找请求头里的“Host”字段来对应server块里的server_name 指令。这个指令的参数可以是一个确切的名字,一个通配符或者一个正则表达式。一个在开头或者结尾包含星号的通配符名字能匹配任何字符串。一个正则需要以波浪号(~)开头。下面举了一个使用精确名称的例子:

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

If several names match the “Host” header, NGINX selects one, trying the names in the following order:

如果多个名称匹配上“Host”头。Nginx使用下列的顺序选择一个:

  1. Exact name. 
  2. Longest wildcard name starting with an asterisk, such as *.example.org.
  3. Longest wildcard name ending with an asterisk, such as mail.*.
  4. First matching regular expression (in order of appearance in the configuration file).
  1. 精确匹配
  2. 以星号开头的最长的通配符名字,例如:*.example.org
  3. 以星号结束的最长的通配符名字,例如:mail.*。
  4. 第一个匹配上正则表达式的(以配置文件里的位置为顺序)。

If the “Host” header field does not match a server name, NGINX will route the request to the default server for this port. The default server is the first one listed in the nginx.conf file. This will be overridden if the default_server parameter is set in the listen directive within a server context. An example is given below.


如果“Host”头字段匹配不上任何一个主机名,Nginx将把这个请求路由到该端口的默认主机。默认主机是nginx.conf文件里的第一个。如果某个主机上下文里的listen指令后跟了default_server参数,那么这个默认主机将被覆盖。实例如下:

server {
    listen      80 default_server;
    …
}

Configuring Locations

配置位置

One aspect NGINX includes in the virtual server configuration is the ability to send traffic to different proxies or serve different files based on the request URIs. These blocks are defined using the location directive placed within a server directive.

Nginx虚拟主机配置里的其中一个牛逼之处在于根据请求URLs把流量分发到不同的代理或主机。这些功能的组件在server指令中的location指令里定义。

For example, you can configure the virtual server to send a portion of requests to a proxied server, send another portion to a different proxied server, and serve the rest with files from the local file system. To accommodate this you configure the virtual server to define three location blocks, one for each case.

例如,你可以配置虚拟主机把请求的一部分发给一个代理服务器,另一部分发送给另一台代理服务器,剩下的通过本地文件系统的文件来处理。要实现这些功能,你需要在虚拟主机里定义三个location组件,每部分一个。

NGINX tests request URIs against the parameters of all location directives and applies the directives that reside within the selected location. Inside each location block, it is usually possible (with a few exceptions) to place even more location directives to further split the configuration into parts that are relevant to specific groups of requests.

Nginx针对所有location指令里的参数来检测请求URL,应用选中的location中的所有指令。在每个location组件中, 通常(也有例外)会放置更多的location指令进一步把配置根据特定的请求群组分成几个部分。

NOTE: In this guide, the word “location” refers to a single location directive and its context.

The parameter of the location directive can be a prefix string or a regular expression. A URI should start with a prefix string in order to match it.

注意:在这篇指南中,”location” 这个词指一个单独的location指令和他的上下文环境。location 指令的参数可以是一个前缀字符串也可以是一个正则表达式。一个URI应该从一个前缀字符串开始匹配。

Below is an example of a location with a prefix string parameter. It will match requests such as/some/path/document.html.


下面是一个以前缀字符串为参数的location,它将匹配如/some/path/document.html 这样的请求。

location /some/path/ {
    …
}

A regular expression is preceded with a tilde (~). In the following example the location which includes a regular expression in the parameter matches URIs that include “.html” or “.htm”.

一个正则表达式是以波浪号(~)开始的,下面这包含了正则表达式的参数的location实例将匹配包含”.html”或者”.htm”的URI。

location ~ \.html? {
#译者注:此处几个意思,应该是 ~\.htm? 才对吧
    …
}

Higher priority is given to regular expressions, unless the “^~” modifier is used. Among the prefix strings NGINX selects the most specific one (that is, the longest and most complete string). The exact logic for selecting a location to process a request is given below:

正则表达式的优先级更高,除非使用了”^~”修饰符。在前缀字符串里Nginx选择最具体的(即匹配最长和最多的字符串)。选择location来处理请求的确切逻辑如下:

  1. Test the URI against all prefix strings.
  2. The “=” modifier defines an exact match of the URI and a prefix string. If the exact match is found, the search stops.
  3. If the “^~” modifier prepends the longest matching prefix string, the regular expressions are not checked.
  4. Store the longest matching prefix string.
  5. Start testing the URI against regular expressions.
  6. Break on the first matching regular expression and use the corresponding location.
  7. If no regular expression matches, use the location corresponding to the stored prefix string.
  1. 针对所有前缀匹配字符串检测URL
  2. “=“修饰符定义了一个URL的精确匹配的一个前缀字符串,如果找到精确匹配,搜索停止。
  3. 如果最长匹配前缀串的前面有”^~",那这个正则表达式就不检测。
  4. 保存最长匹配前缀串。
  5. 开始针对正则表达式检测URL。
  6. 在第一个匹配的正则表达式处退出搜索,并且使用这个location。
  7. 如果没有正则匹配上,那么就使用已存储的前缀串指向的location。

A typical example of using the “=” modifier is with the usage of “/”. If the “/” request needs to be served often, specifying the location parameter as “= /” will speed up processing of these requests. As noted above, this is due to the search being stopped after the first comparison.

一个典型的”=“修饰符的使用是和”/“一起使用的。如果”/“请求经常被访问,那么设location的参数为”=/“能加快处理这些请求的速度。如前面所提到的,这是因为搜索在第一次比较之后就停止了。

location = / {
    ...
}


A location can contain directives that allow you to define how to resolve a request—serve a static file or pass the request to a proxy. In the following example a virtual server has two locations showing each resolution.

location 里的指令可以定义如果处理一个请求——提供一个静态文件还是把请求传递给一个代理。下面这个实例中虚拟主机有两个location分别实现这两种方案。

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

    location /images/ {
        root /data;
    }
}


The proxy_pass directive passes the request to the proxied server located at the URL you supply. The response from the proxied server will then be passed back to the client. In the example above, all requests with URIs that do not start with “/images/” will be passed to the proxied server.

 proxy_pass 指令把你请求的请求传递给你提供的URL对应的代理服务器。代理服务器处理后的响应又返回给客户端。上例中,所有不以”/images/“开头的URL请求都将传递给代理服务器。

The root directive specifies the file system path in which the static files are located. The request URI associated with the location is then added to the path to obtain the static files. In the example above, in response to the URI “/images/example.png”, NGINX will send the “/data/images/example.png” file.

 root 指令指定静态文件在文件系统中的位置。分配到该location的请求URL被添加到路径后来获取静态文件。上例中,Nginx会把”/data/images/example.png”文件发送到URI"/images/exmple.png”的响应里。

Variables

变量

The nginx.conf file also allow you to set variables. Variables help you create configurations that behave differently depending on defined circumstances. Variables are named values that are calculated at run time and are used in parameters of directives. A variable is denoted by the “$” sign at the beginning of its name. Variables define information based upon nginx’s state, such as the properties of the currently processed request.

nginx.conf文件里也可以设置变量。变量帮你创建根据情况而行为可变的配置。命名过的变量将在运行时计算出值以作指令的参数。变量使用 “$” 符号在其名字前进行标记。变量定义的信息取决于Nginx的状态,例如前面处理的请求的属性。

There are plenty of predefined variables, such as the core HTTP variables, but you can also define custom variables using the setmap, and geo directives. Most variables are computed at run time and contain information related to a specific request. For example, $remote_addr contains the client IP address and $uri holds the current URI value.

有大量如 core HTTP 变量的预定义变量,然而你也可以使用 setmap, 和 geo 指令定义自定义变量。多数变量在运行时计算得出并且包含特定请求的相关信息。例如,$remote_addr 包含了客户端IP地址,还有$uri收保存当前URI的值。

Returning Specific Codes

返回指定状态码

Some website URIs may require immediate return of a response with a specific error or redirect code. An example of this would be if a page has been moved temporarily or permanently. The easiest way to do this is to use the return directive. For example:

有些网站的URL需要直接返回一个带有指定错误码或者重定向码的响应。例如当一个页面被临时或永久删除的时候。实现这个功能最简单的方法就是直接使用  return  指令,例如:

location /wrong/url {
    return 404;
}


The first parameter of return is a response code. Additionally, the directive may have a second parameter set to the URL of a redirect (for codes 301, 302, 303, and 307) or the text to return in the response body. For example:

return  的第一个参数是响应码。另外 ,它也可以使用第二个参数设置为URL或者重定向(对于码301,302.302,和307)或者放在响应体里返回的文本。例如:

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


The return directive can be specified in either location or server context.

return指令在location或server上下文环境里使用。

Rewriting the URI

重写URI

A request URI can be modified multiple times during request processing through the use of the

rewrite. This directive has two required and one optional parameters. The first parameter is a regular expression to test the request URI. The second parameter is the URI to replace the current one if it matches the regular expression. The optional third parameter is a flag that can indicate to stop processing further rewrite directives. For example:

一个请求的URL可以在请求处理过程中使用 rewrite 指令进行多次修改。这个指令有两个必须的参数和一个可选参数。第一个参数是检测请求URI的正则式。第二个参数是用来替换匹配了正则式的URI的。第三个可选参数是一个指示是否停止进程运行其他的重写指令的标志位。

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


As this example shows, the second parameter users captures though matching of regular expressions.

如例所示,第二个参数通过匹配正则工捕捉”users”。

The rewrite directives can be used in both the server and location levels. You can include multiple rewrite directives in the same server or location. The rewrite directives are executed one-by-one in the order of their appearance. The rewrite directives on the virtual server level are executed once when that virtual server is selected.

rewrite指令能同时在server和location层使用。可以在同一个server或location里放多条rewrite指令。rewrite指令根据前面顺序一条一条执行。配置在虚拟主机上的rewrite执行一量虚拟主机被选中就执行。

Once this set of rewriting instruction is processed, a location is selected according to the new URI. Then if a selected location contains rewrite directives, they are executed in turn. If the URI matches any of those, then a search for the new location starts after all defined rewrite directives are processed.

一旦这组重写指令集被执行了,就根据新的URI选择一个location。如果被选中的location包含rewrite指令集,就轮流的执行。如果RUI匹配上其中一个,所有定义的rewrite 指令执行完后就开始搜索新的location。

The following example shows rewrite directives in combination with a return directive.

下述例子展示 了rewrite 指令集与return指令组合使用。

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


This example configuration distinguishes two types of URIs. URIs such as/download/some/media/file are changed to /download/some/mp3/file.mp3. The second rewrite and return are skipped (due to the last flag) but NGINX continues processing the request, which now has a different URI. Similarly, such URIs as /download/some/audio/file are replaced with /download/some/mp3/file.ra. If a URI doesn’t match any of these cases, the return directive comes into action and returns a 403 error code.

上例中,配置了两类可区分的URI,URI如/download/some/media/file被修改为 /download/some/mp3/file.mp3。第二个rewrite指令和return指令会跳过(因为last标志位)但是Nginx会继续处理这个拥有新URI的请求。同样的,URL如/download/some/audio/file则被替换为/download/some/mp3/file.ra。如果一个URI匹配不上任何一个rewrite,那return指令就生效并返回一个403错误码。

There are two parameters that interrupt processing of rewrite directives:

有两个参数能中断rewrite指令集的进程:

  • last stops execution of the rewrite directives in the current virtual server or location, but the search for a location continues. So the rewrite directives in the new location will be executed.
  • last 停止当前虚拟主机或location中的rewrite指令集,但是继续搜索新的location。因此新的location中的rewrite指令集还是会被执行。
  • The break parameter as well as the break directive stop processing of rewrite directives on the current level and stop the search of a location. So the rewrite directives in the new location will not be executed.
  • break参数同 break 指令一样停止当前层的rewrite指令集进程并且停止location的搜索,因此新的location里的rewrite指令集将不会被执行。

Configuring Error Pages

配置错误页

To configure the pages returned for particular error codes, use the error_page directive. This directive allows you to set rules for a particular error code, such as the URI of a page to return as a response for a particular error code. You could also set error code to substitute for another one. In the following example, the error_page directive sets a page to return in case of a 404 error.

要为特定的错误码配置页面,使用error_page 指令。这个指令可以为特定的错误码设置规则,例如对一个特定的错误码返回的页面的URI。你也可以使用一个错误码替换另一个。下例中,error_page 指令为404错误码设置了一个返回页面。

error_page 404 /404.html;

Note that this directive does not mean that the error will be returned immediately (this is what return does), but simply provides settings for treating errors when they occur. The error code can come from a proxied server or appear as a result of processing a request by NGINX (for example, 404 pops up when NGINX can’t find a file requested by the client).

注意这个指令并非意味着这个错误会直接返回(那是return干的事),而只是为处理错误的发生提供配置。这个错误码可能来自一个代理服务器也可能来自Nginx对请求处理的结果(例如,当Nginx找不到客户端所请求的文件的时候弹出404)。

In the following example, if a page is not found, the 301 code replaces the 404 code, and a redirect to a different URL is made.

下面这个例子中,如果一个页面找不到,使用301码替换404,并且重定向到一个制作好的不同的URL。

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


This type of replacement may be useful when a page has a new URI, but clients still try to access it with the old address. The 301 code informs a browser that the page has moved permanently. Setting a 301 code tells the browser to replace the old address with the new one automatically upon return.

这类的替换可能会用在一个页面更新了URI,但是客户端还一直访问旧地址的情况。301码用于通知浏览器一个页面被永久的删除了。在返回时自动设置一个301码告诉浏览器更换旧地址为新地址。

The following configuration is an example of passing a request to the backend when a file is not found. Since the error_page directive below has no status code specified after the equal sign, the response the client gets will have the status code returned by the proxied server (not necessarily 404).

下面这个配置举例当文件找不到的时候把请求发送给backend。因为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/;
    }
}


Note that the parameter set for the error_page directive here includes the $uri variable, which holds the URI of the current request. The open_file_cache_errors directive prevents writing an error message if a file is not found. This is not necessary here since missing files will be correctly handled. Due to the use of the error_page directive NGINX makes an internal redirect if a file is not found. More specifically, the /images/some/file URI is replaced with/fetch/images/some/file and a new search for a location starts. As a result, the request ends up in the second location and is proxied.

注意这里设置的error_page指令的参数包含了$uri这个变量,这个变量保存了当前请求的URI的值。 如果文件找不到,open_file_cache_errors 指令阻止写错误消息。这里没有必要因为丢失的文件能被正确的处理。因为这里使用error_page让Nginx做了一个内部重定向如果文件不存在的话。更具体的说,images/some/fileURI会被替换为/fetch/images/some/file并且对开启一个新的对location的搜索。结果是这个请求在第二个location结束并被代理了。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。