アンテナメニュー開閉
←前の記事 次の記事→

【更に高速化】高速で強力なWordPressサイトを構築する7

もっとパフォーマンスアップしたい方に。

【更に高速化】高速で強力なWordPressサイトを構築する7
更に高速化を目指す。(JERRYANG)

WEBとDBの分離、プロキシキャッシュサーバの構築

前回の記事ではSSL(TLS)の導入をご紹介しました。

この記事ではウェブサーバとデータベースサーバの分離、そして静的ファイルを配信するプロキシキャッシュサーバの構築方法をご説明します。

これまではサーバひとつでの運用が可能でしたが、今回からは分離を行うので別途別のサーバが必要となります。

そのため、コスト面やメンテナンスに関しては負担が増大しますので、負担を増やしたくない方は無理に設定を行う必要はありません。

ただ、導入を行った場合には間違いなくパフォーマンスが向上するでしょう。

(本文前に)簡単な3行まとめ

  • WEBとDBの分離でパフォーマンス上昇。
  • プロキシキャッシュサーバの構築で更に向上。
  • ただしコストは増え、メンテナンス性は下がるので注意。

記事目次

WEBとDBの分離

通常のウェブサイトであればウェブサーバのみで運用する事が可能です。

しかし、WordPressなどのコンテンツマネージメントシステム(CMS – Content Management System)のようなブログシステムは、柔軟な動作が行える代わりに別途データーベースを扱う必要があります。

CMSはウェブサーバよりもデーターベースの方が頻繁にアクセスがあるため、貧弱なサーバだと動作が鈍くなってパンクしてしまうおそれがあります。

総アクセス数が少ない場合にはこの弊害は気にならないレベルですが、アクセスが増大すれば表示に時間がかかってしまうでしょう。

この場合に手っ取り早く負荷を軽減したいならばサーバ本体の性能をアップさせれば回避することが可能です。

ただ、サーバのスペックを上げるのは結構なコストがかかってしまいますので、サーバのスペックを上げずに別のサーバで分離を行った方がコストが低くなる場合があります。

また、分離をしておくと今後負荷が生じた場合に何が原因で負荷が上昇しているのかを特定しやすくなります。

メンテナンス性は低下しますが、パフォーマンスを増加、負荷低減させるには役割ごとにサーバを分けるのがおすすめです。

スイッチの作成と接続

分離を行う前にまずサーバ同士をローカルネットワークで接続します。

さくらのVPSではローカル接続を行うには最初にスイッチを作成しなければなりません

スイッチの作成についての詳細は公式ヘルプのhttps://help.sakura.ad.jp/app/answers/detail/a_id/2413/~/%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E5%89%8A%E9%99%A4に記述しています。

次にスイッチを利用してサーバ同士をローカルネットワーク接続するのですが、サーバを一度停止しなければ接続することは出来ません

また、さくらのVPSでは同一リージョン同士でないとローカル接続することが出来ません(東京リージョンは東京リージョンでしか接続できない)。

ローカルネットワーク接続に関しても公式ヘルプのhttps://help.sakura.ad.jp/app/answers/detail/a_id/2407/related/1/session/L2F2LzEvdGltZS8xNDY4NzkzOTI5L3NpZC8xX2tqNU5WbQ%3D%3Dに記述しています。

ローカルネットワーク接続

スイッチを作成し、コントロールパネルでネットワーク接続を行っても完全には接続されていませんので正常に動作しません。

正常に動作させるにはプライベートIPアドレスの設定など様々な設定が必要となります。

今回の例ではWebサーバ『192.168.1.1』、DBサーバ『192.168.1.2』と設定を行います。

また、始める前にWPのSQLをPHPMyAdminからエクスポートしておきます(後でインポートします)。

接続設定

次にデーターベース(DB)側のサーバをMariaDBのインストールまで行い、その後調整します(PHPとNginxのインストールは不要)。

次にDB側のUFW設定でWEB側のSSH接続を許可します。

$ sudo ufw allow in proto tcp from 192.168.1.1/24 to any port SSHのポート

次にMysqlのポートである3306を開放し、WEBがMariaDBに接続出来るようにします。

$ sudo ufw allow in proto tcp from 192.168.1.1/24 to any port 3306

次は『/etc/network/interfaces』でWEBとDBのIPアドレス設定を行います。

$ sudo vim /etc/network/interfaces

interfaces内に以下の記述をWEB側、DB側両方に追加します。

