Nginx – 使用proxy_pass在错误页面中清空响应

任务: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;

相关文章

文章浏览阅读3.7k次,点赞2次,收藏5次。Nginx学习笔记一、N...
文章浏览阅读1.7w次,点赞14次,收藏61次。我们在使用容器的...
文章浏览阅读1.4k次。当用户在访问网站的过程中遇到404错误时...
文章浏览阅读2.7k次。docker 和 docker-compose 部署 nginx+...
文章浏览阅读1.3k次。5:再次启动nginx,可以正常启动,可以...
文章浏览阅读3.1w次,点赞105次,收藏182次。高性能:Nginx ...