【问题标题】:Make Nginx return custom error page when backend is down使 Nginx 在后端关闭时返回自定义错误页面
【发布时间】:2022-02-08 03:32:16
【问题描述】:

我有 Nginx 作为反向代理和 Django 应用程序在它后面工作。 Django 应用通过 UWSGI 连接到 Nginx。 Django 应用程序是使用 Docker 部署的,并且在部署过程中会停机一秒钟左右。我想指示 Nginx 在此期间返回自定义 503 错误页面。

下面是我的 Nginx 配置:

upstream server_django {
    server 0.0.0.0:8000;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name server.com;

    location / {
        # required to serve static assets
        alias    /data/server.com/website_root/;
        try_files $uri @django;
    }

    location @django {
        uwsgi_pass  server_django;
        include     /etc/nginx/uwsgi_params;
    }
}

我尝试在“服务器”块中添加以下配置:

uwsgi_intercept_errors on;
error_page 502 503 504 =503 @django_is_down;
location @django_is_down {
    root /error_pages/server.com/;
    add_header Retry-After 10 always;
    index 503.html;
}

但它没有帮助,因为 Nginx 在后端关闭时盯着默认的 404 页面。

如何检测 Django 何时在 Nginx 中关闭并在发生这种情况时提供自定义错误页面?

【问题讨论】:

  • 您的 @django_is_down 位置使用了原始请求 URI,并且您的 404 错误表明它既找不到 $uri 也找不到 $uri/503.html。你可以试试location @django_is_down { root /error_pages/server.com; add_header Retry-After 10 always; rewrite ^ /503.html break; }
  • 你想让 Django 处理错误并提供错误页面吗?还是在出错时提供静态 HTML?
  • @Mtxz 我希望 Nginx 在 Django 后端关闭时提供静态预定义 503 错误页面(它在部署时发生)
  • 你确定Dango在部署时发回的HTTP代码吗?
  • @Mtxz 我确信 Django 在大约 3 秒的时间间隔内根本不会回复任何 HTTP 代码。这意味着 Django 处于“关闭”状态,根本无法响应。我希望 NGINX 检测到这种情况并使用自定义 503 错误页面进行响应

标签: nginx nginx-reverse-proxy nginx-config


【解决方案1】:

当您使用命名位置作为错误处理程序时,它使用原始请求 URI(无论它是什么),因此假设您有一个类似 http://your.domain/some/route/ 的请求,它将使用 /some/route/ URI 并尝试查找/error_pages/server.com//some/route 目录下的 503.html 索引文件。对于/some/route 请求(不带斜杠),它会尝试查找/error_pages/server.com//some/route 文件,并且根本不会使用您指定的任何索引文件。这意味着只有两个以503.html 文件服务结束的请求是http://your.domain/http://your.domain/503.html,其他一切都会给你一个HTTP 404 错误。如果您甚至没有为这两个自定义 503.html,那么 /error_pages 可能不是顶级目录,而您的意思是 /var/www/error_pages/server.com 之类的东西?

回到问题。如果您想使用命名位置作为错误处理程序,您应该将任何原始请求 URI 重写为新值:

location @django {
    error_page 502 503 504 =503 @django_is_down;
    uwsgi_pass  server_django;
    include     /etc/nginx/uwsgi_params;
}

location @django_is_down {
    root /error_pages/server.com;
    add_header Retry-After 10 always;
    rewrite ^ /503.html break;
}

或者,您可以使用 error_page 指令本身和内部位置更改您的 URI:

location @django {
    error_page 502 503 504 =503 /503.html;
    uwsgi_pass  server_django;
    include     /etc/nginx/uwsgi_params;
}

location = /503.html {
    internal;
    root /error_pages/server.com;
    add_header Retry-After 10 always;
}

如果你想为你的 django 应用保留/503.html URI,你可以使用任何你想要的,例如

location @django {
    error_page 502 503 504 =503 /django_is_down/503.html;
    uwsgi_pass  server_django;
    include     /etc/nginx/uwsgi_params;
}

location = /django_is_down/503.html {
    internal;
    root /error_pages/server.com;
    add_header Retry-After 10 always;
}

(但在这种情况下,您应该将503.html 文件放在/error_pages/server.com/django_is_down 目录下)。

【讨论】:

  • 谢谢你,Ivan,我已经检查过了,它按预期工作!
猜你喜欢
  • 2011-03-08
  • 2011-12-09
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 2018-09-23
相关资源
最近更新 更多