Help us understand the problem. What is going on with this article?

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

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を叩くとキャッシュがクリアされるように出来ると思います。簡単ですね。

zaru
basicinc
マーケティングとテクノロジーで社会のあらゆる問題を解決する集団
https://tech.basicinc.jp/
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした