我想使用 nginx 将整个范围 (9000-9999) 代理到不同 IP 地址上的同一端口。nginx 可以自动绑定到一千个端口吗?我可以不用编写 4000 行 nginx 配置来做到这一点吗?
答案1
您可以使用内置的server_port 变量:
proxy_pass http://backend-host-name:$server_port;
这将使得请求进入的任何端口都被代理到同一个后端端口。
因此,您不需要 1000 个 proxy_pass 语句。但是,您可能会遇到以下问题:听指令。它不会接受端口范围,因此您将需要 1000 行格式的代码:
listen 9000;
listen 9001;
listen 9002;
该列表可以通过电子表格轻松生成。您可能还需要调整 nginx 允许的文件句柄数来处理此数量的套接字。Nginx 可以做到这一点,限制可能在操作系统层。请参阅这里和这里。
不过我要说的是,这似乎是一个有问题的设计。为什么需要 1000 个端口?使用主机名或 URL 的某些部分来区分请求不是更有意义吗?这样可扩展性会更强 - 不需要 2000 个套接字作为基准。
答案2
自 NGINX 版本 1.15.10 起,该listen
指令接受端口范围。
来自文档:
端口范围(1.15.10)以连字符分隔的第一个和最后一个端口来指定:
listen 127.0.0.1:12345-12399; listen 12345-12399;
因此,使用
server {
listen 9000-9999;
proxy_pass http://upstream-host:$server_port;
}
应该可以解决问题。
值得注意的是,工作连接数必须进行相应调整,否则 NGINX 将发出错误:
# nginx -s reload
nginx: [emerg] 512 worker_connections are not enough for 1000 listening sockets
答案3
以下是我最终做的事情:
server {
server_name "~^port(?P<forwarded_port>9\d{3})\.example\.com$";
location / { proxy_pass http://127.0.0.1:$forwarded_port; }
}
这样,您就可以简单地连接到http://port9034.example.com;