TOTEKAN

Mac と過ごす素敵な日々

さくらVPS を設定してみる:
Nginx + リバースプロキシで WordPress を動かしてみた♪

21 分で読める

Highway 138
Highway 138 by Tiberiu Ana, on Flickr

待ちに待った、Nginx + リバースプロキシの設定♪

WordPress はリクエストがきたときに、コンテンツを作るので、表示までに時間がかかってしまうこともあります。リバースプロキシを使うことで、このコンテンツをキャッシュとして保存しておき、キャッシュがあるときは、コンテンツを新しく作らずにキャッシュから表示することができます。

いちど作ったコンテンツをもういちど作る手間を省いて、WordPress の高速化をします。

めざせ、さくさく WordPress♪

リバースプロキシというのは、リクエストを処理するための入り口です。

キャッシュがあるときは、それ以上の処理をさせないようにしたり、キャッシュがない場合は、リクエストの処理を特定のサーバーに依頼したりすることができます。負荷を分散するために、PHP を処理するためだけのサーバー なんていうものも楽に作ることができます。

また入り口を一つに限定することで、セキュリティなども強化することができますね

ということで、さっそくはじめます。

前回までにつくったファイル と その内容
ファイルパス 設定内容
/etc/nginx/nginx.conf Nginx の共通設定
/etc/nginx/conf.d/example.conf サイトの設定ファイル
/etc/nginx/conf.d/extra/gerenal.conf favicon.ico や robot.txt、ドットファイル。静的ファイルの処理
/etc/nginx/conf.d/extra/wordpress-general.conf WordPress 用の共通設定
/etc/nginx/conf.d/default.conf 存在しないドメインへのアクセス用

この記事では、リパースプロキシとして 80番ポートで Nginx を動かして、キャッシュがなかったり、処理ができないものに関しては、Webサーバーとして 8080番ポートで動かす Nginx で処理をさせます。

Nginx のインストール

Holding on to the past 65/365
Holding on to the past 65/365 by SashaW, on Flickr

じゃあ、Nginx のインストールを。。。

以前、 Nginx をインストールしたので、インストールするものはなにもありません。インストールしていない方は、上を参考にインストールしてください。

リバースプロキシの共通設定

my bag contents on a special day
my bag contents on a special day by tnarik, on Flickr

Nginx の設定をしたときのように、共通設定を部品にしていきます。

まずはすべてのサイトで共通に使う設定を部品にしましょう。ここでは /etc/nginx/conf.d/extra/general-proxy.conf として保存します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sudo vi /etc/nginx/conf.d/extra/general-proxy.conf
 
upstream backend {
    ip_hash;
    server 127.0.0.1:8080;
}
 
proxy_cache_path        /var/cache/nginx/ levels=1:2 keys_zone=czone:10m max_size=100m inactive=120m;
proxy_temp_path         /var/cache/nginx;
proxy_cache_key         "$scheme://$host$request_uri";
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_cache_valid       200 302 10m;
proxy_cache_valid       301 1h;                                                           
proxy_cache_valid       any 1m;

重要なところだけ見ていきます。

upstream backend
http://backend という指定で localhost の 8080番ポート ( WebサーバーとしてのNginx ) にリクエストを渡すことができるようになる。
proxy_cache_path
ここでは cache のサイズや保存場所を指定しています。キャッシュは /var/cache/nginx に、10MB から 100MB までの大きさで 2時間の間だけ保存されます。この設定で キャッシュするときは proxy_cache czone; とする。
proxy_cache_key "$scheme://$host$request_uri"
キャッシュを見つけるためのキー。キーに一致するものがあればキャッシュとして返される。。。。だと思う。そんな気がしてます。
proxy_set_header
リバースプロキシからWebサーバーに渡すときのヘッダーを設定します。
proxy_cache_valid
それぞれ HTTPステータスコードによって、再キャッシュをするまでの時間を指定しています。ステータスコードが 200 302 のときは 10分、301 のときは 1時間、その他は 1分という指定にしています。

残りの部分はおまじないだと思ってください。

あとはキャッシュをしたいところで proxy_cache czone; としてあげれば キャッシュがつくられます。

ファイルができたら、Nginx の全体の設定を書いたファイル /etc/nginx/nginx.conf で読み込みをさせます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sudo vi /etc/nginx/nginx.conf
	.
	.
	.
    gzip_proxied        expired no-cache no-store private auth;
    gzip_buffers        4 8k; 
 
# proxy =====================================================
 
    include /etc/nginx/conf.d/extra/general-proxy.conf;
 
# internal ==================================================
    index index.html index.php;
	.
	.
	.

include /etc/nginx/conf.d/extra/general-proxy.conf; の部分を、サイトの設定を読み込む前のところに追加します。

こうして部品にしておくことで、リバースプロキシの機能を使わないときに、数行をコメントアウトするだけで、すぐに機能を無効にできるようになります。

次に、サイトごとの設定をします。

