日本の最高気温記録が更新された

暑さ番付、東の横綱熊谷市で日本の最高気温記録を塗り替える41.1度をマークしたそうです。

今日の熊谷、午前中の最低気温がなんと28.0度、日の出とともに気温が上がり、正午に39度、13時に40度近くまで上昇。その後も勢いは衰えず、14時23分に41.1度に到達したそうです。まじかよ。

そしてさらにもう一つの新記録が誕生しています。東京都青梅市で40.8度を記録。東京都で初の40度越えを観測しました。

最高気温が40度以上を記録した観測地は今まで18ありましたが、青梅が歴代4位タイとなる40.8度の好記録で19番目の40度観測地点に仲間入りです。

気温40度以上の記録を持つ観測地点は以下になります

観測地点 最高気温 記録した日付
埼玉県熊谷 41.1 2018年7月23日 New
高知県江川崎 41.0 2013年8月12日
岐阜県金山 41.0 2018年8月6日 New
岐阜県多治見 40.9 2007年8月16日
山形県山形 40.8 1933年7月25日
東京都青梅 40.8 2018年7月23日 New
山梨県甲府 40.7 2013年8月10日
岐阜県美濃 40.6 2018年7月18日
和歌山県かつらぎ 40.6 1994年8月8日
静岡県天竜 40.6 1994年8月4日
山梨県勝沼 40.5 2013年8月10日
埼玉県越谷 40.4 2007年8月16日
群馬県館林 40.3 2007年8月16日
群馬県上里見 40.3 1998年7月4日
愛知県愛西 40.3 1994年8月5日
千葉県牛久 40.2 2004年7月20日
静岡県佐久間 40.2 2001年7月24日
愛媛県宇和島 40.2 1927年7月22日
山形県酒田 40.1 1978年8月3日
群馬県前橋 40.0 2001年7月24日

この暑さ、あと二週間も続くそうで、この調子では20番目の40度超え観測地点が誕生してもおかしくないです。全くめでたくないですし、全く楽しみじゃないです。ほんと勘弁して欲しいです。

8/6追記: 岐阜県下呂市金山が追加されましたw

nginxのlocationの優先順位を誤解していた

最近nginxを触っていて、locationの優先順位、主に^~の有無による前方一致の扱いについて誤解していたことに気づいた。

まず正解から。locationは以下の流れで決定される

  1. 完全一致チェック -> location = path {}
    • locationとURIが完全一致すれば、この設定で確定
  2. 前方一致チェック -> location path {} または location ^~ path {}
    • ^~ の有無や記述の順番は優先度に影響しない。最長一致するものが選ばれる
      • ^~ ありのlocationが選ばれた場合、この設定で確定
      • ^~ なしのlocationが選ばれた場合、保留して正規表現チェックに移る
  3. 正規表現チェック -> location ~* regexp または location ~ regexp {}
    • 設定ファイルに記述された順番でマッチングしていく
      • マッチするものがあれば、その設定で確定
      • マッチするものがなければ、保留していた前方一致の設定を使う

例えばこんな設定をしたとして

        location /hoge/ {
            return 403;
        }
        location ^~ /hoge/images/ {
            root /var/www/html;
        }
        location ^~ /fuga/ {
            return 403;
        }
        location /fuga/images/ {
            root /var/www/html;
        }
        location ~ \.jpg$ {
            root /data/;
        }

色々なリクエストを送ってみると、こんな結果になる

リクエスURI 前方一致の結果 結果
/hoge/images/a.jpg ^~ /hoge/images/ 前方一致の結果で確定し /var/www/html/hoge/images/a.jpg が返される
/hoge/images/b.png ^~ /hoge/images/ 前方一致の結果で確定し/var/www/html/hoge/images/b.png が返される
/hoge/a.jpg /hoge/ 前方一致の結果は保留され、正規表現にマッチするので /data/hoge/a.jpg が返される
/hoge/b.png /hoge/ 前方一致の結果は保留されるが、マッチする正規表現がないので前方一致の結果が使われて403エラーとなる
/fuga/images/a.jpg /fuga/images/ 前方一致の結果は保留され、正規表現にマッチするので /data/fuga/images/a.jpg が返される
/fuga/images/b.png /fuga/images/ 前方一致の結果は保留されるが、マッチする正規表現がないので /var/www/html/fuga/images/b.png が返される
/fuga/a.jpg ^~ /fuga/ 前方一致の結果で確定し、403エラー
/fuga/b.png ^~ /fuga/ 前方一致の結果で確定し、403エラー

誤解していたのはlocationのマッチング処理順が

  1. =の完全一致
  2. ^~ありの前方一致
  3. 正規表現
  4. ^~なしの前方一致

であると思い込んでいたこと。実際は2の段階で^~のあるものないもの両方がチェックされるので ^~ にマッチするlocationが存在しても、^~なしのlocationが最長一致で選ばれて正規表現マッチに移行する可能性がある。

自分は ^~ をあまり使わないので誤解していても実用上問題なかったのだが、これは非常によろしくない。公式のドキュメントはちゃんと読みましょう。

で、nginxのドキュメントを読むと・・・

nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.

最初に前方一致マッチで一番長くマッチするやつを選んで記憶する

Then regular expressions are checked,

次に正規表現をチェック

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

最長マッチしたlocationが ^~ を持っていたら正規表現はチェックしない

using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates.

=を使うとlocationとURIの完全一致を定義できて、完全一致した場合は検索を終了する