nginx只用一个公网端口转发多个内网服务
一个常见的问题,生产环境的一台有公网ip的服务器,为了安全起见,运维只给开一个端口,于是考虑用nginx根据url的前缀路径来转发到不同服务。例如:
以springboot工程为例,我们自己的web服务一般都会通过设置
来给该服务的所有url设置一个统一的前缀路径 /xxxxxx 。这时候nginx就可以将所有带有前缀 /xxxxxx 的请求转发到该服务。这是一个很简单的事。
问题是有很多第三方服务,例如kafka manager,他是没有这样的前缀的,假设kafka安装在 192.168.0.182 机器上,kafka manager的访问地址就是 http://192.168.0.182:3000 ,我们当然可以在首次访问时通过地址 http://192.168.0.182:3000/kafka 让nginx根据 /kafka 识别到这是kafka manager服务并转发到 http://192.168.0.182:3000 ,但是我们打开kafka manager页面上的链接时是不会有我们自己添加的 /kafka 前缀的,上面的方法失效。
我们都知道http服务是无状态的,就像上面所说即使访问了kafka manager的主页,点击主页上按钮发起的请求也无法被识别为kafka manager请求。但是web服务绝大多是都是需要有状态的,主要有session/cookie、token两种方式来解决这个问题。也可以用来解决上面的问题。
在nginx中配置:
这时候又有一个问题,使用同样的ip:port来访问这些服务,在浏览器看来所有的服务都是一个域的,他们的cookie就会是同一个cookie,这时候nginx没办法根据cookie的不同转发到不同的服务。
我们想到了给每个服务配置一个域名(没有那么多公网域名可用,就在本地hosts文件配置了),产生跨域的效果,让不同的服务有独立的cookie。
从来都是解决跨域问题,从没想过有一天要主动跨域
如果配置了域名,完全可以让nginx根据域名来做识别转发,为什么要用cookie呢?如果你都是配置了公网域名,那确实可以这么干,但是我们是改的hosts文件,保不齐谁的域名就写错了,或者因为只是本地hosts文件的修改根本就没必要统一域名,这时候根据域名做转发就不行了。
kafka manager的访问是不需要认证的,暴露在公网上、面向所有人是一件可怕的事,我们是设置了VPN和访问白名单。