WordPress 用のリバースプロキシの設定

DSC_3623_2 - Reverse the Change You Did Not Hope For
DSC_3623_2 - Reverse the Change You Did Not Hope For by bterrycompton, on Flickr

ここでは WordPress の場合の設定になりますが、他のサイトでも使えるように説明はしていきたいと思います。

またまた部品を作ります。今度は WordPress 用の設定なので、例としてファイルは /etc/nginx/conf.d/extra/wordpress-proxy.conf にします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ sudo vi /etc/nginx/conf.d/extra/wordpress-proxy.conf
 
rewrite /wp-admin$  $scheme://$host$uri/ permanent;
 
location    /wp-admin        { proxy_pass http://backend; }
location    /wp-login.php    { proxy_pass http://backend; }
 
location / {
    if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
        set $mobile 1;
    }
 
    if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
        set $mobile 2;
    }
 
    if ($http_cookie ~* "comment_author_|wordpress_logged_in_(?!test_cookie)|wp-postpass_") {
        set $do_not_cache 1;
    }
 
    proxy_no_cache     $do_not_cache;
    proxy_cache_bypass $do_not_cache;
    proxy_cache czone;
    proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
 
    proxy_pass http://backend;
}

ほとんどが WordPress向けの設定になっていますが、説明していきます。

rewrite /wp-admin$ $scheme://$host$uri/ permanent;
/ をつけているだけですが、これで http://example.com/wp-admin でも http://example.com/wp-admin/ でも http://example.com/wp-admin/index.php にリダイレクトされます。
location /wp-admin, location /wp-login.php
管理画面とログイン画面では キャッシュをしたくないので、そのまま http://backend にリクエストを投げています。
if ($http_user_agent ~* '( いっぱい )')
モバイル向けのキャッシュを用意します。通常の携帯端末のときは $mobile に 1, スマートフォンの場合には $mobile に 2 をセットして、さらにキャッシュを分割。
if ($http_cookie ~* "いっぱい")
ここでは WordPress にログインしているときには $do_not_cache に 1 をセットしておく。$do_not_cache 1 のときは、キャッシュをしないで、http://backend にリクエストを投げさせる。
proxy_no_cache $do_not_cache, proxy_cache_bypass $do_not_cache
$do_not_cache が 1 のときは、キャッシュしない。
proxy_cache czone;
共通設定の部分で出てきた czone という設定でキャッシュする。
proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
キャッシュを探すためのキー。キャッシュを保存するときにもこれをキーとして保存しているはず。WordPress の場合、http://example.com/index.php?p=123 のようなアドレスがリクエストされるため、共通設定のものでは、リクエストがうまく処理できない。そのため設定を上書きしています。$mobile は モバイル向けに別のキャッシュをつくるため。
proxy_pass http://backend;
キャッシュが見つからなかったら、http://backend にリクエストを投げる。

proxy_cache_key の部分は詳しくみていないのですが、WordPress の場合、http://example.com/index.php?p=123 のようなアドレスにリクエストがきます。このとき、

  • http = $scheme
  • example.com = $host
  • index.php = $request_uri
  • ? = $is_args
  • p=123 = $args

のように処理されているんだろうなぁ〜、なんて思っています。たぶんですけど

WordPress 以外で使う方は、location / {} の中を参考にしていただければいいと思います。

キャッシュをさせたくないファイルやディレクトリがあれば、これよりも前に、location /wp-admin のように指定をして、 proxy_pass でリクエストを投げる。キャッシュをつくる時は proxy_cache、そして キャッシュが見つからなかったときのために、proxy_pass する。

こんな流れで設定していきます。

ということで、これで WordPress のための設定は終わりっ♪

あとは、できたものをどんどん組み込んでいきます。

設定ファイルを組み込む

the contents of my life are up for sale - moving on
the contents of my life are up for sale - moving on by philcampbell, on Flickr

Nginx + リバースプロキシ でウハウハまであと一息っ!!

いままでにつくったファイル と その内容
ファイルパス 設定内容
/etc/nginx/nginx.conf Nginx の共通設定
/etc/nginx/conf.d/example.conf サイトの設定ファイル
/etc/nginx/conf.d/extra/gerenal.conf favicon.ico や robot.txt、ドットファイル。静的ファイルの処理
/etc/nginx/conf.d/extra/wordpress-general.conf WordPress 用の共通設定
/etc/nginx/conf.d/default.conf 存在しないドメインへのアクセス用
/etc/nginx/conf.d/extra/general-proxy.conf リバースプロキシの共通設定
/etc/nginx/conf.d/extra/wordpress-proxy.conf WordPress 用のリバースプロキシの設定

ということで、早速 組み込みをしていきましょう。

まずリバースプロキシの共通設定を Nginx の共通設定に埋め込みます。これは、前の手順で組み込み済みです

