大トラブル発生!?nginxのキャッシュ設定で気をつけたいこと

結論からお伝えします。Nginxのキャッシュのキー指定時には、$request_methodを追加しておいたほうがいいです。これをしておかないと、わたしが陥ったトラブルに遭遇する可能性があります。。。

発生したトラブル

ある日自分のサイトにアクセスすると、空のレスポンスが返ってきてしまいました。ブラウザでアクセスしても完全に真っ白な状態です。また、レスポンスコードは200が返ってきていました。(そのせいで当時の検知に引っかからず、発見が遅れてしまいました。。。)

$ curl https://remotestance.com
<- 何も返ってこない。。。

$ curl -I https://remotestance.com
HTTP/1.1 200 OK <- ステータスコードは200が返ってくる。。。

といっても毎回レスポンスが空なわけではなく、きちんとレスポンスを返すサーバもありました。また、EC2のインスタンスを立ち上げなおすと、正しくレスポンスが返ってきました。

サーバの状態によって違うということで、キャッシュ周りが怪しいと当たりをつけて調査を開始しました。

原因

原因は、NginxがHEADリクエストをキャッシュするような設定になっていたからでした。

当時の設定は、以下のように、GETリクエストもHEADリクエストも同じキーでキャッシュするようになっていました。なお、以下はupstreamがFastCGIの例です。

fastcgi_cache_key $scheme$host$uri;

そのために、まだキャッシュされていない状態でHEADリクエストを受けると、次回同じURLが来た際に空のレスポンスを返すようになっていました。

# URL(https://remotestance.com)がまだキャッシュされていない状態
$ curl -I https://remotestance.com
HTTP/1.1 200 OK <- ステータスコード200が返ってきて、空のレスポンスがキャッシュされる。

$ curl https://remotestance.com
<- 次回移行同じURLにアクセスすると、HEADリクエストでキャッシュされた、空のレスポンスが返ってくる。

解決策

原因がわかれば解決策は簡単です。fastcgi_cache_keyに指定するキーを、GETとHEADで別々にしてあげるだけです。

# fastcgi_cache_key $scheme$host$uri;
fastcgi_cache_key $scheme$request_method$host$request_uri;

上記のように、キーに$request_methodをくっつけて、GETとHEADのキーを別にするとレスポンスが正しく返ってくるようになります。

# URL(https://remotestance.com)がまだキャッシュされていない状態
$ curl -I https://remotestance.com
$ curl https://remotestance.com
<!DOCTYPE html>
... <- 正しいレスポンスが返ってくるようになった!

この記事が役に立った場合、シェアしていただけると励みになります!!