addressに関しては編集中のサーバのIPを記述して下さい(DB側を編集中ならば『address 192.168.1.2』)。

interfaces
auto eth1
iface eth1 inet static
address 192.168.1.1(DB側は192.168.1.2です)
netmask 255.255.254.0
offload-tso off

編集が終わったら以下のコマンドでeth1を立ち上げます。

WEB側とDB側どちらも行って下さい。

sudo ifup eth1

その後はping IPで接続出来るかお互いのサーバで確認します。

WEB側でDBに接続できるか確認。
ping 192.168.1.2

DB側でWEBに接続できるか確認。
ping 192.168.1.1

次にDB側でmy.cnfの設定を行います。

$ sudo vim /etc/mysql/my.cnf

bind-addressという項目があるので、コメントアウトします。

interfaces
#bind-address = 127.0.0.1

設定後はMariaDBを再起動します。

$ sudo service mysql restart

次にDB側のMariaDBにログインします。

$ mysql -u root -p

WEB側がDB側のMariaDBにログインするパスワードを設定します。

mysql> grant all privileges on *.* to root@"192.168.1.1" identified by 'ここにWEB側でDB側MariaDBにログインする新しいパスワードを入れる' with grant option;

問題なく追加出来たらテーブルを更新します。

mysql> flush privileges;

MariaDBから離脱します。

mysql> exit

最後にWEB側でDB側のMariaDBにログインします。

ここで先ほど設定した新しいパスワードを要求されます。

$ mysql -u root -h 192.168.1.2 -p

接続が出来ていれば、次にPHPMyAdminの設定を行います。

PHPMyAdmin設定

DB側にPHPMyAdminをインストールしていない場合はcreate_tables.sqlが無いので(インストールしている場合は/usr/share/phpmyadmin/sql/create_tables.sqlにあります)、WEB側に一時設置するかなどしてダウンロードします。

$ cd /tmp
$ wget http://設置ディレクトリ/create_tables.sql

DB側のMariaDBにログインします。

$ mysql -u root -p

次にcreate_tables.sqlをデーターベースに追加します。

mysql> source /usr/share/phpmyadmin/sql/create_tables.sql

tmpに設置した場合は
mysql> source /tmp/create_tables.sql

show databasesでphpmyadminという項目が追加されていれば成功です。

mysql> show databases;

今度はpmaパスを設定します。

mysql> GRANT ALL PRIVILEGES ON phpmyadmin.* TO pma@'192.168.1.1' IDENTIFIED BY 'pmaパスを新規に入力';

離脱します。

mysql> exit

WEB側でrootログインし、config.inc.phpを編集します。

$ sudo su -
# cd /usr/share/phpmyadmin/
# vim config.inc.php

First serverの設定を編集します。

一応元の設定はコメントアウトしておくことをおすすめします。

config.inc.php
/**
 * First server
 */
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = '192.168.1.2';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
$cfg['Servers'][$i]['AllowNoPassword'] = false;

/**
 * phpMyAdmin configuration storage settings.
 */

/* User used to manipulate with storage */
// $cfg['Servers'][$i]['controlhost'] = '';
// $cfg['Servers'][$i]['controlport'] = '';
// $cfg['Servers'][$i]['controluser'] = '';
// $cfg['Servers'][$i]['controlpass'] = '';

// 以下変更なし

WordPress側の設定

WEB側からDB側にPHPMyAdminでアクセス出来る事を確認した後は、最初にエクスポートしたWPのSQLをインポートして下さい。

そして最後にWEB側のwp-config.phpを編集し、ホスト名をDB側に変更します。

$ sudo vim /var/www/example.com/wp-config.php
config.inc.php
/** MySQL のホスト名 */                                                         
define('DB_HOST', '192.168.1.2');

これでWEBとDBの分離が完了し、WordPressも正常に使用出来るようになりました。

次は静的ファイルを配信するプロキシキャッシュサーバの構築方法をご説明します。

静的プロキシキャッシュサーバ

今回構築する静的プロキシキャッシュサーバとはメインサーバの静的ファイル(JPGやCSS等)をキャッシュサーバにキャッシュし、ユーザーにもそのファイルをキャッシュさせることでメインサーバの負荷を低下させるものです。

これはいわゆるコンテンツデリバリーネットワーク(CDN – Content Delivery Network)の簡易自作版で、リバースプロキシ(Reverse proxy)とも言われます。

