proxy_pass
指令https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
语境:在location, if in location, limit_except中使用
该指令设置代理服务器的协议和地址,以及可选的URI以映射到一个location。作为协议,可以指定“http”或“https”。地址可以是域名或IP地址,以及一个可选的端口:
proxy_pass http://localhost:8000/uri/;
或者作为UNIX域套接字路径,在“unix”后用冒号括起来:
proxy_pass http://unix:/tmp/backend.socket:/uri/;
如果一个域名解析到多个地址,所有地址将以轮询方式使用。此外,地址可以指定为服务器组。
参数值可以包含变量。在这种情况下,如果地址指定为域名,首先在描述的服务器组中查找该名称,如果未找到,则使用解析器确定。
请求的URI传递到服务器的方式如下:
如果proxy_pass
指令带有URI,当请求传递到服务器时,匹配location的标准化请求URI部分将被指令中指定的URI替换:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
如果proxy_pass
未带URI,原始请求URI将按客户端发送的形式传递到服务器,或者在处理更改的URI时传递完整的标准化请求URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}
在1.1.12版本之前,如果proxy_pass
未带URI,原始请求URI可能会在某些情况下被传递,而不是更改后的URI。
在某些情况下,无法确定要替换的请求URI部分:
当location使用正则表达式指定时,或者在命名location中。
在这些情况下,proxy_pass
应不带URI指定。
当使用rewrite
指令在代理location内更改URI时,并且同一配置将用于处理请求(break):
location /name/ {
rewrite /name/([^/]+) /users?name=$1 break;
proxy_pass http://127.0.0.1;
}
在这种情况下,指令中指定的URI将被忽略,完整的更改请求URI将传递到服务器。
使用变量在proxy_pass
中:
location /name/ {
proxy_pass http://127.0.0.1$request_uri;
}
在这种情况下,如果指令中指定了URI,它将按原样传递到服务器,替换原始请求URI。
WebSocket代理需要特殊配置,并且从1.3.13版本开始支持。
proxy_pass
指令的基本用法:定义代理服务器的协议和地址,并可选择指定URI。当指定URI时,请求的匹配部分会被替换;未指定URI时,原始请求保持不变。
unix:/path/to/socket
格式指定UNIX域套接字路径,这在高性能场景中非常有用。
proxy_pass
应不带URI。
rewrite
指令的配合:在使用rewrite
更改URI时,proxy_pass
忽略指定的URI,使用修改后的完整URI。
proxy_pass
中使用变量,提供更大的灵活性。
/
和不加 /
的区别在 Nginx 配置中,proxy_pass
指令用于将请求转发到后端服务器。结尾加 /
和不加 /
有以下区别:
不加 /
:
不改变请求的 URI 路径。
请求中的路径直接附加在 proxy_pass
后指定的 URL 后面。
示例:
location /api {
proxy_pass http://backend;
}
如果客户端请求的是 /api/test
,则请求会转发到 http://backend/api/test
。
加 /
:
移除匹配部分路径,再将剩余路径附加到 proxy_pass
后的 URL。
示例:
location /api/ {
proxy_pass http://backend/;
}
如果客户端请求的是 /api/test
,则请求会转发到 http://backend/test
。
假设 Nginx 配置文件如下:
location /api {
proxy_pass http://backend;
}
location /api/ {
proxy_pass http://backend/;
}
http://example.com/api/test
:
location /api
匹配并使用 proxy_pass http://backend
,最终转发到 http://backend/api/test
。location /api/
匹配并使用 proxy_pass http://backend/
,最终转发到 http://backend/test
。http://example.com/api/
:
location /api
匹配并使用 proxy_pass http://backend
,最终转发到 http://backend/api/
。location /api/
匹配并使用 proxy_pass http://backend/
,最终转发到 http://backend/
。/
:保留并直接附加请求路径。/
:移除匹配路径,附加剩余路径。根据需求,编写合适的 Nginx 配置文件。下面给出几个常见的配置示例:
如果需要将前端 /api
的请求路径直接转发到后端 http://backend/api
:
location /api {
proxy_pass http://backend;
}
如果需要将前端 /api
的请求路径移除 /api
前缀后转发到后端 http://backend
:
location /api/ {
proxy_pass http://backend/;
}
/api/test
,检查后端是否接收到 http://backend/api/test
。/api/test
,检查后端是否接收到 http://backend/test
。可以使用以下工具进行测试:
编辑 Nginx 配置文件:
sudo nano /etc/nginx/nginx.conf
添加如下配置:
http {
...
server {
listen 80;
server_name example.com;
location /api {
proxy_pass http://backend;
}
location /api/ {
proxy_pass http://backend/;
}
}
}
重启 Nginx:
sudo systemctl restart nginx
路径保留测试:
curl -i http://example.com/api/test
http://backend/api/test
。路径移除测试:
curl -i http://example.com/api/test
http://backend/test
。/var/log/nginx/access.log
/var/log/nginx/error.log
proxy_pass
配置不当。根据测试结果,调整 Nginx 配置:
确保路径保留:
location /api {
proxy_pass http://backend;
}
移除路径前缀:
location /api/ {
proxy_pass http://backend/;
}
每次修改配置后,重新加载 Nginx:
sudo nginx -s reload
Nginx 可以缓存后端响应以提升性能:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
server {
...
location /api/ {
proxy_cache my_cache;
proxy_pass http://backend/;
}
}
保持后端连接以减少连接开销:
http {
...
upstream backend {
server backend1.example.com;
keepalive 32;
}
server {
...
location /api/ {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://backend;
}
}
}
启用 HTTPS 以确保传输安全:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location /api/ {
proxy_pass http://backend/;
}
}
限制某些路径的访问:
location /api/secret {
allow 192.168.1.0/24;
deny all;
proxy_pass http://backend/;
}
设置适当的请求头:
location /api/ {
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 X-Forwarded-Proto $scheme;
proxy_pass http://backend/;
}
ab
(ApacheBench)进行压力测试。sslscan
或 Qualys SSL Labs
测试 SSL 配置。