任务:Nginx配置反向代理到具有动态查找和缓存的docker容器.
流程工作流程
>检查缓存.如果上游发现 – 代理
>如果找不到 – 请求它,缓存和代理
>如果找到但缓存无效 – 清除缓存并再次运行
当前配置(模板):
server {
listen *;
server_name {{host}};
set $attempt 0;
location / {
try_files '/dev/null' @run;
}
location @run {
internal;
set $container_name "{{container_name}}";
set $upstream "";
rewrite_by_lua '
local attempt = tonumber(ngx.var.attempt)
if attempt > 1 then
ngx.log(ngx.ALERT,"Upstream down")
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
local routes = ngx.shared.upstream_cache
if attempt > 0 then
ngx.log(ngx.ALERT,"Deleteing cache")
routes:delete(ngx.var.http_host)
end
ngx.var.attempt = attempt + 1
-- try cached route first
local route = routes:get(ngx.var.http_host)
if route == nil then
ngx.log(ngx.ALERT,"Asking docker about IP of " .. ngx.var.http_host)
local handle = io.popen("docker inspect --format \'{{ .NetworkSettings.IPAddress }}\' " .. ngx.var.container_name)
local result = handle:read("*a")
handle:close()
route = result
end
if route ~= nil then
ngx.var.upstream = route:gsub("^%s*(.-)%s*$","%1")
routes:set(ngx.var.http_host,route)
else
ngx.exit(ngx.HTTP_NOT_FOUND)
end
';
error_page 504 @run;
proxy_buffering 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_redirect off;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_connect_timeout 2;
proxy_pass $scheme://$upstream;
}
}
它几乎可以工作.除了缓存无效且error_page触发的情况外,一切正常.
在这种情况下,进程按原样运行,即log:
[error] 7238#0: *6 upstream timed out (110: Connection timed out) while connecting to upstream
[alert] 7238#0: *6 [lua] [string "rewrite_by_lua"]:12: Deleteing cache
[alert] 7238#0: *6 [lua] [string "rewrite_by_lua"]:21: Asking docker about IP
它向上游提出了正确的请求.
但是响应是空的!
在下一个请求 – 一切正常,上游从缓存中获取.
为什么以及如何解决这个问题?
最佳答案
该死的很简单.
error_page 504 = @run;而不是error_page 504 @run;
error_page 504 = @run;而不是error_page 504 @run;