今回紹介する方法も別のサーバを用意して行うため、コストが増加する事を望まない方は無理に設定しなくてもOKです。

キャッシュサーバに使用するサンプルドメインはstatic.example.comを設定しています。

ローカル接続

とりあえずキャッシュサーバはNginxのインストールまで進めます。

キャッシュサーバのURLにアクセスした時にファイルが無いとエラーが発生するため、キャッシュサーバのルートディレクトリにindex.htmlを置いても構いません。

ただ、後の設定では直接キャッシュサーバのURLにアクセスした場合、メインサーバに移動するようにしています(http://static.example.com/にアクセスした場合、http://example.com/に自動移動する)。

まずはキャッシュサーバをメインサーバとローカル接続します。

これは先程のWEBとDBの分離と同じやり方です。

コントロールパネルで設定した後はinterfacesの設定を行い、IPを他と被らないように設定します。

IPは例として『192.168.1.3』にしています。

$ sudo vim /etc/network/interfaces
interfaces
auto eth1
iface eth1 inet static
address 192.168.1.3
netmask 255.255.254.0
offload-tso off

Nginx設定その1

ローカル接続が終わったら次にキャッシュサーバ側のNginx設定を行います。

なお、メインサーバがSSL(TLS)設定を行っており、なおかつHSTSを有効化している場合はキャッシュサーバ側もSSL(TLS)設定を行って下さい

HSTSが有効化されているとhttp接続を受け付けませんので注意。

$ sudo vim /etc/nginx/conf.d/example.com.conf
example.com.conf

server {
        listen 80;
        server_name static.example.com;

        # static.example.comに直接アクセスがあった場合にexample.comへ301リダイレクトする。
        # メインサーバがSSL(TLS)を使用している場合はhttps
        return 301 http://example.com$request_uri;
}

server {
        listen   80;

        # キャッシュサーバがSSL(TLS)を使用している場合はSSL設定を有効化する。
        # listen 443;

# SSL SETTINGS
#        ssl on;
#        ssl_certificate /etc/letsencrypt/live/static.example.com/fullchain.pem;
#        ssl_certificate_key /etc/letsencrypt/live/static.example.com/privkey.pem;
#        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#        ssl_prefer_server_ciphers on;
#        ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECD H+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !LOW !kECDH !DSS !MD5 !WXP !PSK !SRP !CAMELLIA !SEED';
#        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
#        ssl_stapling on;
#        ssl_stapling_verify on;
#        ssl_trusted_certificate /etc/letsencrypt/live/static.example.com/chain.pem;
#        resolver 8.8.8.8 8.8.4.4 valid=300s;
#        resolver_timeout 5s;
#        ssl_session_tickets on;
#        ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
#        ssl_session_cache builtin:1000 shared:SSL:10m;
#        ssl_session_timeout 5m;

#       add_header Strict-Transport-Security 'max-age=315350000; includeSubDomains; preload';

#/ SSL SETTINGS

        server_name  static.example.com;
        root /var/www/example.com/;
        index index.html index.php;
        access_log off;

# Static Cache Settings

        # PNG JPG(JPEG) GIF ICO CSS JS)はキャッシュサーバにキャッシュする。
        location ~ \.(png|jpg|jpeg|gif|ico|css|js)$ {
                proxy_buffering on;
                proxy_redirect off;

                proxy_buffers 8 64k;
                proxy_buffer_size 64k;

                proxy_cache st_cache;
                proxy_cache_valid 200 180m;
                proxy_cache_valid 404 5m;
                proxy_cache_valid any 30m;

                proxy_connect_timeout 10;
                proxy_send_timeout 10;
                proxy_read_timeout 90;

                proxy_cache_use_stale timeout invalid_header updating http_500 http_502 http_503 http_504;
                proxy_cache_lock on;
                proxy_cache_lock_timeout 5s;

                proxy_pass https://192.168.1.1;
                break;
        }

#/ Static Cache Settings

        # static.example.comに直接アクセスがあった場合にexample.comへ301リダイレクトする。
        # メインサーバがSSL(TLS)を使用している場合はhttps
        location /{
                 rewrite ^(.*)$ http://example.com$1 permanent;
        }

        # JPG(JPEG) GIF PNG ICOファイルはユーザーにキャッシュさせる(30日間)。
        location ~ .*\.(jpg|jpeg|gif|png|ico) {
                access_log off;
                expires 30d;
        }

        # CSS JSファイルはユーザーにキャッシュさせる(7日間)。
        location ~ .*\.(css|js) {
                access_log off;
                expires 7d;
        }
}

次にStatic Cache Settings内の項目について説明していきます。

なお、項目については公式サイトのhttp://nginx.org/en/docs/http/ngx_http_proxy_module.htmlでも解説されています。

また、キャッシュサーバ専用の設定なので通常よりも設定値は大きくなっています。

なお、キャッシュサーバに使用しているスペックはさくらVPS4Gです。

proxy_buffering

proxy_bufferingはプロキシ機能を有効化するか否かを設定します。

例では『on』を設定しています。

proxy_redirect

proxy_redirectはアクセス時に設定されたURLを上書きします。

例では『off』を設定しています。

proxy_buffers

proxy_buffersは応答を読み取るために使用されるバッファの数とサイズを設定します。

例では『8 64k』を設定しています。

proxy_buffer_size

proxy_buffer_sizeは受信した応答の最初の部分を読み取るために使用されるバッファのサイズを設定します。

例では『64k』を設定しています。

proxy_cache

proxy_cacheはプロキシキャッシュに使用するゾーン名を設定します。

例では『st_cache』を設定しています。

proxy_cache_valid

proxy_cache_validは応答パターンごとのキャッシュ時間を設定します。

例では『200 180m』『404 5m』『any 30m』の3種類を設定しています。

proxy_connect_timeout

proxy_connect_timeoutはプロキシサーバとの接続を確立するためのタイムアウト時間を設定します。

例では『10』を設定しています。

proxy_send_timeout

proxy_send_timeoutはプロキシサーバにリクエストを送信するためのタイムアウト時間を設定します。

例では『10』を設定しています。

proxy_read_timeout

proxy_read_timeoutはプロキシサーバからの応答を読み取るためのタイムアウト時間を設定します。

例では『90』を設定しています。

proxy_cache_use_stale

proxy_cache_use_staleは設定したエラーが発生した時に古いキャッシュを使用します。

例では『timeout invalid_header updating http_500 http_502 http_503 http_504』を設定しています。

proxy_cache_lock

proxy_cache_lockは同一のリクエストが同時間に複数あった場合、リクエストを一纏めにします。

例では『on』を設定しています。

proxy_cache_lock_timeout

proxy_cache_lock_timeoutはproxy_cache_lockのタイムアウト時間を設定します。

例では『5s』を設定しています。

proxy_pass

proxy_passはキャッシュサーバが受け付けるURLを設定します。

今回はメインサーバを受け付けるため、先程設定したメインサーバのIP『https://192.168.1.1』を設定しています。

Nginx設定その2

次にnginx.confを編集します。

キャッシュサーバ用設定なので、こちらも通常より大きな設定値となっています。

$ sudo vim /etc/nginx/nginx.conf
nginx.conf
user  nginx;
worker_processes  4;
worker_rlimit_nofile 100000;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
        worker_connections 2048;
        multi_accept on;
        use epoll;
        accept_mutex_delay 100ms;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    charset UTF-8;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

        server_tokens off;
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        access_log off;
        #access_log  /var/log/nginx/access.log  main;

        keepalive_timeout 10;
        client_header_timeout 10;
        client_body_timeout 10;
        reset_timedout_connection on;
        send_timeout 10;

        limit_conn_zone $binary_remote_addr zone=addr:5m;
        limit_conn addr 100;

        # GZIP Settings
        gzip  off;
        #/ GZIP Settings

        # Proxy Cache Settings
        proxy_cache_path /var/cache/nginx/static levels=1:2 keys_zone=st_cache:256m max_size=10g inactive=360m;
        proxy_temp_path /var/cache/nginx/tmp;
        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_ignore_headers X-Accel-Redirect X-Accel-Expires Cache-Control Expires Set-Cookie;
        #/ Proxy Cache settings

        # Openfilecache
        open_file_cache max=100000 inactive=20s;
        open_file_cache_valid 30s;
        open_file_cache_min_uses 2;
        open_file_cache_errors on;
        #/ Openfilecache

    include /etc/nginx/conf.d/*.conf;
}

次にProxy Cache Settings内の項目について説明していきます。

なお、項目については公式サイトのhttp://nginx.org/en/docs/http/ngx_http_proxy_module.htmlでも解説されています。

proxy_cache_path

proxy_cache_pathはプロキシキャッシュの保存場所(path)を設定します。

levels』はサブディレクトリの文字数を表し、1つ目は一文字、2つ目は2文字を表しています。なお、最大3階層まで設定可能です(例-1:2:3)

keys_zone』はキャッシュのゾーン名(名前は自由設定、例は『st_cache』)を設定し、更にゾーンに使用するメモリを設定します。例では256m(256MB)です。

inactive』はアクセスの無いファイルを自動削除する時間です。例では360m(360分)で削除されます。

max_size』はProxy Cacheで生成された全キャッシュの最大量の制限を表します。例では10g(10GB)に達すると新たなキャッシュが生成されません。

例では『/var/cache/nginx/static levels=1:2 keys_zone=st_cache:256m max_size=10g inactive=360m』を設定しています。

proxy_temp_path

proxy_temp_pathはキャッシュの一時ファイルを保存する場所を設定します。

例では『/var/cache/nginx/tmp』を設定しています。

proxy_cache_key

proxy_cache_keyはキャッシュ時に使用するキーを設定します。

Nginxはこのキー情報を用いて閲覧者へファイルを手渡します。

例では『$scheme ://$host$request_uri』を設定しています。

proxy_set_header

proxy_set_headerはプロキシ・サーバのリクエストヘッダに付与するフィールドを設定します。

例は複数あるので除外します。

proxy_ignore_headers

proxy_ignore_headersは特定のリクエストヘッダが処理する内容を無効にします。

例では『X-Accel-Redirect X-Accel-Expires Cache-Control Expires Set-Cookie』を設定しています。

これでNginxの設定は全て終わりましたので、次にURLの置き換えを行います。

URLの置き換え

Nginxで設定した静的ファイルのURLを置き換えます。

全てのURLを手動で変更するのは非常に大変なので、WordPressで用意されているフィルタ機能を使用して置き換えます

記述するのはfunctions.phpです。

functions.php

// 引用元:WordPressで利用する画像のURLをフックで変更する
// 引用元URL:https://worklog.be/archives/3217

// キャッシュサーバ url切り替え
function url_replaces( $content ) {
 
    $url1 = '/example.com\/wp-content\/uploads/';
    $url2 = 'static.example.com/wp-content/uploads';
 
    $content = preg_replace( $url1, $url2, $content );
 
    return $content;
 
}
add_filter( 'post_thumbnail_html', 'url_replaces' ); //アイキャッチ画像のフィルターフック
add_filter( 'the_content', 'url_replaces' ); //コンテンツデータのフィルターフック
add_filter( 'widget_text', 'url_replaces' ); //テキストウィジェットのフィルターフック

これでサイトにアクセスすると、設定した静的ファイル全てがプロキシキャッシュサーバからの配信に切り替わります。

ただし、WordPressの管理対象外(HTMLファイル等)はフィルタの効果が効かないため、手動で編集する必要があるのでご注意下さい。

静的ファイルが完全に分離出来た後はWordPress側でクッキードメインの指定を行います。

これにより、静的ファイルの送信時に不必要なクッキーの付与が行われなくなります。

$ sudo vim /var/www/example.com/wp-config.php
wp-config.php

/** クッキードメイン(静的ファイルを配信していないドメイン)を指定 **/
define('COOKIE_DOMAIN', 'www.example.com');

以上ですべての作業が完了しました。

お疲れ様でした。

次回はAMPの構築方法

次回はAccelerated Mobile Pages(AMP)の構築方法をご紹介します。

AMPは構築するのが少々ややこしいですが、WordPressならば比較的簡単に導入することが可能です。

なお、公開された関連記事は以下より閲覧することが可能です。

シリーズ目次

記事内でのサンプルは『さくらVPS4G・Ubuntu14.04・Nginx・PHP7・MariaDB・Wordpress・+α』となっています。

記事の執筆時、参考となった情報はここのtxtで公開しています。

暗号通貨アドレス

寄付されたコインはサイト運営やコミュニティの発展のために使用されます。

Bitcoin:1NEh5GY6GyY3NZ3bY4ZUtu1CWhRcGhErwc

NEM:NDBEQJ-7XIF6P-46AST5-2JQVLP-JIJS43-VOY5L7-LWA5

アンテナサービス運営中

当サイトでは現在アンテナサービス(プリズムアンテナ)を運営しています。

様々なジャンルのサイト(200以上)を取り扱っているので、よろしければ暇つぶしにどうぞご利用下さい。

アンテナのジャンルについては『アンテナについて』をご覧下さい。