このサイトはnginxでgzip圧縮とリバースプロキシキャッシュを利用しています。
ですが、nginxのgzipモジュールは、クライアントがgzipに対応してない場合は圧縮しないで送ってくれるという、大変気の利いたモジュールなのですが、プロキシキャッシュと合わせていると、以下の様な場合に不都合があります。
- 先にgzip対応のクライアントでアクセスされ、gzip圧縮されたキャッシュができる→非対応クライアントでアクセスすると、gzip圧縮されたキャッシュが送られてくる
- 先にgzip非対応のクライアントでアクセスされると、gzip圧縮されていないキャッシュができてしまう
というわけで、confに一つ条件文を加えて、gzip圧縮比対応の場合はキャッシュを作らないようにしました。
set $do_not_cache 0; if ($http_accept_encoding !~ "gzip") { set $do_not_cache 1; } proxy_no_cache $do_not_cache;
ちゃんと動いてるかのされてるかのテスト
Nginx Cache Controller にキャッシュ日時をHTMLに埋めさせて、curlを使ってテストをしました。
$ curl manaten.net ... <meta http-equiv="Last-Modified" content="Sat, 10 Aug 2013 14:53:35 GMT" /> ... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 11199 0 11199 0 0 10988 0 --:--:-- 0:00:01 --:--:-- 20971 $ curl manaten.net ... <meta http-equiv="Last-Modified" content="Sat, 10 Aug 2013 14:53:38 GMT" /> ...
Last-Modifiedの値が叩いた日時になり、キャッシュされてないことがわかります。
curlに compressed オプションをつけると、gzipに対応したクライアントとして振る舞うようになります。
$ curl manaten.net --compressed ... <meta http-equiv="Last-Modified" content="Sat, 10 Aug 2013 14:54:30 GMT" /> ... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3537 0 3537 0 0 5313 0 --:--:-- --:--:-- --:--:-- 30756 $ curl manaten.net --compressed ... <meta http-equiv="Last-Modified" content="Sat, 10 Aug 2013 14:54:30 GMT" /> ...
Last-Modifiedの値が複数回叩いても変わらず、キャッシュされていることがわかります。 また、サイズが小さくなっており、gzip圧縮されていることもわかります。
この方法ですと、結局gzip圧縮非対応のクライアントに対してプロキシキャッシュが効かなくなってしまいますが、そもそも表示されないよりマシであり、今日日そのようなクライアントはごくわずかでしょうから問題ないでしょう。