• 002-nginx-proxy_pass、在 nginx 反向代理中使用域名,配置动态域名解析


    一、概述

      代理(proxy),即中间人,它代替客户端发送请求给服务器,收到响应后再转给客户端。通常意义上的代理是从用户的角度讲的,用户通过某个代理可以访问多个网站,这个代理是靠近用户的,比如某些公司可能需要限制员工所访问的网站,就会在网络出口处放置一个代理来做过滤。

      反向代理(reverse proxy),本质上跟代理是一回事,只不过是从服务器的角度讲的,是靠近服务器的。比如某个网站有多个服务器,提供同样的功能,一般会在网络入口处放一个代理,接收客户端的请求,再基于某种策略(比如轮转)转发给后端服务器,这样可以提高整个系统的服务能力。nginx 就是一种常见的 HTTP 协议反向代理。

    1.1、反向代理指令

    nginx 中常见的反向代理指令有两个:proxy_pass 和 fastcgi_pass,前者使用标准的 HTTP 协议转发,后者使用 FastCGI 协议转发,用于 PHP 等架构的环境。在我要说的这个域名问题上,它们行为是一样的,所以下面仅以 proxy_pass 为例。

    一个最简单的反向代理配置如下:

    server {
        location / {
            proxy_pass https://github.com;
        }
    }

    1.2、域名解析

    其作用是将所有请求转发到 github.com。注意此处写的是域名,而非 IP。我们知道在真正发起请求前,是需要将域名解析成 IP 的,对于 github.com 来说,在我的环境上它会被解析成两个 IP:192.30.253.112 和 192.30.253.113,TTL 都是 50s,如下图:

    那么使用上面这个配置,nginx 是什么时候做这件事情的呢?答案是启动的时候,只做一次,解析结果会被缓存下来,也就是完全无视 TTL,后续所有的请求转发,都是直接使用缓存下来的 IP,不会再做任何域名解析。对于 github.com 这种返回多个 IP 的情况,nginx 在转发时会自动对 IP 列表进行轮转。

    可以使用 sudo tcpdump -n -i any port 53 抓包来验证这个行为。注:53 是 DNS 服务的默认端口。

    那么问题来了,IP 变了怎么办?有什么办法让 nginx 自动重新解析域名吗?

    1.3、配置动态域名解析

    resolver 8.8.8.8;
    
    server {
        location / {
            set $servers github.com;
            proxy_pass http://$servers;
        }
    }

    如上,通过使用变量($servers)的方式可以强制 nginx 遵守域名解析结果的 TTL,过期后自动重新解析。不过这种写法有个副作用,如此配置后 nginx 不会自动使用系统 /etc/resolve.conf 的配置,此时必须使用 resolver 指令手动给它指定一个 DNS 服务器。

      其中 8.8.8.8是谷歌的开源免费DNS,国内的有114.114.114.114.如果是内网域名,需要制定内网的DNS服务器。

    参看地址:

      https://github.com/inetfuture/blog/issues/4

      https://www.nginx.com/blog/dns-service-discovery-nginx-plus/ 

    二、反向代理

      注意设置proxy_pass 后,同时需要设置proxy_set_header

    proxy_set_header Host js.test.com; 
    proxy_pass http://js.test.com/; 

    2.1、nginx location proxy_pass 后面的url 加与不加/的区别

      在nginx中配置proxy_pass时,当在后面的url加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。 

      在nginx中配置proxy_pass时,如果是按照^~匹配路径时,要注意proxy_pass后的url最后的/,当加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走;如果没有/,则会把匹配的路径部分也给代理走。

    首先是location进行的是模糊匹配

      1)没有“/”时,location /abc/def可以匹配/abc/defghi请求,也可以匹配/abc/def/ghi等

      2)而有“/”时,location /abc/def/不能匹配/abc/defghi请求,只能匹配/abc/def/anything这样的请求

    下面2种情况分别用http://192.168.1.1/proxy/test.html 进行访问。

    1、proxy_pass后有 / 绝对路径 不带走 location 路径

    location  /proxy/ {
        proxy_pass http://127.0.0.1:81/;
    }

    结论:会被代理到http://127.0.0.1:81/test.html 这个url

    扩展1、

    location  /proxy/ {
        proxy_pass http://127.0.0.1:81/ftlynx/;
    }

    结论:会被代理到http://127.0.0.1:81/ftlynx/test.html 这个url。

    扩展2、

    location  /proxy/ {
        proxy_pass http://127.0.0.1:81/ftlynx;

    结论:会被代理到http://127.0.0.1:81/ftlynxtest.html 这个url

    2、proxy_pass 后没有 / ,带走location路径

    location  /proxy/ {
        proxy_pass http://127.0.0.1:81;
    }

    结论:会被代理到http://127.0.0.1:81/proxy/test.html 这个url

    3、可以通过的rewrite来实现/的功能

     
  • 相关阅读:
    C#3.0实现变异赋值(Mutantic Assignment)
    博客园积分算法探讨
    C#动静结合编程之二: 两种哲学
    REST构架风格介绍之二:CRUD
    C# vs C++之一:委托 vs 函数指针
    REST构架风格介绍之一:状态表述转移
    C#动静结合编程之三:Duck Typing
    C#动静结合编程之四:泛型委托
    C# vs C++之二:GC vs RAII
    Ecshop文章分类列表页如何自定义Title以提高SEO效果
  • 原文地址:https://www.cnblogs.com/bjlhx/p/9472541.html
Copyright © 2020-2023  润新知