Drupalはバージョンが上がるたびに高機能になり、重くなってきています。静的サイトとは比較にならないくらい負荷がかかります。

Drupal内部における対策としては、データベースアクセスを中心にスロークエリ解消やボトルネック対策を行うことになります。

しかし、Drupal内部だけで対策しても限界があります。

ここでは、Drupal周辺の負荷対策を紹介します。

WebサーバーをApacheからNginxに変更する

高速・軽量なWebサーバーとして定評のあるNginxに切り替えることでパフォーマンスを向上させます。

DrupalはNginxで動く?で「Nginx1.4+Fastcgi+Apc+Mysql5.6+Drupal7.23」で実験した内容を紹介しています。

特殊な拡張モジュールを使っていない限りでは問題なく動作するようです。

Nginxをリバースプロキシサーバーとして利用する

「Nginx(リバースプロキシ)+Apache(Webサーバー)」という構成で静的キャッシュを行います。

要求メモリが少ないため、Webサーバー内に追加することで実験できる。Webサーバー以下の変更がポート番号くらいなのでリリース間際のチューニングに最適。など、導入障壁画が低いです。

Nginxだけでフロントキャッシュ&Webサーバーにする方法もありますが、WebサーバーをNginxにするためには上記のようにFastcgiを導入する必要があります。また、Nginxは.htaccessを理解しませんので、.htaccessで定義している内容をNginxの設定に置き換える必要があります。
また、Apacheで利用しているExtension(mod_xxxx)も置き換える必要があります。

以下はNginxを簡単にリバースプロキシとして利用する際のconfファイルの例です。

Nginx標準では部分キャシュクリア機能を持たないため、下記「location ~ /purge(/.*)」を機能させるためにはngx_cache_purgeモジュールをincludeしたNginxをmakeする必要があります。

http {
    server_tokens off;

    # キャッシュ
    〜
    proxy_cache_path      /var/cache/nginx/cache levels=1 keys_zone=zone1:4m inactive=1d max_size=50m;
    proxy_temp_path       /var/cache/nginx/temp; 
    proxy_ignore_headers  X-Accel-Redirect X-Accel-Expires Cache-Control Expires Set-Cookie;
    〜
    include       mime.types;
    default_type  application/octet-stream;
    access_log /var/log/nginx/access.log;
    sendfile        on;
    keepalive_timeout  65;

    # バーチャルドメイン
    server {
        listen              80;
        server_name         my-public-nginx-server;
        index               index.php;
    
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    Host            $http_host;
        proxy_redirect      off;
        proxy_max_temp_file_size    0;
 
        location / {
            set $do_not_cache 0;

            if ($request_method = "POST") {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/system/) {
              set $do_not_cache 1;
            }

            if ($request_uri ~ ^/node/add/) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/node/[0-9]+/edit) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/node/[0-9]+/delete) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/node/[0-9]+/delete) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/user) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/admin) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/contact) {
              set $do_not_cache 1;
            }
            if ($request_uri ~ ^/inquiry) {
              set $do_not_cache 1;
            }
            〜

            proxy_no_cache     $do_not_cache;
            proxy_cache_bypass $do_not_cache;

            set $dbg_v  "get $host$uri";
            access_log  /var/log/nginx/debug.log debug_log_fmt;

            proxy_pass         http://my-local-apache-server:8080;
            proxy_cache        zone1;
            proxy_cache_key    $host$request_uri;
            proxy_cache_valid  200 302 10m;
            proxy_cache_valid  404 5m;
        }
 
        location ~ /purge(/.*) {
            set $dbg_v  "prg $host$1";
            access_log  /var/log/nginx/debug.log debug_log_fmt;

            proxy_cache_purge zone1 $host$1;
        }
    }
}

Drupalのコンテンツ更新に応じたページ単位のPurgeを行う

上記例は、Nginx単独のキャッシュとして機能し、設定値に応じた固定のキャッシュ期間で動作します。

能動的にキャシュをクリアするには(上記設定では)「http://ドメイン名/purge/キャシュクリアしたいURI」のような形でHTTPアクセスするしかありません。

それでは不便、ということで、Drupal内から、コンテンツの更新/削除などをきっかけにPurgeをキックする仕組みも用意されています。

Purgeモジュール

https://www.drupal.org/project/purge

expireをHookし、変更されたコンテンツに関連するページをPurgeするためのHttpコールを行います。

Cache Expirationモジュール

https://www.drupal.org/project/expire

PurgeモジュールのためのExpire Hookを生成します。

見積りカテゴリ: 
このエントリーをはてなブックマークに追加
Facebook icon
Twitter icon
Google icon