zoukankan      html  css  js  c++  java
  • 学习 NGINX

    At a high level, configuring NGINX Plus as a web server is a matter of defining which URLs it handles and how it processes HTTP requests for resources at those URLs. At a lower level, the configuration defines a set of virtual servers that control the processing of requests for particular domains or IP addresses. 

    NGINX Plus can 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.

    There are two types of parameter to the location directive: prefix strings (pathnames) and regular expressions. 

    URI 匹配逻辑

    regular expressions 比 prefix strings 优先级大。

    测试所有 prefix uris。

    如果匹配上了完全匹配 "=",返回结果。

    If the ^~ (caret-tilde) modifier prepends the longest matching prefix string, the regular expressions are not checked. (没看懂)

    测试完所有 prefix uris 之后,储存最长匹配表达式,进行正则匹配。

    如果正则匹配成功,返回。

    如果没有一个正则匹配,使用之前储存的最长的 prefix uri。

    Directives 继承关系

    For most directives, a context that is defined inside another context (a child context) inherits the values of directives included at the parent level. To override a value inherited from the parent, include the directive in the child context. For more information on context inheritence, see the documentation for the proxy_set_header directive.

    Location 中处理请求

    通过 Location directives 处理请求,比如是提供静态资源,还是转向代理服务器。

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

     使用变量

    使用变量来区分处理不同环境下的请求。比如根据请求的 ip,头部信息等提供不同的服务。

    rewrite

    根据正则表达式重写 uri。

    说下我对 rewrite 的两个参数的理解,不知道对不对。

    • last – Stops execution of the rewrite directives in the current server or location context, but NGINX Plus searches for locations that match the rewritten URI, and any rewrite directives in the new location are applied (meaning the URI can be changed again).
    • break – Like the break directive, stops processing of rewrite directives in the current context and cancels the search for locations that match the new URI. The rewrite directives in the new location are not executed.

    last: 第一个 rewrite 生效后,在当前的 location 或 server 中不再执行 rewrite 了。但是 rewritten uri(经过 rewrite 后的结果)还会从头走一遍 rewirte 的扫描、修改过程。

    break: 相比 last,rewritten uri 不再进入 rewrite 扫描。

    Index file

    To return the index file, NGINX checks for its existence and then makes an internal redirect to the URI obtained by appending the name of the index file to the base URI. The internal redirect results in a new search of a location and can end up in another location as in the following example:

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

    Here, if the URI in a request is /path/, and /data/path/index.html does not exist but /data/path/index.php does, the internal redirect to /path/index.php is mapped to the second location. As a result, the request is proxied.

    访问 /,重定向变成 /index.php。/index.php 再次被 location 中搜索。上面的 rewrite 之后的 uri 也是一样,重新被 location, rewrite 搜索。

    try_files

    The try_files directive can be used to check whether the specified file or directory exists and make an internal redirect, or return a specific status code if they don’t. For example, to check the existence of a file corresponding to the request URI, use the try_files directive and the $uri variable as follows:

    server {
        root /www/data;
    
        location /images/ {
            try_files $uri /images/default.gif;
        }
    }

    The file is specified in the form of the URI, which is processed using the root or alias directives set in the context of the current location or virtual server. In this case, if the file corresponding to the original URI doesn’t exist, NGINX makes an internal redirect to the URI specified in the last parameter, returning /www/data/images/default.gif.


    如果要找的静态文件不存在,返回默认的静态文件。并且状态码是 200 而不是 304,因为这个重定向是内部重定向,客户端并不知情。

    如果默认的静态文件不存在,我本地返回的 500。原因是构成了死循环

    rewrite or internal redirection cycle while internally redirecting to "/images/default.jpg"

    也可以自定义错误码,当 try_files 所有文件都没有找到的时候

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

     reverse proxy

    用途

    负载均衡

    从不同网站获取内容并展示,不太理解

    以非 HTTP 协议传递请求。Supported protocols include FastCGIuwsgiSCGI, and memcached.

    传递请求

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

    This example configuration results in passing all requests processed in this location to the proxied server at the specified address. This address can be specified as a domain name or an IP address. The address may also include a port:

    location ~ .php {
        proxy_pass http://127.0.0.1:8000;
    }

    Note that in the first example above, the address of the proxied server is followed by a URI, /link/. If the URI is specified along with the address, it replaces the part of the request URI that matches the location parameter. For example, here the request with the /some/path/page.html URI will be proxied to http://www.example.com/link/page.html. If the address is specified without a URI, or it is not possible to determine the part of URI to be replaced, the full request URI is passed (possibly, modified).

    什么情况下会传递处理后的 URI,什么情况下会传递完整的 URI 过去?

    代理服务器在同一个 NGINX 中,为什么只有一条记录,代理的不应该也是一条吗?

    本地测试了一下:

    传递处理后的 URI 并补全

    location /images-before-proxy {
        proxy_pass http://localhost:8081/images/;
    }

     传递的是匹配后的地址,访问 http://localhost:8080/images-before-proxy/image_name.jpg --> 匹配到 image_name.jpg --> 将 image_name.jpg 补全到 http://localhost:8081/images/ --> http://localhost:8081/images/image_name.jpg

    传递完整的 URI

    将配置改成

    location /images-before-proxy {
        proxy_pass http://localhost:8081/; # 没有 /images/ 了
    }
    

     访问 http://localhost:8080/images-before-proxy/image_name.jpg --> http://localhost:8081/images-before-proxy/image_name.jpg,返回 404 了。

    访问 http://localhost:8080/images/image_name.jpg --> http://localhost:8081/images/image_name.jpg,返回 200。

    那我现在理解成,只要域名或者 IP 地址跟了后缀,就会传递匹配后的 URI 并补全到 proxied uri 后面。

    传递请求头部

    NGINX 会擦除所有值为空的头部。根据这个特性,你如果不想传递某些头部,就将其设置为空。proxy_set_header Accept-Encoding "";

    设置时可以读取 NGINX 自定义变量

    缓冲区

    NGINX 储存从 proxied server 过来的响应,直至响应完全被接收,才会发给客户端。这样能提高性能。

    如果关闭缓存,那么响应会同步的发送给客户端,即从收到代理服务器后就立刻发送给客户端。

    出口IP

    作为客户端,服务器连接代理服务器的地 IP 址。当代理服务器只接受某些 IPs 的时候有用。

    压缩

    压缩能有效地减少传输数据量,但同时会增加客观的处理负担从而对性能不利。NGINX 在发送响应前会压缩,但不会压缩已经被压缩的数据。

    压缩的参数:是否压缩、需要压缩的 MIME type、最小压缩长度。

    默认情况下,NGINX 不压缩发给代理的响应。通过 Via 首部识别请求是否来自代理。使用 gzip_proxied 命令设置。比如压缩代理服务器不会储存的数据(为什么?)

    gzip_proxied no-cache no-store private expired auth;

    解压

    有些客户不会解压,需要我们帮它解压好。有些客户能解压的,我们就不帮它解压(节省带宽)。

    通过 gunzip 打开。注意事项:If enabled, the following directives are also taken into account when determining if clients support gzip:gzip_http_versiongzip_proxied, and gzip_disable

    意思是,如果同时打开了解压和压缩,对于支持 gzip 的客户,数据还是压缩的;只有对于不支持的客户,才会解压。

    尝试一下,压缩开关打开,压缩类型选择所有,响应头头中带了

    Content-Encoding:gzip
    Content-Type:image/jpeg

    大小是 19.7 KB。

    关闭 gzip 后:

    没有了 Content-Encoding:gzip

    还是 19.7 KB,大小没变。

    然后又尝试了一个 378KB 的图片,传输大小为 369 KB,开始关闭 gzip 后大小也无变化。系统是 MacOS,所以大小可能有出入。

    发送压缩文件

    开头提到,临时压缩文件会消耗资源,从而降低性能。所以,可以提前压缩好文件。把 gzip_static on; 打开,访问 /path/to/file,如果 /path/to/file.gz 存在,那么实际上返回的是 /path/to/file.gz,文件名默认还是 file。

    我发现 try_fiels 会与这个冲突,从而返回默认的静态文件。

    负载均衡

    默认使用轮询算法

    upstream myproject {
        server 127.0.0.1:8888 weight=3;
        server 127.0.0.1:8889;
    }
    
    server {
        listen 8011;
        server_name www.domain.com;
        location / {
          proxy_pass http://myproject;
    }  

     在这两个端口,启动了 Tornado app,发现确实是 3-1, 3-1 的接收请求。  

    如果要配置静态文件,需要在代理端口 8011 配置,而不是增加 server 监听 8888 或者 8889。应该变成这样

      server {
        listen 8011;
        server_name www.domain.com;
            location /images/ {
                    root /data;
            }
        location / {
          proxy_pass http://myproject;
        }
    

      

  • 相关阅读:
    doT.js——前端javascript模板引擎问题备忘录
    (转)regex类(个人理解)
    ajax提交表单、ajax实现文件上传
    SQL添加表字段
    Elasticsearch使用总结
    有一张表里面有上百万的数据,在做查询的时候,如何优化?从数据库端,java端和查询语句上回答
    sql语句的字段转成Date
    Mybatis 示例之 foreach
    Eclipse不编译解决方案
    Java使用RSA加密解密及签名校验
  • 原文地址:https://www.cnblogs.com/jay54520/p/7071078.html
Copyright © 2011-2022 走看看