我想使用 nginx 作为以下子域的反向代理api.example.com
,monitor.example.com
但的配置设置api.example.com
始终被覆盖monitor.example.com
。api vhost 具有速率限制器,我不想在监视器 vhost 上应用该设置。第二个 vhost 设置上access_log
也access_log
没有遵循路径。
我可以正确访问后端服务器的内容,但我不明白为什么配置设置api.example.com
也应用于monitor.example.com
vhost。
api.example.com
limit_req_zone $binary_remote_addr zone=api:10m rate=90r/m;
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$request_body"';
upstream backend {
server web-06:80 max_fails=5 fail_timeout=20s;
server web-01:80 max_fails=5 fail_timeout=20s;
}
server {
listen 80;
#logging
#access_log off;
#error_log off;
access_log /var/log/nginx/access.log custom;
location / {
#rate limiting
limit_req zone=api burst=1;
proxy_pass http://backend;
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_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
monitor.example.com
upstream backend2 {
server web-06:80 max_fails=5 fail_timeout=20s;
server web-01:80 max_fails=5 fail_timeout=20s;
}
server {
listen 80;
#logging
#access_log off;
#error_log off;
error_log /var/log/nginx/monitor-error.log;
access_log /var/log/nginx/monitor.log;
location / {
proxy_pass http://backend2;
}
}
答案1
您的两个服务器块将始终发生冲突,因此配置文件中第一个观察到的服务器块将作为所有请求的默认服务器块,除非您server_name
为每个配置指定适当的配置以应用于该主机名/子域的传入请求。(这也适用于所有请求,其请求与$HOST
提供的任何配置都不匹配,并且配置中没有指定default_server
)。当服务器块上缺少配置或$HOST
请求不匹配时,NGINX 默认以这种方式处理请求。
NGINX 将检查请求的主机名。如果$HOST
匹配到具有匹配项的服务器块,server_name
它将使用该配置来确定为请求提供什么服务。如果没有这样的配置来定义哪个服务器块处理什么,则在没有匹配项server_name
(并且您没有指定default_server
)时将默认使用配置中加载的第一个配置块。(server_name api.example.com;
将指定与匹配的服务器块api.example.com
,而server_name monitor.example.com;
指定与匹配的服务器块monitor.example.com
)
只有通过这种方式才能通过一个 NGINX 实例实现多个主机名对多个后端的正确反向代理,其中用于处理对不同后端的不同主机名请求的每个代理块都有单独定义的server_name
指令server
。
你的后端也会有不同的配置 - 如果每个后端只为一个主机服务,那么你不需要需要指定 server_name 在那里 - 你确实需要指定反向代理上的 server_name 以确保它通过正确的配置块路由请求,然后路由到正确的后端。(但是,如果后端可以为两个站点提供服务,则可能需要在后端进行类似的配置)
我已经设置了许多系统,其中一个 NGINX 实例反向代理网络上的多个不同后端和系统,并且始终需要server_name
定义它们才能正常工作。这也是让一个 NGINX 实例从同一实例和配置文件为许多不同的网站提供服务的相同原理。我也在nginx
Ubuntu 中维护该软件包,这是我看到那里的人们在设置他们的 NGINX 来执行您要做的事情时提出的一个常见问题。
答案2
http{
...
server {
listen 80;
server_name api.example.com;
#charset koi8-r;
access_log logs/api.example.com.access.log combined;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://servername1;
root path1;
}
}
server {
listen 80;
server_name monitor.example.com;
access_log logs/monitor.example.com.access.log combined;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://servername2;
root path2;
}
}
}