Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
66
Help us understand the problem. What is going on with this article?
@zaru

nginxでリバースプロキシキャッシュして、キャッシュを削除する機能を付ける

More than 1 year has passed since last update.

nginxでリバースプロキシかましてキャッシュさせることでパフォーマンスを稼ぐっていうのは、わりとよくあるシチュエーションなんですが、キャッシュ自体のコントロールっていうのが、案外忘れがちというか、置いてけぼりになることが多いので、キャッシュを削除できる環境を作るメモです。

nginxのリバースプロキシ設定

まず、nginxはデフォルトでキャッシュする機能があるので設定するだけでいけます。下記の設定は、単なるWebサーバ https://example.com をバックエンドとして、全URLをキャッシュする設定です。

nginx.conf
http {

    proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=zone1:4m inactive=7d max_size=50m;
    proxy_temp_path /var/cache/nginx/tmp;

}
server.conf
server {

    proxy_redirect   off;
    proxy_set_header Host               $host;
    proxy_set_header X-Real-IP          $remote_addr;
    proxy_set_header X-Forwarded-Host   $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;

    proxy_ignore_headers Cache-Control;
    proxy_cache zone1;
    proxy_cache_key $uri;
    proxy_cache_valid 200 302 1m;
    proxy_cache_valid 404 10m;

    location / {
        proxy_pass https://example.com;
    }

}

proxy_cache_path

ここのパラメータが毎回分からなくなるのでメモ。第1パラメータはキャッシュファイルを保存する場所です。

キー
levels キャッシュを保存するディレクトリ階層とディレクトリ名に使用される文字数になります。1:2だと/1/01に、2:2:2だと/01/01/01になります。ただし階層を増やしたり、文字数を増やすとその分ディレクトリが作成されることになるので、inode枯渇で死ぬケースもあるようです。参考 nginxのキャッシュ階層を深くしすぎてinodeが枯渇した
keys_zone proxy_cacheディレクティブで指定するキーです。コロン区切りで、共有メモリの容量指定ができます。1MBにつき約8000個のキャッシュメタデータを保存できるようです
inactive 指定した期間後、自動的にキャッシュが削除されます。デフォルトだと10分に設定されています
max_size キャッシュのファイルサイズ上限です。keyz_zoneのメモリと、max_sizeどちらかが枯渇した時点でキャッシュが停止します

キャッシュを削除する

キャッシュを消したい場合は、proxy_cache_pathの中にある該当ファイルを消せばOKなのだけど、いちいちそんな手動で消すの面倒くさいし、ログインしなきゃいけないのでありえんとなるわけです。下記コマンドの様にURLからキャッシュファイルを特定するコマンドもありますけど…。

find /var/cache/nginx/example.com -type f -exec grep -l "KEY: http://example.com/$" {} \; | xargs rm -f

キャッシュ可能なURLを作成する

本題です。nginxデフォルトだとキャッシュを削除する機能はありません。そこでnginxモジュールngx_cache_purgeを使用します。

ngx_cache_purgeをnginxに組み込むには、nginxをソースからビルドして上げる必要があります。はい、面倒くさいですね。nginx自体パッケージからインストールしているし…という人には、nginxのビルドを自動化できるツールnginx-buildを利用しましょう。モジュールも超簡単に導入できます。

もしくは、Itamaeであれば僕が以前作ったItamaePluginがあるので、それを使っても良いと思います。

ngx_cache_purgeを導入したら、設定ファイルにキャッシュを削除する用のURLディレクティブを指定します。この例だと/hoge/piyoのURLをキャッシュしていたとしたら/purge/hoge/piyoにアクセスするとキャッシュが削除できます。

server.conf
server {
    location ~ ^/purge(/.*) {
        allow              127.0.0.1;
        deny               all;
        proxy_cache_purge zone1 $1;
    }
}

アプリケーション側からは、データソースの変更があったタイミングで削除用のURLを叩くとキャッシュがクリアされるように出来ると思います。簡単ですね。

66
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
zaru
basicinc
マーケティングとテクノロジーで社会のあらゆる問題を解決する集団

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
66
Help us understand the problem. What is going on with this article?