前几天在配置线上的 nginx 的时候,遇到一个诡异的问题,还搞了蛮久,记录一下。
首先配置入口:nginx.conf
#user nobody;
worker_processes 4;
error_log /home/work/nginx/logs/error.log;
pid /home/work/nginx/logs/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;
events {
use epoll;
worker_connections 51200;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /home/work/nginx/logs/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
include vhost/*.conf;
}
然后配置相应的 vhost/ai-platform.arganzheng.life.conf:
upstream portal {
server 10.21.12.88:8080;
# server 10.21.12.89:8080;
}
upstream blog {
server 10.21.7.1:8000;
}
server {
listen 80;
server_name ai-platform.arganzheng.life;
access_log /home/work/nginx/logs/ai-platform.arganzheng.life.access.log main;
root /home/work/apps/frontend/portal;
location /api/ {
proxy_pass http://portal;
}
location /blog/ {
proxy_pass http://blog/;
}
location / {
index index.html index.htm;
}
}
这里的陷阱在于 proxy_pass
后面有没有带上 /
,差别很大。官方文档上有说明,但是可能没有注意,就会出问题的时候莫名其妙。
A request URI is passed to the server as follows:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
location /name/ { proxy_pass http://127.0.0.1/remote/; }
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
location /some/path/ { proxy_pass http://127.0.0.1; }
Before version 1.1.12, if proxy_pass is specified without a URI, the original request URI might be passed instead of the changed URI in some cases.
举个例子,上面的配置,如果一个请求 http://ai-platform.arganzheng.life/api/hello
如果配置是:
location /api/ {
proxy_pass http://portal;
}
那么转发给 upstream 的URL将会是: http://10.21.12.88:8080/api/hello
,如果配置的是:
location /api/ {
proxy_pass http://portal/;
}
那么转发给 upstream 的URL将会是: http://10.21.12.88:8080/hello
。