带有正则表达式的 Nginx 变量
Nginx variable with regexp
我有一个用于大约 40 多个节点服务器的 nginx 配置,全部写成:
location /39/api {
proxy_pass http://172.31.32.233:3138;
}
location /io39 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:3138;
}
location /40/api {
proxy_pass http://172.31.32.233:3139;
}
location /io40 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:3139;
}
如您所见,目标节点端口随着 /io39 和 /39/api 路径中的 ID 增加,我知道我可以使用正则表达式将数字捕获到位置指令中,但如何才能我将变量增加为一个整数并将其用作代理的目标端口,因此我可以为千个端口编写一个唯一的指令?
谢谢!
尽管有一个 evaluation regex modifier in Perl and PHP prior to 5.5, as far as I know there is no any equivalent for nginx and no regex mathematics is possible. One of the possible techniques described in 答案。例如,您可以通过这种方式添加类似 30000
的内容(我首先使用最长的 4 位正则表达式模式,因为正则表达式匹配位置是从第一个到最后一个检查的):
location ~ "^/(\d{4})/api" {
set $port 3;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{4})" {
set $port 3;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d{3})/api" {
set $port 30;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{3})" {
set $port 30;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d{2})/api" {
set $port 300;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{2})" {
set $port 300;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d)/api" {
set $port 3000;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d)" {
set $port 3000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
这将为您提供 /1/api
或 /io1
(以及 /01/api
或 /io01
)的端口号 30001,[=17= 的端口号 30002 ] 或 /io2
等等 /9999/api
或 /io9999
URI 最多 39999。
另一种方法是使用lua-nginx-module
or OpenResty:
location ~ "^/(?<number>\d{1,4})/api" {
set_by_lua_block $port { return ngx.var.number + 3099 }
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(?<number>\d{1,4})" {
set_by_lua_block $port { return ngx.var.number + 3099 }
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
我有一个用于大约 40 多个节点服务器的 nginx 配置,全部写成:
location /39/api {
proxy_pass http://172.31.32.233:3138;
}
location /io39 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:3138;
}
location /40/api {
proxy_pass http://172.31.32.233:3139;
}
location /io40 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:3139;
}
如您所见,目标节点端口随着 /io39 和 /39/api 路径中的 ID 增加,我知道我可以使用正则表达式将数字捕获到位置指令中,但如何才能我将变量增加为一个整数并将其用作代理的目标端口,因此我可以为千个端口编写一个唯一的指令?
谢谢!
尽管有一个 evaluation regex modifier in Perl and PHP prior to 5.5, as far as I know there is no any equivalent for nginx and no regex mathematics is possible. One of the possible techniques described in 30000
的内容(我首先使用最长的 4 位正则表达式模式,因为正则表达式匹配位置是从第一个到最后一个检查的):
location ~ "^/(\d{4})/api" {
set $port 3;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{4})" {
set $port 3;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d{3})/api" {
set $port 30;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{3})" {
set $port 30;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d{2})/api" {
set $port 300;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d{2})" {
set $port 300;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/(\d)/api" {
set $port 3000;
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(\d)" {
set $port 3000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}
这将为您提供 /1/api
或 /io1
(以及 /01/api
或 /io01
)的端口号 30001,[=17= 的端口号 30002 ] 或 /io2
等等 /9999/api
或 /io9999
URI 最多 39999。
另一种方法是使用lua-nginx-module
or OpenResty:
location ~ "^/(?<number>\d{1,4})/api" {
set_by_lua_block $port { return ngx.var.number + 3099 }
proxy_pass http://172.31.32.233:$port;
}
location ~ "^/io(?<number>\d{1,4})" {
set_by_lua_block $port { return ngx.var.number + 3099 }
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.31.32.233:$port;
}