将NGINX配置为Web服务器


    在较高的层次上,将NGINX配置为web服务器需要定义它处理哪些url以及如何处理这些url上的HTTP资源请求。在较低的级别上,NGINX配置定义了一组虚拟服务器,用于控制对特定域或IP地址的请求的处理。
    每个HTTP虚拟服务器都定义了多个名为location的特殊配置实例,用于控制URI的处理。每个location都定义了当请求被映射到该location时的方案。每个location都可以代理请求或返回相应文件。此外,可以修改URI,以便将请求重定向到另一个location或虚拟服务器。此外,还可以返回特定的错误代码,并且可以根据每个错误代码配置特定页面。

1. 设置虚拟服务器

    NGINX配置文件至少需要一个server指令,用于定义一个虚拟服务器。当NGINX处理请求时,它首先选择处理请求的虚拟服务器。
    一个虚拟服务器由http上下文中的server指令来定义,例如:

http {
    server {
        # Server configuration
    }
}

    可以在http上下文中添加多个server指令来定义多个虚拟服务器。
    server配置块通常包含一个listen指令,用于指定侦听请求的服务器IP地址和端口。接受IPv4和IPv6地址。IPv6地址需要括在方括号中。
    下面的示例显示侦听IP地址127.0.0.1和端口8080的服务器配置:

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

    如果省略端口,则使用标准端口。同样,如果省略地址,服务器将侦听所有地址。如果根本不包括listen指令,标准端口是80/tcp,这取决于超级用户权限。
    如果有多个服务器与请求的IP地址和端口匹配,nginx将请求报文的host头部与server块的server_name指令进行比对。server_name参数可以是一个完整的名称,通配符或者正则表达式。通配符是一种字符串,可以在开始,结尾或两者包含星号(*)。星号匹配任何字符序列。nginx使用perl语法的正则表达式,在它们前面加上波形号(~)。示例列举了一个准确的名字:

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

    如果多个名称匹配请求的host报头,nginx将按以下顺序搜索名称并使用找到的第一个匹配项:

  • 准确名称
  • 以星号开头的最长通配符,如*.example.org
  • 以星号结尾的最长通配符,如mail*
  • 第一个匹配的正则表达式(按在配置文件中出现的顺序)

    如果host头与任何服务器名称都不匹配,nginx将请求路由到请求到达端口的默认服务器。一般默认服务器是nginx.conf文件中列出的第一个,除非你使用listen指令的default_server参数明确指定一台服务器作为默认服务器。

server {
    listen 80 default_server;
    #...
}

2. 配置locations

    NGNX可以基于请求URI向不同代理发送业务或提供不同的文件。这些块由server指令中的location指令定义。
    例如,你能定义3个location块指导虚拟服务器将一部分请求发送到一台代理服务器,其他请求发送到另一台不同的代理服务器,通过本地文件系统提供文件来处理剩下的请求。
    NGINX比较着请求的URI和所有location指令的参数,并应用匹配location中的指令。在每个location块,通常可以(除了少数例外)放置更多的location指令来进一步完善对特定请求组的处理。
    location指令有两种类型的参数:前缀字符串(代表路径名)和正则表达式。要使请求URI与前缀字符串匹配,它必须以前缀字符串开头。
    下面的location示例带有匹配请求URI的路径名参数,该示例以 /some/path/ 开始,例如 /some/path/document.html。

location /some/path/ {
    #...
}

    对于区分大小写的匹配,正则表达式前面是波形号 ~ ,对于不区分大小写的匹配,前面是波形号加星号 ~* 。下面的示例匹配在任何位置包含string.html或.htm的URI(正则表达式?表示匹配前面的字母 l 零次或一次):

location ~ \.html? {
    #...
}

3. NGINX Location优先级

    为了找到最匹配URI的location,NGINX首先将URI与location的前缀字符串对比。然后查找带正则表达式的location。
    除非使用^~修饰符,否则正则表达式将具有更高的优先级。在前缀字符串中,NGINX选择最具体的那个(最长,最完整的字符串)。选择location的具体过程如下:

  • 将接收到的URI与所有前缀字符串逐一匹配;
  • = 意味着URI与前缀字符串完全匹配。如果出现完全匹配,停止继续搜索;
  • 如果 ^~ 修饰符在最长的匹配前缀字符串前面,则不检查正则表达式;
  • 存储最长的匹配前缀字符串;
  • 将URI与正则表达式进行匹配;
  • 中断第一个匹配的正则表达式并使用相应的location;
  • 如果没有正则表达式匹配,使用与存储的前缀字符串对应的location。

    = > ^~ >正则表达式 > 前缀字符串
     = 修饰符的典型应用是用于 / 的请求。如果 / 的请求很频繁,在location指令中明确 =/ 的参数可以加速处理,因为匹配的搜索在第一次比较后就会停止。

 location = / {
    #...
}

    location上下文可以包含如何处理请求的指令,这些指令类似:提供一个静态文件或者将请求发往代理服务器。在下面的示例中,匹配第一个location上下文的请求会接收到/data文件夹提供的文件,匹配第二个location的请求会被转发到 www.example.com 的代理服务器。

