一般,nginx中有两个模块都有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_pass
语法: proxy_pass address;
场景: server
说明: 设置后端代理服务器的地址。这个地址(address)可以是一个域名或ip地址和端口,或者一个 unix-domain socket路径.
详见官方文档: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_pass
server {
listen 127.0.0.1:80;
proxy_pass 127.0.0.1:8080;
}
server {
listen 80;
proxy_connect_timeout 1s;
proxy_timeout 1m;
proxy_pass abc.com;
}
server {
listen 53 udp;
proxy_responses 1;
proxy_timeout 20s;
proxy_pass dns.abc.com:53;
}
server {
listen [::1]:80;
proxy_pass unix:/tmp/stream.socket;
}
server {
listen 80;
server_name www.abc.com;
upstream websocket {
server 192.168.100.10:8010;
}
# 正常代理,不修改后端url的
location /testa/ {
proxy_pass http://127.0.0.1;
}
# 修改后端url地址的代理(本例后端地址中,最后带了一个斜线)
location /testb {
proxy_pass http://www.test.com:8801/;
}
# 使用 if in location
location /google {
if ( $geoip_country_code ~ (RU|CN) ) {
proxy_pass http://www.google.hk;
}
}
location /testc/ {
# 没有匹配 limit_except 的,代理到 unix:/tmp/backend.socket:/uri/
proxy_pass http://unix:/tmp/backend.socket:/uri/;;
# 匹配到请求方法为: PUT or DELETE, 代理到9080
limit_except PUT DELETE {
deny all;
}
}
location /wsapp/ {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
/
解析首先,我们看上边的两个例子
location /testa/ {
proxy_pass http://127.0.0.1;
}
location /testb {
proxy_pass http://www.test.com/;
}
#错误写法
location ~ /testd {
proxy_pass http://127.0.0.1:8801/; # 记住,location为正则表达式时,不能这样写!!!
}
区别只在于proxy_pass转发的路径后是否带 “/”,
- 针对不带/
, 假如我们访问的url=http://www.abc.com/testa/test.php,
则通过nginx代理后,请求的路径访问地址为http://www.abc.com/testa/test.php
- 针对带/
, 假如我们访问的url=http://www.abc.com/testb/test.php,
则通过nginx代理后,请求的路径访问地址为http://www.abc.com/test.php
- 实现上述效果也可以通过rewrite来实现,代码如下
location ^~ /test/
{
proxy_set_header Host www.abc.com;
rewrite /testb/(.+)$ /$1 break;
proxy_pass http://www.abc.com;
}
proxy_set_header
Syntax: proxy_set_header field value
Default: Host $proxy_host / Connection close
Context: http / server / location
Reference: proxy_set_header
proxy_set_header Host $http_host;
proxy_set_header X-Forward-For $remote_addr;
需要注意的是:如果Host请求头部没有出现在请求头中,则$http_host值为空,但是$host值为主域名。因此,一般而言,会用$host代替$http_host变量,从而避免http请求中丢失Host头部的情况下Host不被重写的失误。
闲言少叙,直接看nginx修改前后的配置文件:
location / {
proxy_pass http://10.40.15.43:8080/testf/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
修改后的配置文件:
location / {
proxy_pass http://10.40.15.43:8080/testf/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
add_header From admin.abc.com.cn;
proxy_cookie_path /testf/ /;
chunked_transfer_encoding off;
}
问题分析:原来配置会导致cookie存储的位置不是基于“/”那么在第二次访问的时候会从新创建session,因此session中的信息丢失,因此修改cookeie的存储路径解决问题。