nginxで時間指定でsorryページへリダイレクトする

nginxで時間指定でsorryページへリダイレクトする

nginxをリバースプロキシとして動作しているウェブアプリケーション。本体のバックエンドが停止している時間だけproxyしないでsorryページへ飛ばしたい。
Apacheだとmod_redirectのRewriteCondで${TIME_HOUR}${TIME_MIN}とかで指定できますが、nginxだとどうやるんだろう。

変数を調べる

リクエストの時間はわからないみたいだけど、ローカルサーバの時間なら変数で参照できる模様。何種類かあるみたい。

変数名 意味
$time_local サーバの時間
$time_iso8601 同、ISO8601形式
$time_msec 同、ミリ秒単位

具体的にどんな数字がはいってくるんだろ。ISO形式ではないってことはepocタイムだろうなぁ。

条件をつけるには

if()ってのが使える。location中では使わないほうがいいような文書
www.nginx.com
もあるようだけど、その文書にもreturnなら安全とあるのでこれを利用します。

if( condition ){
   todo ;
}

何時何分〜っての表現

ifのconditionでは残念ながら変数は数字ではなく文字列として評価されるみたい。"="や"!="は使えるし、真(!=0)と偽(0)も使えるけど、大小比較(<>)は使えない。
幸いなことに正規表現の評価ができる。8月19日0時〜4時にマッチするISO8601形式は以下。

2019-08-19T0[0-3]

で完成形はこちら

ということで特定のlocationでProxyの前にifとreturnをかけばいい。こんな感じ。04時には終了させるので03時までマッチさせる。
めんどくさいことにifと次の(の間にスペースがないと文法的にNG。

location /hogehoge/ {
    if ( $time_iso8601 ~ '2019-08-19T0[0-3]' ) {
        return 302 https://www.example.com/sorry.html ;
    }
    proxy_pass http://10.1.100.1/hogehoge/ ;
}

この他にも

ifではファイルの有無でも評価してくれる。なのでcronで時間指定で空ファイルを作成して、そのファイルの有無でリダイレクトさせる方法もある。

location /hogehoge/ {
   if ( -t /tmp/redirect.txt ){
以下略

でも、cronとnginxの二箇所に設定があるとわかりにくいしメンテナンス容易性も下がるような。
正規表現がわかりにくいとかって話は却下。