server {
    location /images/ {
        root /data;
    }

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

    root指令提供了查找相关静态文件的系统路径。与该location关联的请求URI被附加到路径中,以获取要提供的静态文件的全名。在上面的示例中,针对请求 /images/example.png,nginx提供文件/data/images/example.png。
    proxy_pass指令将请求传递到配置了URL访问的代理服务器。来自代理服务器的响应被传递给客户端。在上面的示例中,所有不以/images/开头的请求都被传递给了代理服务器。

4. 使用变量

    你可以在配置文件中使用变量,通过定义环境,使nginx处理请求有所不同。变量在计算时被临时赋值,也被用作指令的参数。变量名称的开头用 \ 符号表示。变量根据NGINX的状态定义信息,例如当前正在处理的请求的属性。
    有一些预定义的变量,例如$server_name这种核心HTTP变量。你可以使用set,map,geo指令来定义用户变量。大多数变量是在运行时计算的,并且包含与特定请求有关的信息。例如, $remote_addr包含客户端IP地址, $uri 包含当前URI值。

5. 返回特定状态码

    某些网站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上下文中。

6. 重写请求中的URI

    通过使用rewrite指令,可以在请求处理期间多次修改请求URI。rewrite指令具有一个可选参数和两个必需参数。第一个必需的参数是匹配请求URI的正则表达式,第二个参数是用于替换的URI。可选的第三个参数是一个标志,它可以停止rewrite指令的进一步处理或者发送一个重定向(301或302码)。例如:

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

    如上例所示,第二个参数users通过正则表达式获得。
    你可以在server和location上下文中使用多个rewrite指令。NGINX会按指令出现顺序依次执行。当上下文被选中后,server上下文中的rewrite指令会被执行一次。
    NGINX处理了一组重写指令后,它会按照新URI选择location上下文。如果选中的location包含rewrite指令,就依次执行。如果URI与任何一个都匹配,在所有已定义的rewrite指令被执行之后,将搜索新location。
    以下示例显示了与return指令结合使用的rewrite指令:

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。由于last标志,随后的rewrite,return指令被忽略,但是NGINX继续处理不同URI的请求。类似的,URI /download/some/audio/file 被替换成 /download/some/mp3/file.ra。如果URI不满足任何一个rewrite指令,NGINX会向客户端返回403错误码。
    有两个参数可以中断rewrite指令的进程:

  • last 停止执行当前server或location上下文中的rewrite指令,但是NGINX查找匹配重写的URI的location,并应用新location中的rewrite指令。(意味着URI能够再次被改变)
  • break 类似break指令,停止当前上下文中的rewrite指令进程,取消查找匹配新URI的location。新location中的rewrite指令不会被执行。

7. 重写HTTP响应

    有时,您需要重写或更改HTTP响应中的内容,用一个字符串替换为另一个字符串。您可以使用sub_filter指令定义要应用的重写。该指令支持变量和替换链,从而使更复杂的更改成为可能。
    例如,可以更改绝对链接,该链接引用代理以外的服务器:

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

虚拟主机配置文件如下:

server {
    listen 80;
    root /www ;
    location / {
         sub_filter      /blog/ /blog-staging/;
    }
}

默认首页如下:

# cat /www/index.html 
<html>
/blog/ <br>
/blog-staging/
</html>

浏览器访问结果:
在这里插入图片描述
    另一个示例将 http:// 方法更改为 https:// 并将localhost地址替换为请求报文头的主机名。sub_filter_once 指令告诉NGINX在一个location内连续使用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也不会再次被修改了。

8. 处理错误

    使用error_page指令,您可以配置NGINX以返回自定义页面以及错误代码,在响应中替换不同的错误代码,或者将浏览器重定向到其他URI。在以下示例中,error_page指令指定要返回的页面(/404.html),并附带404错误代码。

error_page 404 /404.html;

    请注意,此指令并不意味着立即返回错误(return指令这样做),而只是指定错误发生时的处理方式。错误代码可能来自代理服务器,也可能是在NGINX处理期间发生的(例如,NGINX无法找到客户端请求的文件时返回404)。
    在下面示例中,当NGINX找不到页面,它将代码404替换为301,并重定向客户端到http:/example.com/new/path.html。当客户端仍尝试使用其旧URI访问页面时,此配置很有用。301代码通知浏览器该页面已永久移动,并且在返回时自动用新地址替换旧地址。

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

    下面的配置示例表示当文件找不到时,将请求传递给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/;
    }
}

    error_page指令告知NGINX,当文件找不到时,进行一次内部重定向。error_page指令最后参数中的 $uri 变量保存当前请求的URI,并将其传递给重定向。
    例如,如果 /images/some/file 没有找到,就会被替换为 /fetch/images/some/file 并开始搜索相关location。最后,请求在第二个location上下文结束,并被代理到http://backend/。
    如果文件找不到,open_file_cache_errors指令可以防止写入错误消息。这里没有必要这样做,因为丢失的文件已经被正确处理了。

参考文档

https://docs.nginx.com/nginx/admin-guide/web-server/web-server/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值