nginxをWEBサーバに、あるいはリバースプロキシにして後ろにApacheやアプリケーションサーバを運用している人は多いと思いますが、nginx1台だけでリバースプロキシ(+キャッシュ)とWEBサーバを実現できないものか、というテーマでやってみました。
ユーザからのリクエストは以下の順に受け取られます。
[ ユーザの{PC,スマホ}] -> [nginxのリバースプロキシ] -> [nginx (WEBサーバ)] -> [アプリケーション]
構築した環境は以下の通りです。
OS: CentOS release 6.4 (Final)
nginx: nginx-1.4.1-1.el6.ngx.x86_64 (nginxリポジトリからインストール)
nginxは最新のパッケージが入手できるので、nginx公式からリポジトリファイルをコピペして作ってインストールすることをおすすめします。あと、リーダー曰く nginxの古いバージョンはDNSのTTLを無視するっぽい ので、epelからインストールしないほうがよさげです。
[ (っ´∀`)っ@友の会 ~]$ sudo yum install nginx (中略) Dependencies Resolved ======================================================================================================================================================================== Package Arch Version Repository Size ======================================================================================================================================================================== Installing: nginx x86_64 1.4.1-1.el6.ngx nginx 311 k Transaction Summary ======================================================================================================================================================================== Install 1 Package(s) Total download size: 311 k Installed size: 770 k Is this ok [y/N]: y (中略) ---------------------------------------------------------------------- Thanks for using NGINX! Check out our community web site: * http://nginx.org/en/support.html If you have questions about commercial support for NGINX please visit: * http://www.nginx.com/support.html ---------------------------------------------------------------------- Verifying : nginx-1.4.1-1.el6.ngx.x86_64 1/1 Installed: nginx.x86_64 0:1.4.1-1.el6.ngx Complete!
上記の方法でインストールしたnginxですが、全体の設定を /etc/nginx/nginx.conf に、キャッシュの設定を /etc/nginx/conf.d/000_PROXY.conf に、バーチャルホストの設定を /etc/nginx/conf.d/100_VHOSTS.conf に施すことにします。 nginx.conf ですが、 worker_processes の調整をするくらいで、 log_format や gzip の設定などはお好みで構いません。
000_PROXY.conf ですが、今回はバーチャルホストが2つある前提でこんなconfigにしてみました。1つ目のサイト SITE1 は同じサーバの20001番ポートで、SITE2 は 20002番ポートで待ち受けることにします。
proxy_cache_path /var/cache/nginx/static_file_cache levels=1:2 keys_zone=cache_static_file:128m inactive=7d max_size=480m; proxy_temp_path /var/cache/nginx/temp; upstream LB_WEB_001{ server 127.0.0.1:20001; } upstream LB_WEB_002{ server 127.0.0.1:20002; } ### ### http://SITE1/ ### server { listen 80; server_name SITE1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / { client_max_body_size 100M; proxy_pass http://LB_WEB_001; set $do_not_cache 0; if ($request_method != GET) { set $do_not_cache 1; } if ($uri !~* ".(jpg|png|gif|jpeg|css|js|swf|pdf|html|htm)$") { set $do_not_cache 1; } proxy_no_cache $do_not_cache; proxy_cache_bypass $do_not_cache; proxy_cache cache_static_file; proxy_cache_key $scheme$host$uri$is_args$args; proxy_cache_valid 200 2h; proxy_cache_valid any 1m; break; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } ### ### http://SITE2/ ### server { listen 80; server_name SITE2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / { client_max_body_size 100M; proxy_pass http://LB_WEB_002; set $do_not_cache 0; if ($request_method != GET) { set $do_not_cache 1; } if ($uri !~* ".(jpg|png|gif|jpeg|css|js|swf|pdf|html|htm)$") { set $do_not_cache 1; } proxy_no_cache $do_not_cache; proxy_cache_bypass $do_not_cache; proxy_cache cache_static_file; proxy_cache_key $scheme$host$uri$is_args$args; proxy_cache_valid 200 2h; proxy_cache_valid any 1m; break; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
次に、 100_VHOSTS.conf はこう書きます。
# # http://SITE1/ # server { listen 127.0.0.1:20001; server_name SITE1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; access_log /home/vhosts/SITE1/logs/access_log main; error_log /home/vhosts/SITE1/logs/error_log; location / { root /home/vhosts/SITE1/public_html; index index.php index.html index.htm; } location ~ .php$ { root /home/vhosts/SITE1/public_html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } # # http://SITE2/ # server { listen 127.0.0.1:20002; server_name SITE2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; access_log /home/vhosts/SITE2/logs/access_log main; error_log /home/vhosts/SITE2/logs/error_log; location / { root /home/vhosts/SITE2/public_html; index index.php index.html index.htm; } location ~ .php$ { root /home/vhosts/SITE2/public_html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
ここまでできたら、ドキュメントルートやログのディレクトリを作成するのと、忘れてはいけないのはキャッシュディレクトリの作成です。
[ (っ´∀`)っ@友の会 ~]$ sudo mkdir -p /var/cache/nginx/{temp,static_file_cache}
キャッシュ領域ですが、ハードディスクではキャッシュを作る意味がないので、RAMDISK上に作成します。 容量512MBでramdiskを作成するので、 /etc/fstab にはこう追記します。
tmpfs /var/cache/nginx tmpfs defaults,noatime,mode=1777,size=512m 0 0
fstab に書き込んだら、マウントしましょう。
[ (っ´∀`)っ@友の会 ~]$ sudo mount /var/cache/nginx
そしていよいよ nginx を起動します。
[ (っ´∀`)っ@友の会 ~]$ sudo service php-fpm start [ (っ´∀`)っ@友の会 ~]$ sudo service nginx start [ (っ´∀`)っ@友の会 ~]$ sudo chkconfig php-fpm on [ (っ´∀`)っ@友の会 ~]$ sudo chkconfig nginx on
それぞれのサイトに何度かアクセスして、キャッシュが蓄積されているか確認してみましょう。
[ (っ´∀`)っ@友の会 ~]$ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 195G 11G 175G 6% / none 939M 0 939M 0% /dev/shm tmpfs 512M 3.1M 509M 1% /var/cache/nginx
こんな風に、 /var/cache/nginx パーティションの使用量が蓄積されればキャッシュされてることがわかります。
※ キャッシュコントロールについて
nginxのキャッシュコントロールですが、RAMDISKのアンマウント/リマウントによる全クリアか、TTL切れによるexpire待ちの2種類になります。個別のキャッシュコントロールは、URLなどのキーで探して個別にクリアするプログラムを書くしかなさそうです。また、キャッシュがある状態でRAMDISKのリマウントを行った場合は、必ずnginxを再起動しないと、キャッシュミスのエラーが発生しますので、これらの動作をワンセットにしたスクリプトを書くのもよいでしょう。
でわ~♪
[amazonjs asin="4873114934" locale="JP" title="ウェブオペレーション ―サイト運用管理の実践テクニック (THEORY/IN/PRACTICE)"]