• nginx笔记(三)


    配置web服务器

    设置虚拟服务器:

          http语境内,定义server指令为一个虚拟服务器。当然也可以添加多个server指令到http语境中。

    server配置块一般包含listen指令指示IP地址和端口。也接受IPV6,IPV6包含在方括号中。

    server {
        listen 127.0.0.1:8080;
        # Additional server configuration
    }

         如果端口忽略,则使用标准端口。如果地址忽略,则侦听所有地址。如果listen指令不写,则标准端口 80/tcp或默认商品8000/tcp,取决于superuser权限。

        如果有若干服务器匹配IP地址和端口,nginx会使用server块中的server_name指令,自动匹配请求中的host信息头。server_name参数可以是确切的全名称,通配符或正则表达式。

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

        如果有若干个名称匹配Host信息头,则nginx按以下顺序获取最先匹配的名字:

        (1)确切的名称;

         (2)最长的通配符字串,以*号开头(*符号匹配所有任何字符),例:*.example.org;

         (3)最长的通配符字串,以*号结尾,例:mail.*;

          (4)首先匹配的Perl语法的正则表达式,前置有~波浪符号。

       如果Host信息头不匹配server名称,则nginx将其转到默认服务器,默认服务器设置在nginx.conf文件中。

    server {
        listen 80 default_server;
        #...
    }

    配置URI文件夹:

        nginx可通过在server指令内定义location指令将流量转发到不同的位置。每个location指令块内还可以定义更多location指令,以进一步特定请求。

        location指令有两种参数:前缀字符串(路径名)或正则表达式。

        以下示例 /some/path/ 的前缀路径匹配以此路径开头的URL,比如:/some/path/document.html。

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

      正则表达式:

      正则表达式的前面有波浪号(〜),用于区分大小写的匹配;或波浪号(〜*)用于不区分大小写的匹配。

      Location指令匹配的优先级:

      为寻找URI最佳匹配,nginx会先用字符串前缀比较URI location。然后用正则表达式搜索这些位置。

      除了使用^~修饰符,其他的正则表达式会有更高优先级。通过字符串前缀nginx会选择最具体的字符串(即最长和最完整的字符串)。

      下面是处理请求location的确切逻辑:

       1、针对所有前缀字符串测试URI;

       2、=(等号)修饰符定义URI和前缀字符串的精确匹配。如果找到完全匹配的内容,搜索将停止。

       3、如果^〜(脱字符号)修饰符加上最长的匹配前缀字符串,则不检查正则表达式。

       4、存储最长的匹配前缀字符串;

       5、针对正则表达式测试URI;

       6、找到第一个匹配的正则表达式后停止处理,并使用相应的位置;

       7、如果没有正则表达式匹配,则使用已保存的前缀字符串相对应的位置。

       =号修饰符最典型用法就是对 / 的请求,如果对 / 的请求很频繁,则使用 =/ 可以加快搜索速度。

    location = / {
        #...
    }

       location指令上下文内包含了如何处理请求的方法。如下例:

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

       root指令:指定要搜索的静态文件的系统路径;

       proxy_pass指令:将请求转给被代理服务器处理,并将响应结果再返回给客户端。

    使用变量:

    变量以$符号开头。

    nginx有许多预定义的变量,参考:https://nginx.org/en/docs/http/ngx_http_core_module.html?&_ga=2.160412349.1274850824.1587864344-45792041.1587182428#variables

    也可自定义变量,使用set,map和geo指令。

    返回具体的状态码:

    有些URI需要立即返回返回特定的诸如错误或跳转码,比如临时或永久性转移,最简单方法 就是使用 return 指令:

    location /wrong/url {
        return 404;
    }

    return 指令的第一个参数是状态码;第二参数为可选值,比如要跳转的URL或者响应的主体文字;

    return指令可以出现在location和server上下文中。

    重写请求URI:

    通过 rewrite指令,可以重写请求URI。

    rewrite指令的第一参数为正则表达式用于匹配URI,第二参数为替换后的URI,第三参数为可选值,可用于停止后面的rewrite指令的处理或重定向。

    在server和location上下文中可以包含多个rewrite指令。nginx按指令的出现顺序一一执行。

    当nginx处理了一级重写指令后,它会通过用新URI来选择location。如果这个被选择的location又包含rewrite指令,这些指令又会依次执行。如果URI匹配任何一个,则会在处理所有定义 的重写指令后再次开始对新location进行搜索。

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

    以上例说明:当URI诸如是  /download/some/media/file , 则会重写成 /download/some/mp3/file.mp3 , 因为 last 标记的原因 ,后续的指令(第二个rewrite和return指令)则会忽略 。同样,URI比如说是 /download/some/audio/file 会被替换成 /download/some/mp3/file.ra。如果URI都不匹配rewrite指令,则Nginx返回 403错误码。

       rewrite指令有两种标记会打断往下执行:

       last -- 停止在当前 server 或 location 上下文中执行重写指令,但是nginx搜索与重写的URI匹配的location,并应用新 location 中的所有 rewrite 指令(这意味着可以再次更改URI)。

      break -- 停止在当前 server 或 location 上下文中执行重写指令,并取消对新 URI的新一轮 location 搜索。

    重写HTTP响应:

    有时候你需要重写或改变http响应内容,则可以使用 sub_filter 指令。 该指令支持变量和一系列的替代,可以做出更复杂的变更。

    以下例子,/blog/ 绝对链接变更为 /blog-staging/。

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

    下例中,http:// 变成 https://, 并将 localhost 地址变成 hostname主机名。 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修改的响应部分不会再次替换。

    错误处理:

        error_page 指令能配置 nginx 返回自定义页面,并替换成不同的状态码给客户端响应。

    error_page 404 /404.html;

       注意,此指令不会立即返回错误,而是指明错误发生时的处理方式。错误代码可能来自被代理的服务器也可能是nginx处理期间发生 。

       以下例子,当nginx找不到页面,则用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/ {
            # 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在找不到文件时进行内部重定向。

       例如,如果未找到 /images/some/file,则将其替换为 /fetch/images/some/file,并开始对位置的新搜索。结果,请求在第二个location上下文中结束,并被到 http://backend/

    open_file_cache_errors如果找不到文件,伪指令可防止写入错误消息。

    提供静态内容

    根目录和索引文件:

    root指令能指明要搜索文件的根目录。为了获取请求文件的路径,nginx根据请求URI路径附加到root指令指定的路径。

    该指令可以放在http,server 或 location 上下文。在下例中,root指令用于定义server主机,它应用到了所有未重定义root指令的location块当中:

    server {
        root /www/data;
    
        location / {
        }
    
        location /images/ {
        }
    
        location ~ .(mp3|mp4) {
            root /www/media;
        }
    }

    上例中,nginx搜索用/images/ 开始在系统的 /www/data/images 文件夹中搜索。但是如果URI以 .mp3 或 .mp4 扩展名结尾,则以 /www/media 目录搜索,因为它在匹配的location中重定义了root。

    如果请求以斜杠结尾,NGINX会将其视为对目录的请求,并尝试在目录中查找索引文件。index指令用于定义索引文件名(默认值:index.html )。

       为了返回索引文件,NGINX检查其是否存在,然后对通过将索引文件的名称附加到基本URI所获得的URI进行内部重定向:

    location / {
        root /data;
        index index.html index.php;
    }
    
    location ~ .php {
        fastcgi_pass localhost:8000;
        #...
    }

       按上例,如果URI请求是 /path,而 /data/path/index.html不存在,但/data/path/index.php存在。于是内部跳转到第二个location中处理,最后请求被代理。

    若干选项:

         try_files指令:用于检查指定文件或目录是否存在,不存在则转到指定的状态码或路径。

    location / {
        try_files $uri $uri/ $uri.html =404;
    }

    上例当找不到$uri变量对应的目录或文件时,则返回404错误码。

    location / {
        try_files $uri $uri/ @backend;
    }
    
    location @backend {
        proxy_pass http://backend.example.com;
    }

    上例当找不到$uri文件或目录时,转到第二个location,然后反向代理给backend.example.com。

    内容提供方面的性能优化:

    (1)开启sendfile:

    默认情况下,nginx在传输文件前会先前文件复制到缓存。而开启sendfile指令,则跳过步骤直接复制文件给另一端。另外,为防止一个快速连接完全占用工作进程,可以使用 sendfile_max_chunk 指令限制单个sendfile函数传输的数据量。如下例:

    location /mp3 {
        sendfile           on;
        sendfile_max_chunk 1m;
        #...
    }

    (2)开启tcp_nopush:

    使用tcp_nopush指令与sendfile指令一起,这使 NGINX 在 sendfile() 获得数据块之后立即在一个数据包中发送HTTP响应头。

    (3)开启tcp_nodelay:

    tcp_nodelay指令的开启能允许覆盖Nagle算法。此算法原来是用于解决在低速网络下传输问题,它将多个小数据包合并一个较大的数据包,发送时会有200ms的延迟。如今,在处理大型静态文件时,无论数据包大小如何,都可以立即发送数据。延迟还会影响在线应用程序(SSH,在线游戏,在线交易等)。

    默认情况下,tcp_nodelay指令设置为on,这表示Nagle的算法已禁用。仅对保持连接使用此伪指令。

    location /mp3  {
        tcp_nodelay       on;
        keepalive_timeout 65;
        #...
    }

    (4)优化积压队列

    通常情况下,当建立连接后,会将其放入侦听套接字的“侦听”队列中。在正常负载下,队列很小或根本没有队列。但是在高负载下,队列会急剧增长,从而导致性能不均匀,连接断开和延迟增加。

    查询侦听队列,使用此命令:

    netstat -Lan

    输出可能类似于以下内容,它显示端口80上的侦听队列中有10个未接受的连接,而已配置的最大128个排队的连接。这种情况是正常的:

    Current listen queue sizes (qlen/incqlen/maxqlen)
    Listen         Local Address         
    0/0/128        *.12345            
    10/0/128        *.80       
    0/0/128        *.8080

    相反,在以下命令中,不可接受的连接数(192)超过了限制128。当网站遇到大量流量时,这是很常见的。

    Current listen queue sizes (qlen/incqlen/maxqlen)
    Listen         Local Address         
    0/0/128        *.12345            
    192/0/128        *.80       
    0/0/128        *.8080

    为了获得最佳性能,您需要增加操作系统和NGINX配置中排队等待NGINX接受的最大连接数。

    操作系统的调优:

    将net.core.somaxconn内核参数的值从其默认值(128)增加到足够大的值以应对大量流量。在此示例中,此值增加到4096。

    sudo sysctl -w net.core.somaxconn=4096

    编辑添加以下行到 /etc/sysctl.conf文件:

    net.core.somaxconn = 4096

    Nginx调优:

    如果将somaxconn内核参数设置为大于512的值,请将backlog参数更改为NGINX listen指令以匹配:

    server {
        listen 80 backlog=4096;
        # ...
    }

    反向代理

    当NGINX代理请求时,它将请求发送到指定的代理服务器,获取响应,然后将其发送回客户端。可以使用指定协议将请求代理到HTTP服务器(另一个NGINX服务器或任何其他服务器)或非HTTP服务器(可以运行使用特定框架开发的应用程序,例如PHP或Python)。支持的协议包括FastCGI,uwsgi,SCGI和memcached。

    为了将请求传递到HTTP代理服务器,必须在一个位置内指定proxy_pass指令:

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

    要将请求传递到非HTTP代理服务器,应使用适当的** _ pass指令:

    fastcgi_pass:将请求传递给FastCGI服务器uwsgi_pass:将请求传递给uwsgi服务器scgi_pass:将请求传递到SCGI服务器memcached_pa​​ss:将请求传递到memcached服务器

    传递请求标头:

    默认情况下,NGINX在代理请求中重新定义两个标头字段“ Host”和“ Connection”,并消除其值为空字符串的标头字段。“Host”设置为 $proxy_host 变量,“Connection”设置为 close。

    要更改这些设置以及修改其他标题字段,请使用proxy_set_header指令。可以在一个位置或更高位置指定此伪指令。也可以在server上下文或http块中指定它。

    location /some/path/ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://localhost:8000;
    }

    上例中,Host值设置为 $host 变量;

    为了防止将标头字段传递给代理服务器,请按以下步骤将其设置为空字符串:

    location /some/path/ {
        proxy_set_header Accept-Encoding "";
        proxy_pass http://localhost:8000;
    }

    配置缓存:

    默认情况下,NGINX缓冲响应来源于被代理的服务器。响应存储在内部缓冲区中,直到接收到整个响应后才发送给客户端。缓冲有助于优化慢速客户端的性能,如果响应从NGINX同步传递到客户端,则这可能会浪费被代理服务器的时间。但是,启用缓冲后,NGINX允许被代理服务器快速处理响应,而NGINX将响应存储的时间与客户端下载响应所需的时间一样长。

    负责启用和禁用缓冲的指令是proxy_buffering。默认情况下,它设置为on并且启用了缓冲。

    proxy_buffers指令控制为请求分配的缓冲区的大小和数量。来自被代理服务器响应的第一部分存储在单独的缓冲区中,缓冲区的大小由proxy_buffer_size指令设置。这部分通常包含一个相对较小的响应头,并且可以使其小于其余响应的缓冲区。

    在以下示例中,增加了默认缓冲区数,并使响应第一部分的缓冲区大小小于默认值。

    location /some/path/ {
        proxy_buffers 16 4k;
        proxy_buffer_size 2k;
        proxy_pass http://localhost:8000;
    }

    如果禁用了缓冲,则响应将从客户端服务器接收到的响应同步发送到客户端。对于需要尽快开始接收响应的快速交互客户端,此行为可能是理想的。

    location /some/path/ {
        proxy_buffering off;
        proxy_pass http://localhost:8000;
    }

    压缩与解压缩

    压缩响应通常会大大减少传输数据的大小,由于压缩是在运行时发生的,因此也会增加相当大的处理开销。NGINX在将响应发送到客户端之前执行压缩,但不会“双重压缩”已压缩的响应(例如,由被代理服务器进行的响应)。

    开启压缩:

    gzip on;

    默认情况下,NGINX仅压缩MIME类型为 text/html 的响应。要压缩其他MIME类型的响应,请包含gzip_types指令并列出其他类型。

    gzip_types text/plain application/xml;

    要指定要压缩的响应的最小长度,请使用gzip_min_length指令。默认值为20字节(此处调整为1000):

    gzip_min_length 1000;

    默认情况下,NGINX不压缩对代理请求的响应(来自代理服务器的请求)。请求来自代理服务器的事实取决于请求中是否存在Via标头字段。要配置这些响应的压缩,请使用gzip_proxied指令。该指令用于指定NGINX应该压缩哪些代理请求。例如,合理的做法是仅压缩对不会缓存在代理服务器上的请求的响应。为此,gzip_proxied指令具有参数,这些参数指示NGINX检查响应中的Cache-Control标头字段,并在该值是no-cache,no-store或private时压缩响应。此外,您必须包括expired参数才能检查Expires标头字段的值。在以下示例中,将与auth参数一起设置这些参数,该参数将检查Authorization标头字段的存在(授权响应特定于最终用户,并且通常不缓存):

    gzip_proxied no-cache no-store private expired auth;

    与大多数其他指令一样,配置压缩的指令可以包含在 http 上下文中或 server 或 location 配置块中。

    gzip压缩的整体配置可能如下所示:

    server {
        gzip on;
        gzip_types      text/plain application/xml;
        gzip_proxied    no-cache no-store private expired auth;
        gzip_min_length 1000;
        ...
    }

    开启解压缩:

    某些客户端不支持使用gzip编码方法的响应。同时,可能希望存储压缩的数据,或者动态压缩响应并将其存储在缓存中。为了成功服务于接受和不接受压缩数据的两个客户端,NGINX可以在将数据发给后者时,即刻对数据进行解压缩。

    gunzip on;

    gunzip指令可以和gzip指令在同一上下文中设置:

    server {
        gzip on;
        gzip_min_length 1000;
        gunzip on;
        ...
    }

    请注意,此指令是在单独的模块中定义的,默认情况下可能未包含在NGINX开源构建中。

    传输压缩文件:

    要将文件的压缩版本而不是常规文件发送到客户端,请在适当的上下文中将gzip_static指令设置为on。

    location / {
        gzip_static on;
    }

    在这种情况下,为了满足对 /pathto/file 的请求,NGINX尝试查找并发送文件 /path/to/file.gz 。如果该文件不存在,或者客户端不支持gzip,则NGINX发送该文件的未压缩版本。

    请注意,gzip_static指令不启用即时压缩。它仅使用任何压缩工具预先压缩的文件。要在运行时压缩内容(不仅是静态内容),请使用gzip指令。

  • 相关阅读:
    C# 模式&模式匹配
    CentOS7下安装 dotnet sdk
    PLSQL 设置
    Visual Studio Code 开发 .NetCore 插件列表
    .net core 服务生命周期
    从 Asp.Net Core 2.2 迁移到 3.0 的方案
    CSRedisCore 介绍
    Entity Framework 命令
    DataAnnotations 模型配置
    依赖注入学习(理论)
  • 原文地址:https://www.cnblogs.com/xiwang6428/p/12780555.html
Copyright © 2020-2023  润新知