一、proxy_pass的nginx官方指南

nginx中有两个模块都有proxy_pass指令。

ngx_http_proxy_module的proxy_pass:

语法: proxy_pass URL;场景: location, if in location, limit_except解释: 设置后端代理做事器的协议(protocol)和地址(address),以及location中可以匹配的一个可选的URI。
协议可以是\"大众http\"大众或\"大众https\"大众。
地址可以是一个域名或ip地址和端口,或者一个 unix-domain socket 路径。
详见官方文档: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_passURI的匹配,本文第四部分重点谈论。
ngx_stream_proxy_module的proxy_pass:

语法: proxy_pass address;场景: server解释: 设置后端代理做事器的地址。
这个地址(address)可以是一个域名或ip地址和端口,或者一个 unix-domain socket路径。
详见官方文档: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_pass

二、两个

proxyphpnginx之proxypass指令完整拆解 jQuery

在两个模块中,两个proxy_pass都是用来做后端代理的指令。

ngx_stream_proxy_module模块的proxy_pass指令只能在server段利用利用, 只须要供应域名或ip地址和端口。
可以理解为端口转发,可以是tcp端口,也可以是udp端口。

ngx_http_proxy_module模块的proxy_pass指令须要在location段,location中的if段,limit_except段中利用,处理须要供应域名或ip地址和端口外,还须要供应协议,如\"大众http\公众或\"大众https\"大众,还有一个可选的uri可以配置。

三、proxy_pass的详细用法

ngx_stream_proxy_module

server { listen 127.0.0.1:12345; proxy_pass 127.0.0.1:8080;}server { listen 12345; proxy_connect_timeout 1s; proxy_timeout 1m; proxy_pass example.com:12345;}server { listen 53 udp; proxy_responses 1; proxy_timeout 20s; proxy_pass dns.example.com:53;}server { listen [::1]:12345; proxy_pass unix:/tmp/stream.socket;}

ngx_http_proxy_module

server { listen 80; server_name www.test.com; # 正常代理,不修正后端url的 location /some/path/ { proxy_pass http://127.0.0.1; } # 修正后端url地址的代理(本例后端地址中,末了带了一个斜线) location /testb { proxy_pass http://www.other.com:8801/; } # 利用 if in location location /google { if ( $geoip_country_code ~ (RU|CN) ) { proxy_pass http://www.google.hk; } } location /yongfu/ { # 没有匹配 limit_except 的,代理到 unix:/tmp/backend.socket:/uri/ proxy_pass http://unix:/tmp/backend.socket:/uri/;; # 匹配到要求方法为: PUT or DELETE, 代理到9080 limit_except PUT DELETE { proxy_pass http://127.0.0.1:9080; } }}

四、

server { listen 80; server_name www.test.com; # 环境A # 访问 http://www.test.com/testa/aaaa # 后真个request_uri为: /testa/aaaa location ^~ /testa/ { proxy_pass http://127.0.0.1:8801; } # 环境B # 访问 http://www.test.com/testb/bbbb # 后真个request_uri为: /bbbb location ^~ /testb/ { proxy_pass http://127.0.0.1:8801/; } # 环境C # 下面这段location是精确的 location ~ /testc { proxy_pass http://127.0.0.1:8801; } # 环境D # 下面这段location是缺点的 # # nginx -t 时,会报如下缺点: # # nginx: [emerg] \公众proxy_pass\"大众 cannot have URI part in location given by regular # expression, or inside named location, or inside \公众if\公众 statement, or inside # \"大众limit_except\"大众 block in /opt/app/nginx/conf/vhost/test.conf:17 # # 当location为正则表达式时,proxy_pass 不能包含URI部分。
本例中包含了\公众/\"大众 location ~ /testd { proxy_pass http://127.0.0.1:8801/; # 记住,location为正则表达式时,不能这样写!


} # 环境E # 访问 http://www.test.com/ccc/bbbb # 后真个request_uri为: /aaa/ccc/bbbb location /ccc/ { proxy_pass http://127.0.0.1:8801/aaa$request_uri; } # 环境F # 访问 http://www.test.com/namea/ddd # 后真个request_uri为: /yongfu?namea=ddd location /namea/ { rewrite /namea/([^/]+) /yongfu?namea=$1 break; proxy_pass http://127.0.0.1:8801; } # 环境G # 访问 http://www.test.com/nameb/eee # 后真个request_uri为: /yongfu?nameb=eee location /nameb/ { rewrite /nameb/([^/]+) /yongfu?nameb=$1 break; proxy_pass http://127.0.0.1:8801/; } access_log /data/logs/www/www.test.com.log;}server { listen 8801; server_name www.test.com; root /data/www/test; index index.php index.html; rewrite ^(.)$ /test.php?u=$1 last; location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } access_log /data/logs/www/www.test.com.8801.log;}

文件: /data/www/test/test.php

<?phpecho '$_SERVER[REQUEST_URI]:' . $_SERVER['REQUEST_URI'];

通过查看 $_SERVER['REQUEST_URI'] 的值,我们可以看到每次要求的后真个request_uri的值,进行验证。

小结

环境A和环境B进行比拟,可以知道proxy_pass后带一个URI,可以是斜杠(/)也可以是其他uri,对后端request_uri变量的影响。

环境D解释,当location为正则表达式时,proxy_pass不能包含URI部分。

环境E通过变量($request_uri, 也可以是其他变量),对后真个request_uri进行改写。

环境F和环境G通过rewrite合营break标志,对url进行改写,并改写后真个request_uri。
须要把稳,proxy_pass地址的URI部分在环境G中无效,不管如何设置,都会被忽略。