高性能なNGINX+PHP-FPM Webサーバーの構築と最適化ガイド(CentOS 7)
PHP-FPM(FastCGI Process Manager)は、PHPスクリプトを実行するためのFastCGI実装の一つです。静的コンテンツの処理に優れたNGINXとPHP-FPMを組み合わせることで、LAMPスタック(Apache + mod_php)よりも高速で高性能なWebサーバーを構築できます。
LEMPは、WebサイトのホスティングやWebアプリケーションの公開のために一般的に一緒に導入されるオープンソースソフトウェア群を指す略語です。それぞれLinux(OS)、Nginx(より一般的なLAMPスタックにおけるApacheの代替となるWebサーバー)、MySQL/MariaDB(データベース)、PHP(動的コンテンツの処理)を表しています。
本記事では、CentOS 7サーバー上で高負荷のWebプロジェクトをホスティングするために、LEMPスタック(NGINX + PHP-FPM + MariaDB/MySQL)のインストール方法と最適化の手順を詳しく解説します。
NginxのインストールとWebサーバーとしての設定
新規インストールしたCentOSサーバーを前提とするため、まず定番のEPELリポジトリを追加し、サーバー上の全パッケージを最新状態に更新します。
# yum install epel-release -y
# yum update -y
最新版のNginxをインストールするには、以下のコマンドで公式リポジトリを追加します。
# rpm -Uvh https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
あるいは、リポジトリ設定ファイル(/etc/yum.repos.d/nginx.repo)を手動で作成し、以下の内容を記述しても構いません。
[nginx] name=nginx repo baseurl=https://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1
CentOS 8を使用している場合は、URL内のバージョン番号を変更してください。
yum(またはdnf)パッケージマネージャーを使ってNginxをインストールします。
# yum install nginx -y
続いて、nginxを起動し、systemctlで自動起動を有効にします。
# systemctl start nginx
# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service
Webサーバーが正常に稼働しているか確認するには、ブラウザでサーバーのIPアドレスを開きます。テストページが表示されない場合は、firewalldの許可サービス、ポート、ゾーンの設定を見直してください。
次に、個別ドメインwoshub-linux.com用の設定ファイルを作成します。サイト用ディレクトリと設定ファイルを作成しましょう。
# mkdir -p /var/www/woshub-linux.com && mkdir -p /var/www/woshub-linux.com/log
設定ファイルを開きます。
# nano /etc/nginx/conf.d/woshub-linux.com.conf
以下の内容を追記します。
server {
listen 80;
server_name woshub-linux.com;
root /var/www/woshub-linux.com;
index index.php index.html index.htm;
access_log /var/www/woshub-linux.com/log/access.log main;
error_log /var/www/woshub-linux.com/log/error.log;
location / {
return 301 https://woshub-linux.com$request_uri;
}
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff)$ {
return 301 https://woshub-linux.com$request_uri;
}
location ~ \.php$ {
return 301 https://woshub-linux.com$request_uri;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
rewrite ^ /robots.txt break;
allow all;
log_not_found off;
access_log off;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 80;
server_name www.woshub-linux.com;
rewrite ^ https://woshub-linux.com$request_uri? permanent;
}
server {
listen 443 ssl http2;
server_name woshub-linux.com;
root /var/www/woshub-linux.com;
index index.php index.html index.htm;
access_log /var/www/woshub-linux.com/log/ssl-access.log main;
error_log /var/www/woshub-linux.com/log/ssl-error.log;
keepalive_timeout 60;
ssl_certificate /etc/letsencrypt/live/woshub-linux.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/woshub-linux.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
add_header Strict-Transport-Security 'max-age=604800';
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff)$ {
access_log off;
expires max;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param DOCUMENT_ROOT /var/www/woshub-linux.com;
fastcgi_param SCRIPT_FILENAME /var/www/woshub-linux.com/$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED /var/www/woshub-linux.com/$fastcgi_script_name;
include fastcgi_params;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param HTTPS on;
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort off;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 443 ssl http2;
server_name www.woshub-linux.com;
rewrite ^ https://woshub-linux.com$request_uri? permanent;
}この設定ファイルには、HTTPSによる安全なアクセスのための設定が含まれています。多くの人気CMSはデフォルトでHTTPSを使用するためです。後から無料のLet's Encrypt証明書をインストールして設定することも可能です。
PHP-FPMのインストール
NginxにはPHPハンドラーが組み込まれていないため、PHPスクリプトを処理するためにphp-fpmといくつかのPHPモジュールをインストールする必要があります。
php-fpmはシンプルかつ高速なPHPプロセスマネージャーです。Apacheとは異なりHTTPプロトコルを使用せず、専用のFastCGIプロトコルで動作します。軽量で扱いやすいFPMはPHPリクエストをより速く処理でき、Apacheとの組み合わせと比較してメモリ消費も抑えられます。
一方、Nginxは静的コンテンツの配信に非常に効率的です。この構成では、Nginxがプロキシサーバー(キャッシュ兼フロントエンド)として機能し、php-fpmがバックエンドとして動作します。
新しいバージョンのPHPをインストールするにはREMIリポジトリを使用します。
# rpm -ivh https://rpms.famillecollet.com/enterprise/remi-release-7.rpm
インストール後、/etc/yum.repos.d/remi-php74.repoファイルを編集します。
php-fpmと主要なPHPモジュールをインストールします。
# yum install php-fpm php-cli php-mysql php-gd php-ldap php-odbc php-pdo php-opcache php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap php-zip
php-fpmデーモンを起動し、自動起動を有効にします。
# systemctl start php-fpm
# systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.
サービスが起動していることを確認するには、次のコマンドを実行します。
# lsof -i:9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME php-fpm 1551 root 7u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN) php-fpm 1552 apache 9u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN) php-fpm 1553 apache 9u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN) php-fpm 1554 apache 9u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN) php-fpm 1555 apache 9u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN) php-fpm 1556 apache 9u IPv4 2078435 0t0 TCP localhost:cslistener (LISTEN)
php-fpmをUnixソケットで動作させるように変更します。/etc/php-fpm.d/www.confから「listen = 127.0.0.1:9000」の行を削除し、以下を追加してください。
listen = /var/run/php-fpm/php-fpm.sock listen.mode = 0660 listen.owner = nginx listen.group = nginx
php-fpmをapacheユーザー以外(デフォルト設定)で実行するには、設定ファイルに以下のパラメータを指定します。
user = nginx group = nginx
php-fpmの設定ファイルを変更したら、サービスを再起動します。
# systemctl restart php-fpm
WebサーバーへのMySQL/MariaDBのインストール
この手順については、「MariaDB on Linux のインストールと最適化」の詳細ガイドが別記事として公開されているため、ここでは割愛します。そちらの記事を参考にしてください。
高負荷対応のためのNginx + PHP-FPMの設定
Webサーバーで大量のクライアントリクエスト(高トラフィックサイト)を処理するには、nginxとphp-fpmを適切にチューニングすることが重要です。
Nginxの設定
/etc/nginx/nginx.confファイルを開き、以下のようにNginxの設定を変更します。
worker_processes 2;— ワーカープロセス数をサーバーのCPUコア数と同じに設定します。worker_connections 1024;— 1ワーカープロセスあたりの接続数を設定します(1024〜4096の値を推奨)。use epoll;— Linux環境で最適な接続処理方式です。multi_accept on;— nginxが最大数の接続を受け入れるようになります。
httpブロックの設定:
tcp_nodelay on;— ヘッダーとファイルの先頭部分を1つのパケットで送信します。tcp_nopush on;
静的ファイルが多いWebプロジェクトでは、gzip圧縮を有効にしましょう。
gzip on;
Google PageSpeedのチェックをすべて通過できるよう、さまざまなファイルタイプを追加します。
gzip_types application/atom+xml application/javascript text/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json font/ttf application/x-font-ttf application/vnd.ms-fontobject application/font-woff application/font-woff2 application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vnd.wap.wml text/vtt text/x-component text/x-cross-domain-policy;
タイムアウト関連の設定を変更します。
keepalive_timeout 30;— keepalive接続を閉じるまでWebサーバーが30秒待機します。keepalive_requests 100;— 1クライアントからのkeepaliveリクエストの最大数です。reset_timedout_connection on;— 応答しなくなったクライアントからの接続をリセットしたい場合は有効にします。client_body_timeout 10;— クライアントからのリクエスト確認を10秒待ち、応答がなければ接続を切断します。send_timeout 2;— クライアントがWebサーバーの応答を読み取らなくなった場合、nginxが接続をリセットします。
大きなファイルのアップロードを想定していないサイトであれば、nginx側で制限を設けましょう。
client_max_body_size 2m;— サーバーは2MBを超えるリクエストを受け付けません。
プロジェクトのコンテンツが頻繁に更新されない場合は、「expires max;」によるキャッシュを利用するか、必要なファイルタイプに対してホストの設定ファイルに該当オプションを追加できます。例:
location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff)$ {
expires 7d;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~指定したファイルタイプのキャッシュは7日間保持されます。
設定を変更したら、必ずnginxを再起動してください。
# systemctl restart nginx
PHP-FPMの設定
php-fpmのインストール時にUnixソケットへ切り替え済みですが、これはパフォーマンスを大幅に向上させます。試算によると、生産性は2〜3倍に向上すると言われています。その他のphp-fpmパラメータは、プロジェクトごとに個別に調整する必要があります。ここでは、1 vCPU・RAM 1,024MBのサーバーを例に設定を見ていきます。
php-fpmには約512MBを割り当て、残りをデータベースとnginx用に確保するとよいでしょう。
設定ファイル/etc/php-fpm/www.confに以下を追加します。
pm.max_children = 18— 子プロセスの最大数pm.start_servers = 6— 起動時に作成される子プロセスの数pm.min_spare_servers = 4— アイドル状態のサーバープロセスの最小数pm.max_spare_servers = 16— アイドル状態のサーバープロセスの最大数pm.max_requests = 400— 子プロセスが再起動されるまでのリクエスト処理回数
MariaDBの最適化設定については、当サイトの関連記事で詳しく解説しています。筆者もその記事をもとにmy.cnfのパラメータを自分のプロジェクト向けに設定しましたが、データベースは優れたパフォーマンスを発揮しています。
サイトを運用してみると、nginx + php-fpmの組み合わせがapache2 + mod_phpよりもはるかに高速にリクエストを処理し、Webページを返していることが一目でわかるでしょう。
-
UbuntuにNginxをインストールして設定する完全ガイド
Webアプリケーションは、ここ数年でさまざまなクライアントへサービスを提供する手段として大きく普及しました。Webアプリケーションを活用すれば、ユーザーがどんなデバイスやOSを使っていても、より多くの層にアプローチできます。 Webサーバーをインストールし、適切に設定できるスキルは、Web開発者にとってもソフトウェアエンジニアにとっても非常に価値のあるものです。Webサーバーとは、インターネットやネットワーク経由でクライアントにWebコンテンツを配信する役割を担うプログラムのことです。 この記事では、UbuntuにNginx Webサーバーをインストールして設定する方法を詳しく解説します。 な
-
Linuxサーバーで高トラフィックのWebサイトに対応させるApacheとPHPの構成方法
LAMPスタック(Linux、Apache、MySQL、PHP)のインストール手順を解説するチュートリアルのほとんどは、PHPスクリプトの処理にApacheの組み込みモジュールを使うことを推奨しています。例えばUbuntuでは、sudo apt install libapache2-mod-phpというコマンドでパッケージをインストールした時点でこの設定が有効になります。その結果、Apacheはmpm_preforkを使用せざるを得なくなり、訪問者がサイトにアクセスするたびに新しいプロセスが起動されて接続を処理することになります。トラフィックが少ないうちはこれでも十分に機能します。しかし、アク