Nginx如何动态转发到不同IP的内网服务?

场景:

有三台主机,A ,B,C;A和B网络互通,B和C互通,而B的IP固定不变,A和C都是动态IP。
B主机作为代理,转发到C服务器上,A作为客户端,如何做?才能一次配置后不需要修改B,就可以代理到C上?

通常,我们配置Nginx代理如下:

location ^~ /proxy/ {
                proxy_pass http://127.0.0.1:8080;
                proxy_set_header Host $Host;
                proxy_set_header   X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header X-Forwarded-Proto $scheme;
        }

但是这种方式面对动态IP,就会比较头疼了。所以现在出现了很多微服务,通过注册中心和心跳机制,可以灵活的剔除联系不上的主机,从而达到自动化的效果

但是Nginx这里能否做到更灵活一点?
答案是肯定的,
怎么做?

一次配置

就是在发起到B服务的请求中,将C的动态IP带上,如下:
curl http://B-host/proxy/newC-host:port/…
这样,我们截取proxy后面的信息作为代理的目标,就能一次配置B,后续都不需要在修改B了

Nginx中有一个变量:request_uri,这个变量可以获取到对应的请求接口路径,不包含IP地址,在结合正则表达式,就能很好的实现功能
例如,
接口:http://B-host/proxy/newC-host:port/…
对应的request_uri 就是/proxy/newC-host:port/…

看配置

if ($request_uri ~ ^/proxy/(.*)){    #通过正则表达式,截取指定路径
                set $backend_host http://$1;
        }
                location ^~ /proxy/ {
                proxy_pass $backend_host;
                #proxy_set_header Host $Host;
                proxy_set_header   X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header X-Forwarded-Proto $scheme;
        }

这里说明一下,通过正则判断$request_uri 是否是以/proxy开头,是的话,就将/proxy/后面的数据截取
,赋值给变量backend_host 为http://$1 ,其中$1 就是/proxy/ 后面的所有路径

if ($request_uri ~ ^/proxy/(.*)){
                set $backend_host http://$1;
        }

接下来就是指定代理方向就可以了

location ^~ /proxy/ {
                proxy_pass $backend_host;
                proxy_set_header Host $Host;
                proxy_set_header   X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_set_header X-Forwarded-Proto $scheme;
        }

配置好后,重启Nginx
nginx -s reload
完成

看效果

nginx对ip做转发 nginx ip转发不同服务器_nginx对ip做转发


这样,只要B固定,C变动,也不需要改变B的配置,只要知道C的IP和端口号,A就能访问到

应用场景

那么,这种配置方案有什么应用场景吗?
肯定是有的,不然我也不会那么辛苦写这些了

一般在企业中,会有本地环境和测试环境。测试环境可能会有很多很多的服务,而本地环境只和测试环境的Nginx打通,和其他服务可能网络不通,但是想要更好的在本地调试提高工作效率,就可以通过本文的配置方式做代理了