Nginxで今度はキャッシュ機能についてDockerでの環境構築をして色々試してみたわ。
キャッシュサーバとは
ブラウザからサーバにリクエストを投げると通常はそのサーバから、リクエストに応じたレスポンスが帰ってくるけど
アクセスが集中するとサーバがレスポンスを返しきれなくなったりする、
で、サーバからのレスポンスを保存して、同じアクセスが来たときにサーバへリクエストを飛ばさず、代わりにレスポンスを返してあげるのがキャッシュサーバである。(ドヤ
イメージ
オリジンサーバは実際のWebサービスが立ち上がっているサーバのことで
ブラウザからのリクエストを一次受けして、キャッシュがあった場合はオリジンサーバの代わりに返してあげるのがキャッシュサーバ
キャッシュがある場合
オリジンサーバは何もしなくてもオッケー
キャッシュサーバが返してくれるんで
キャッシュがない場合
キャッシュサーバに該当するキャッシュがない場合は仕方ない、
オリジンサーバにリクエストを流して、その結果を返す
ただし、キャッシュに保存するから次のアクセスではオリジンには行かせないぞ
検証
環境を最近ハマっているDockerで再現してみた。
リポジトリはこれな https://github.com/smithshiro/docker_nginx_cache_origin(宣伝ではないんや、ソース全部はるのダルいだけw
構成
フォルダ構成はtreeコマンドで一発
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ tree . ├── README.md ├── docker │ ├── cache_nginx │ │ ├── Dockerfile │ │ └── default.conf │ └── origin_nginx │ └── default.conf ├── docker-compose.yaml └── src ├── css │ ├── main.css │ └── reset.css ├── image │ └── sample.jpg └── index.html |
docker-compose.yaml
まずは全体な
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
version: '3' services: cache_nginx: build: ./docker/cache_nginx volumes: - ./docker/cache_nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - origin_nginx ports: - 10088:80 origin_nginx: image: nginx:latest volumes: - ./docker/origin_nginx/default.conf:/etc/nginx/conf.d/default.conf - ./src:/var/www/html |
キャッシュサーバ(cache_nginx)のポートのみを開放しているから、直接オリジンサーバ(origin_nginx)にアクセスはできないようになっているのがミソ
cache_nginxのdefault.conf
アクセスをキャッシュするのと、見つからないときはオリジンに問い合わせるのがミソ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
proxy_cache_path /var/lib/nginx/cache/nginx levels=1 keys_zone=cache:4M inactive=1d max_size=100M; proxy_temp_path /var/lib/nginx/cache/nginx_temp; server { server_name localhost; listen 80; root /var/www/html; access_log /var/log/nginx/access_test.log; location ~* \.(css|js|jpg|png)$ { proxy_pass http://origin_nginx; proxy_cache cache; proxy_cache_key "$scheme://$host$request_uri$is_args$args"; proxy_cache_valid 200 301 302 1d; proxy_cache_valid 404 1m; proxy_cache_valid 500 5s; add_header X-Cache-Status $upstream_cache_status; } location / { proxy_pass http://origin_nginx; } } |
origin_nginxのdefault.conf
まあ、普通w
1 2 3 4 5 6 7 8 9 |
server { listen 80; root /var/www/html; access_log /var/log/nginx/access.log; location / { index index.html; } } |
起動は"docker-compose up -d"
動作検証の前に、新しく出たディレクティブの解説をする
proxy_cache_pathディレクティブ
コンテキスト | http |
説明 | キャッシュの保存先とそのキーゾーンを定義する |
デフォルト値 | inactive=10m loader_files= 100 loader_sleep=50 loader_threshold=200 |
proxy_cacheディレクティブ
コンテキスト | http, server, location |
説明 | キャッシュに利用するキーゾーンを指定する |
デフォルト値 | off |
proxy_cache_keyディレクティブ
コンテキスト | http, server, location |
説明 | キャッシュのキーに使用する文字列を指定する |
デフォルト値 | $scheme$proxy_host$request_uri |
proxy_cache_validディレクティブ
コンテキスト | http, server, location |
説明 | ステータスコードごとのキャッシュの有効期間を指定する |
デフォルト値 | なし |
curlコマンドで試す
初回アクセスの場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ curl -svo /dev/null localhost:10088/css/reset.css * Trying 127.0.0.1... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 10088 (#0) > GET /css/reset.css HTTP/1.1 > Host: localhost:10088 > User-Agent: curl/7.58.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.19.2 < Date: Wed, 11 Nov 2020 14:05:27 GMT < Content-Type: text/css < Content-Length: 597 < Connection: keep-alive < Last-Modified: Wed, 11 Nov 2020 12:57:03 GMT < ETag: "5fabdf9f-255" < X-Cache-Status: MISS < Accept-Ranges: bytes < { [597 bytes data] * Connection #0 to host localhost left intact |
X-Cache-Status: MISS となっているので、オリジンサーバから取ってきている
けど、この結果をキャッシュ化して次のアクセスではこれを返すでしょう。
再度アクセス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ curl -svo /dev/null localhost:10088/css/reset.css * Trying 127.0.0.1... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 10088 (#0) > GET /css/reset.css HTTP/1.1 > Host: localhost:10088 > User-Agent: curl/7.58.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.19.2 < Date: Wed, 11 Nov 2020 14:05:32 GMT < Content-Type: text/css < Content-Length: 597 < Connection: keep-alive < Last-Modified: Wed, 11 Nov 2020 12:57:03 GMT < ETag: "5fabdf9f-255" < X-Cache-Status: HIT < Accept-Ranges: bytes < { [597 bytes data] * Connection #0 to host localhost left intact |
X-Cache-Status: HIT となっているので、キャッシュを返しているのが成功しているようだ
ちなみに、キャッシュはcache_nginxの以下にできてた
/var/lib/nginx/cache/nginx
1 2 3 4 |
root@7352107b3139:/var/lib/nginx/cache/nginx# pwd /var/lib/nginx/cache/nginx root@7352107b3139:/var/lib/nginx/cache/nginx# ls 6 |
まとめ
- キャッシュサーバを立てるとオリジンサーバに変わってレスポンスを返してくれるので、負荷が削減できる
- Nginxではキャッシュ用のディレクティブが用意されていて、リクエストごとにキャッシュをするかどうかの制御ができる
- キャッシュされたファイルはキャッシュサーバに保存され、削除されるまではこれをオリジンに代わって返す
nginxを現場で活用するための知識を、実践的なノウハウを交えて解説した書籍です。
nginxのインストール方法や基本的な設定方法からはじめ、nginxを利用した「静的コンテンツ配信サーバ」「HTTPSサーバ」「Webアプリケーションサーバ」「大規模コンテンツ配信システム」の構築方法をそれぞれ詳しく紹介しています。後半ではnginxサーバのモニタリングやログの収集、そして軽量スクリプト言語Luaでnginxを拡張する方法について解説しているので、nginxをこれから使う方はもちろん、さらに活用したい方にもお勧めです。