nginx之proxy_pass
- 往期回顾:nginx
proxy_pass
是nginx
中常见的反向代理指令。
格式:proxy_pass {传输协议}{主机名}{URI}
- 传输协议:
http://
或者https://
- 主机名:
IP:PORT
URI
:具体的访问地址
先下结论:
当URI
是\
时,表示是绝对路径,则不会将location
后的匹配规则路径携带到转发目标路径中。
当URI
为空时,表示是相对路径,则会将location
后的匹配规则路径携带到转发目标路径中。
假设访问地址是:http:test.nginx.com/proxy/getUserName
1 | # 1.URI=/,表示是绝对路径。所以最终的访问地址是: http://127.0.0.1:81/getUserName |
综上所述:只有当URI
为空时,才会将location
后的匹配字符串带到最终的转发目标路径上。
proxy_set_header 排坑
这里简单描述一下我遇到的场景,在排查过程中耗费了较多的精力。这里我们需要对接外部服务,但是外部服务有一些安全策略,互联网无法直接访问,需要通过跳板机进行访问,同样”外部服务“也只能通过跳板机访问”服务集群“,这里在跳板机上部署了nginx2
。nginx1
是原本环境中的反向代理。
在nginx
中配置了这样一段,用于”外部服务“请求”服务集群“。用于
1 | location /proxy/ { |
在测试中发现,”外部服务“始终无法调用到”服务集群“的接口,而在nginx2
的访问日志中显示404
,一直以为是”服务集群“中部署有问题,但是通过curl
又能正常访问。
在折腾一段时间之后,发现是proxy_set_header
这个变量设置的有问题导致请求到达nginx1
时出现问题。在了解这个具体问题之前,先来简单解释一下nginx
的工作方式。
nginx
作为反向代理时,它是需要监听service_name
和端口的。
第一步根据请求中的
IP
和端口先匹配到具体的代理server
。第二步才是进行路径的匹配,根据
location
的路径规则,进行具体的代理逻辑。
然而第一步中的匹配不是根据请求的地址中的IP和端口,而是通过请求头中的Host
属性进行匹配。再回到最开始出现问题的地方,由于我设置了proxy_set_header Host $host:$server_port;
,导致到达nginx1
的请求的请求头中的Host
是nginx2
本机地址,从而导致nginx1
代理规则匹配失败,所以这里出现的404
是由于nginx1
无法匹配到具体的代理server
导致。
若没有配置则默认是:proxy_set_header Host $proxy_host;
,表示代理的地址。
变量名 | 端口 | 值 |
---|---|---|
$host | 没有端口 | 本机地址 |
$pass_host | 80不显示,其他显示 | 被代理服务的ip和端口 |
$http_host | 端口存在则显示 | 请求时的ip和端口 |