サイトの設定ファイルに WordPress 用のリバースプロキシの設定を埋め込みます。編集するファイルは /etc/nginx/conf.d/example.conf です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ sudo vi /etc/nginx/conf.d/example.conf
 
server {
    listen      80; 
    server_name *.example.com;
    rewrite     ^   http://example.com$request_uri?;
}
 
server {
    listen      80;
    server_name example.com;
    root        /var/www/exampleCom;
    index       index.html index.php;
 
    access_log  /var/log/nginx/example_com_proxy_access.log main;
    error_log   /var/log/nginx/example_com_proxy_error.log;
 
    include	/etc/nginx/conf.d/extra/general.conf;
    include   /etc/nginx/conf.d/extra/wordpress-proxy.conf
}
 
server {
    listen      8080; 
    server_name example.com;
    root        /var/www/exampleCom;
    index       index.html index.php;
 
    access_log  /var/log/nginx/example_com_access.log main;
    error_log   /var/log/nginx/example_com_error.log;
 
#    include	/etc/nginx/conf.d/extra/general.conf; # コメントアウト
    include	/etc/nginx/conf.d/extra/wordpress-general.conf;
 
    location ~ \.php$ {
        try_files       $uri    =404;
        include         fastcgi_params;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        if ($uri !~ ^(/uploads/|/wp-content/uploads/) {
            fastcgi_pass    localhost.localdomain:9000;
        }
    }      
}

このページからコピペしてもいいのですが、以前に編集したファイルの状態から、簡単に書き換える方法があります。

まず ファイルを開いたら、PHP の処理を書いた方の server {} で囲まれた部分をコピー。次に、それをコピーしたものを、コピーしたところの上の部分にペースト。

ペーストしたブロックに include /etc/nginx/conf.d/extra/wordpress-proxy.conf; を付け足すlocation ~ \.php$ {} を削除

コピーされた方の server {} にある include /etc/nginx/conf.d/extra/wordpress-proxy.conf; をコメントアウトlisten 80; を liseten 8080; にする。 。

処理の流れを追っていきます。

80番ポートにきたリクエストが静的ファイルの場合、まずは /etc/nginx/conf.d/extra/general.conf で処理されます。静的ファイルには Expires フラグをつけて、ユーザー側でファイルがキャッシュしてもらうので、いちいち 8080番ポートにリクエストを投げる必要はないという判断です。

処理できなかった静的ファイルや、PHP などへのリクエストが /etc/nginx/conf.d/extra/wordpress-proxy.conf でキャッシュできるものはキャッシュするようにして、Webサーバーとして動かしている 8080番ポートの Nginx に投げられます。

最後に /etc/nginx/conf.d/extra/wordpress-general.conf が、上までに処理できなかった静的ファイルを処理、WordPress のパーマリンクを PHP で実行できるように直して、php-fpm に処理を投げる。

こんな流れになっています。なんとなくでもいいので、把握しておくと設定をいじるときに迷わなくっていいのかな? と。

ということで、ついに Nginx + リバースプロキシで WordPress の高速化ができました♪

Nginx を再起動して設定を反映してあげますっ!!

1
2
3
4
$ sudo /etc/init.d/nginx restart
 
あ、リロードでも平気かも?? 試してないですが。
$sudo /etc/init.d/nginx reload

ab コマンドなりで試してみてくださいね♪

ab コマンドで試してみた

Try del Colo
Try del Colo by [Chalito], on Flickr

うちの設定だとこんな感じになりました。たぶん遅い方 ( 120 [#/sec] なんて方もいるみたいなので ) だと思いますけど、これだけできたら充分かなぁ〜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ ab -c 200 -t 20 -n 1000 "http://totekan.jp/"
 
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Document Length:        35309 bytes
 
Concurrency Level:      200
Time taken for tests:   11.352 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      36517778 bytes
HTML transferred:       36293238 bytes
Requests per second:    88.09 [#/sec] (mean)
Time per request:       2270.389 [ms] (mean)
Time per request:       11.352 [ms] (mean, across all concurrent requests)
Transfer rate:          3141.48 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       37  750 698.8    689    9422
Processing:     0  777 2238.7     13   11300
Waiting:        0  701 2097.4      0   11288
Total:        198 1528 2115.5    843   11342

ということで、次回からは。。。。何しよう?

でわでわ、たかともでした。

参考にさせていただきました

どのサイトもすごくわかりやすくまとまっていて、すごく参考になりました。モバイル向けの処理は AKIBE さん、WordPress向けの設定はWordPressコデックスを日本語化された Shinichi Nishikawa's blog さん、細かい設定は wiki.nginx.org にお世話になりました。ありがとうございます。

最後まで記事を読んでいただき、ありがとうございます。

このブログを少しでも、みなさんの記憶に残していただけるのであれば、ぜひ 左のアイコンから RSS 登録していただけたらうれしいです。また Twitter や Facebook もやっています。それぞれ、下から登録していただけたら、うれし泣きで号泣させていただきます。

Ads by Google