flaskのbackendが再起動中とかに502 Bad Gateway
で画面が止まってしまうので
backendが生きていないときは復帰するまでreloadするものを用意してみた。
11/22 静的HTMLでリロードする方法 追記
- 302リダイレクトで返すとリダイレクトループになるので503に。
- すぐ
location.reload()
させるとログが大変なのでsleepさせないといけない。 - よくよく見たら試行錯誤の末2箇所でsleepかかってる。片方で良い。
- nginxでnon-blocking sleep - Qiitaの通り、nginx本体にsleepする機能はないのでnginxモジュールを使う必要がある。
-
echo-nginx-module
もngx_lua
もnginxをコンパイルし直す必要があるが、nginxの依存関係にあるnginx-mod-http-perl
の中でsleepが使えたのでこちらを利用する。ngx_http_perl_modules モジュール 日本語訳 - 普通にdocumentrootの下に
location.reload()
するhtml置けば良いことに今更気づく。
ngx_http_perl_modules モジュールを使う方法
/etc/nginx/nginx.conf
http {
# 省略...
perl_modules perl/lib;
perl_require hello.pm;
# 省略...
/usr/share/nginx/perl/lib/hello.pm
package hello;
use nginx;
sub handler {
my $r = shift;
$r->discard_request_body;
$r->sleep(2000, \&next);
$r->send_http_header("text/html");
return OK if $r->header_only;
$r->print("<script>setTimeout(\"location.reload()\",2000);</script>");
$r->print("please wait a moment\n<br/>");
return OK;
}
sub next {
my $r = shift;
$r->send_http_header;
return OK;
}
1;
__END__
/etc/nginx/default.d/hello.conf
location ~ /hello/(.*)$ {
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_param SCRIPT_NAME /hello;
uwsgi_param PATH_INFO /$1;
uwsgi_pass unix:/run/flask_hello/uwsgi.sock;
proxy_intercept_errors on;
error_page 502 =503 @sleep_redirect;
}
location @sleep_redirect {
perl hello::handler;
}
静的HTMLでリロードする方法
/etc/nginx/default.d/hello.conf
location ~ /hello/(.*)$ {
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_param SCRIPT_NAME /hello;
uwsgi_param PATH_INFO /$1;
uwsgi_pass unix:/run/flask_hello/uwsgi.sock;
proxy_intercept_errors on;
error_page 502 =503 /502.html;
}
location /502.html {
root /usr/share/nginx/html/;
}
/usr/share/nginx/html/502.html
<!DOCTYPE html>
<html>
<script>setTimeout("location.reload()",2000);</script>
please wait a moment!
</html>