[PR]
Nginx
Nginx(エンジンエックス)は全世界で最も高稼働なWebサイトの実に37%以上に利用され、今も膨大なコンテンツを高速でユーザーに届けている高性能なオープンソースのHTTP Webサーバです。
2002年にオープンソースとして開発が始まり、10年以上を経て多くのユーザ、開発者の貢献によりパフォーマンスと安定性の高さ、豊富な機能、容易な設定、低消費リソースを実現し、多くの支持を得ています。
そんなNginxですが、単にWebサーバとしてだけではなく、ロードバランサやWebアクセラレータとしても活用することが可能です。
Nginxをロードバランサとして利用する場合、いわゆるIPアドレスによる負荷分散を行うL4ロードバランサではなく、URLやHTTPヘッダーで負荷分散が可能なL7ロードバランサとして振る舞います。そのためリクエスト毎にロードバランスするバックエンドを変えるなど、柔軟な設計をとる事が可能です。
Nginxロードバランサの特徴
- URLに基づいたスマートなバランシング決定
- 圧縮、キャッシングなどのWebアクセラレーション
なお、Nginxの商用サポートやロードバランスのリアルタイム監視(デモ)などが必要な場合、NGINX Plusを検討すると良いでしょう。本稿の構成ではコミュニティ版のNginxを利用しますが、NGINX Plusはコミュニティ版の設定をそのまま利用することも可能です。
構築概要
今回は次の様なシステムを構築してみたいと思います。まずはスモールスタートで……ということで、Nginxで2台のWordPressサーバをロードバランスする構成です。
フロントにロードバランサとしてNginxを1台、裏にWordPressを実行させるWebサーバを2台、そしてDBサーバとしてMariaDB(MySQLと互換性を持つDB)といったシンプルな構成です。
構築
Step1:サーバのオーダー
まずはSoftLayerのポータルからDevice(サーバ)を4台オーダーしましょう。今回は1Core、1GBメモリ、回線は100Mbpsの最小構成の仮想マシンをオーダーしています。
本稿で紹介する構成は、構築スクリプトをGitHubに公開しているので、それをそのままProvisioning Scriptに指定すれば簡単にできあがるようになっています。
オーダーの注意点(必須)
- CentOS7.xの最小構成を選ぶ(LAMP構成やDB構成ではなく、4台とも最小構成を選んでください)
- 4台のサーバーが同じVLANを利用すること
- SSH Keysを指定する
- Provisioning Scriptに対応するスクリプトを指定する
lb01:Nginxのロードバランサ
https://raw.githubusercontent.com/kazuhisya/SL-Scripts/master/centos_el7_nginx_lb
wp01、wp02:WordPressのWebサーバ1・2
https://raw.githubusercontent.com/kazuhisya/SL-Scripts/master/centos_el7_nginx_wp
db01:MariaDBのDBサーバ
https://raw.githubusercontent.com/kazuhisya/SL-Scripts/master/centos_el7_mariadb
Step2:初期設定(LB)
サーバが利用できるようなったら、SSH Keysに指定した鍵を使いrootユーザでロードバランサにログインします。Provisioning Scriptにより、既にNginxがインストール済みの状態になっているはずです。
ここからロードバランスの設定を行っていきましょう。/etc/nginx/conf.d/default.confを確認してください。
Nginxをロードバランサとして利用するときは、このupstreamディレクティブで接続先を指定します。とに各WordPressサーバに割り振られたPrivate IPを指定します。
location/wp-adminでは、WordPressの管理画面の振り先を指定します。今回の構成では、各WordPressのコンテンツ(画像や設定、プラグインなど)は2台のサーバ間で共有されていません。そのため、管理画面は片側のサーバだけに振り分けて手動で対応していきます。
編集できたら以下のコマンドでNginxを再起動します。
1 | [root@lb01 ~]# systemctl restart nginx.service |
Step3:初期設定(DB)
次にDBサーバにsshでログインします。なおDBサーバもProvisioning ScriptによりMariaDBのインストール及びWordPress用DBおよびユーザは既に作成済みです。
ここでは、DBに接続するためのパスワードをメモしておきましょう。
1 | [root@db01 ~]# cat /root/db_password.txt |
2 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
Step4:初期設定(WP)
WordPressサーバにsshでログインします。お気づきかもしれませんが既にこのサーバもProvisioning ScriptによりWordPressのインストール及び、それを動かすためのNginx、php、php-fpmが導入済みです。
ここでは、WordPressの設定ファイルを作っていきましょう。サンプルの設定ファイルをコピーします。(wp01、wp02共に実施)
1 | [root@wp01 ~]# cp /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php |
中身を以下の様に編集します。(以下抜粋)
01 | /** WordPress のためのデータベース名 */ |
02 | define('DB_NAME', 'wordpress'); |
04 | /** MySQL データベースのユーザー名 */ |
05 | define('DB_USER', 'wordpress'); |
07 | /** MySQL データベースのパスワード */ |
08 | define('DB_PASSWORD', 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); |
11 | define('DB_HOST', 'XXX.XXX.XXX.XXX'); |
- WordPressのためのデータベース名:wordpress
- MySQLデータベースのユーザー名:wordpress
- MySQLデータベースのパスワード:DBサーバの/root/db_password.txtの中身
- MySQLのホスト名:DBサーバのPrivate IP
また、以下の箇所に関してはWordPress.orgの秘密鍵生成サービスをブラウザから開き書き換えましょう。このユニークキーもDBの設定と同じく、両サーバであわせる必要があります。
04 | * それぞれを異なるユニーク(一意)な文字列に変更してください。 |
06 | * 後でいつでも変更して、既存のすべての cookie を無効にできます。これにより、すべてのユーザーを強制的に再ログインさせることになります。 |
10 | define('AUTH_KEY', 'put your unique phrase here'); |
11 | define('SECURE_AUTH_KEY', 'put your unique phrase here'); |
12 | define('LOGGED_IN_KEY', 'put your unique phrase here'); |
13 | define('NONCE_KEY', 'put your unique phrase here'); |
14 | define('AUTH_SALT', 'put your unique phrase here'); |
15 | define('SECURE_AUTH_SALT', 'put your unique phrase here'); |
16 | define('LOGGED_IN_SALT', 'put your unique phrase here'); |
17 | define('NONCE_SALT', 'put your unique phrase here'); |
Step5:WordPressセットアップ
WordPressの残りのセットアップはブラウザから行います。ブラウザからNginxロードバランサのPublic IPを開いてWordPressのインストールウィザードを進めてください。
最後まで進むと、以下の様な画面に切り替わります。
性能検証
WordPressのセットアップが終わったところで、その性能を少し確認してみたいと思います。
単体性能
まずは単体での検証です。手元のマシンからインターネット経由でwp01のPublic IPへ負荷を掛けて見ます。検証に利用したコマンドは以下です。/?p=1はサンプルで登録してあるWordPressの Hello world! ページです。
02 | Document Length: 11681 bytes |
05 | Time taken for tests: 170.809 seconds |
06 | Complete requests: 1000 |
09 | Total transferred: 11943000 bytes |
10 | HTML transferred: 11681000 bytes |
11 | Requests per second: 5.85 [#/sec] (mean) |
12 | Time per request: 17080.887 [ms] (mean) |
13 | Time per request: 170.809 [ms] (mean, across all concurrent requests) |
14 | Transfer rate: 68.28 [Kbytes/sec] received |
1秒あたり5.85リクエスト捌けているようですね。
LB性能
次に手元のマシンからlb01のPublic IPへ、つまり2台のロードバランスでの検証を行います。なお、負荷条件は同じです。
02 | Document Length: 11681 bytes |
05 | Time taken for tests: 84.188 seconds |
06 | Complete requests: 1000 |
09 | Total transferred: 11943000 bytes |
10 | HTML transferred: 11681000 bytes |
11 | Requests per second: 11.88 [#/sec] (mean) |
12 | Time per request: 8418.760 [ms] (mean) |
13 | Time per request: 84.188 [ms] (mean, across all concurrent requests) |
14 | Transfer rate: 138.54 [Kbytes/sec] received |
1秒あたり11.88リクエスト捌けています。このケースではロードバランサの性能劣化はほとんど見られず、概ね2倍、しっかりスケールアウトして意図する性能が得られていますね。
キャッシングで更に高速化
ここまででNginxをロードバランサとして利用できるようになりましたが、もう一歩踏み込んでロードバランサにキャッシングの機能を追加してみましょう。
キャッシュがない場合バックエンドにアクセスを振り分け、キャッシュがある場合はフロントエンドのNginxから直接キャッシュを返す構成です。このような構成にすることで、PHPやDBへのアクセスが減り、更なるレスポンス高速化が見込めます。
このキャッシングの機能はロードバランサやリバースプロキシとしてNginxを利用した際の醍醐味の一つでもあります。
設定サンプルを/etc/nginx/conf.d/default.cache.exampleとして設置してあるので、以下の様に設定を入れ替えて、初期設定(LB)の項目と同じくバックエンドのIPを書き換えましょう。
1 | [root@lb01 ~]# mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.org |
2 | [root@lb01 ~]# cp /etc/nginx/conf.d/default.cache.example /etc/nginx/conf.d/default.conf |
編集し終わったら、同じようにNginxの再起動をしておきます。
1 | [root@lb01 ~]# systemctl restart nginx.service |
準備が整ったら、一度負荷を掛けるページにアクセスして、キャッシュに載せましょう。
キャッシュができあがっているか確認しましょう。キャッシュは/var/cache/nginx/cache/以下に出来上がるように設定されています。
1 | [root@lb01 ~]# tree -A /var/cache/nginx/cache/ |
4 | └── XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
キャッシュが出来上がっていることも確認できたので、負荷を掛けて見ましょう。
02 | Document Length: 11681 bytes |
05 | Time taken for tests: 0.917 seconds |
06 | Complete requests: 1000 |
09 | Total transferred: 11958625 bytes |
10 | HTML transferred: 11695577 bytes |
11 | Requests per second: 1089.98 [#/sec] (mean) |
12 | Time per request: 91.745 [ms] (mean) |
13 | Time per request: 0.917 [ms] (mean, across all concurrent requests) |
14 | Transfer rate: 12729.13 [Kbytes/sec] received |
1秒あたり1089.98リクエスト捌けていますね。なんと100倍近い高速化が出来ました。Transfer rateも手元の環境からのインターネット計測にもかかわらず、12729.13[Kbytes/sec]と、ほぼ100Mbpsの帯域を使い切れたようですね。
キャッシュに載りきっている場合これだけ高速化が可能ということですね。キャッシュが既にある場合、フロントで高速にコンテンツを返し、ない場合は2台のバックエンドに振り分ける理想的な環境が出来上がりました。
なお、よりアクセスが集中する場合やバックエンドが増えた場合、Nginx のロードバランサ自体がボトルネックになってくる事があります。
Nginx は傾向としてメモリよりも CPU 資源を利用する傾向があるので、仮想マシンであればコア単位でアップグレードが可能な SoftLayerの大きなアドバンテージと言えそうです。さらに、よりパフォーマンスが必要になった場合、仮想化のオーバーヘッドを気にせず CPU性能をフルに発揮できるベアメタルサーバを簡単にオーダーできるのも魅力です。
まとめ
本稿ではSoftLayerでNginxロードバランサを利用したWordPressサイト構築の概要について記載しました。更に踏み込んだ内容として管理画面のSSL化や、振り分けた2台のWordPressサーバのコンテンツ共有、SoftLayerのCDN機能を用いた高速化など、手を加えることは沢山あるでしょう。
Nginxのスケールアウト構成は市販のロードバランサ等と比べると、駆け出しのエンジニアでも比較的取り組みやすく、キャッシングなどをうまく活用することで驚くほどの性能を発揮できるのでお勧めです。この機会に触れてみてはいかがでしょうか。