问题描述
我是 Nginx 新手,想请教一下。我需要为平衡器编写以下逻辑。请求转到公共地址 gate.mysite.com,然后代理到四个外部服务器 remote[1-4].server.com 之一。 如果请求包含带有某个数字的标头“X-Stamp”,则请求将路由到服务器,其数量使用公式 (X-Stamp mod 4)+1 计算。如果没有标题“X-Stamp”,则为循环。此外,还有以下路由规则:
gate1.mysite.com -> remote1.server.com
gate2.mysite.com -> remote2.server.com
gate3.mysite.com -> remote3.server.com
gate4.mysite.com -> remote4.server.com
我使用 Nginx openresty 编写了这样的配置。
http {
upstream host1 {
server remote1.server.com:443;
}
upstream host2 {
server remote2.server.com:443;
}
upstream host3 {
server remote3.server.com:443;
}
upstream host4 {
server remote4.server.com:443;
}
upstream all {
server remote1.server.com:443;
server remote2.server.com:443;
server remote3.server.com:443;
server remote4.server.com:443;
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name gate.mysite.com;
...
location / {
set $num_header_glob '';
rewrite_by_lua_block {
--reading request headers
local req_headers = ngx.req.get_headers()
local num_header = ""
-- checking an a header value to determine target uri
if req_headers["X-Stamp"] then
num_header = ((req_headers["X-Stamp"])%4)+1
else
-- default path if not header found
num_header = "5"
end
ngx.log(ngx.NOTICE,string.format("resolved num_header: %s",num_header))
ngx.var.num_header_glob = num_header
}
proxy_pass https://$target_uri;
}
}
map $num_header_glob $target_uri {
"1" "host1";
"2" "host2";
"3" "host3";
"4" "host4";
"5" "all";
}
}
server {
listen 443 ssl;
server_name gate1.mysite.com;
...
location / {
proxy_pass https://host1;
}
}
server {
listen 443 ssl;
server_name gate2.mysite.com;
...
location / {
proxy_pass https://host2;
}
}
server {
listen 443 ssl;
server_name gate3.mysite.com;
...
location / {
proxy_pass https://host3;
}
}
server {
listen 443 ssl;
server_name gate4.mysite.com;
...
location / {
proxy_pass https://host4;
}
}
}
但是我需要补充以下条件——如果我在响应中收到一个HTTP-status 307,我需要替换传输给客户端的HTTP头位置值
"remote1.server.com" to "gate1.mysite.com"
"remote2.server.com" to "gate2.mysite.com"
"remote3.server.com" to "gate3.mysite.com"
"remote4.server.com" to "gate4.mysite.com"
如何实现?
解决方法
您正在寻找的是 header_filter
阶段。类似的东西:
header_filter_by_lua_block {
if ngx.status == 307 then
ngx.header["Location"] = (ngx.header["Location"] or ""):gsub("://remote(%d).server.com","://gate%1.mysite.com")
end
}