Web Server
Web ServerはHTTPリクエストを受け付け、静的ファイルの配信やアプリケーションサーバーへのプロキシを担当します。 NginxとApacheのアーキテクチャの違いを理解することで、適切な設定とトラブルシューティングが可能になります。
Nginx vs Apache アーキテクチャ
┌─────────────────────────────────────────────────────────────────────────┐ │ Nginx (イベント駆動) │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Master Process (設定読込、Worker管理) │ │ │ │ │ ├── Worker Process 1 ─── Event Loop ─┬─ Connection 1 │ │ │ ├─ Connection 2 │ │ │ ├─ Connection 3 │ │ │ └─ ... (数千接続) │ │ │ │ │ ├── Worker Process 2 ─── Event Loop ─┬─ Connection N │ │ │ └─ ... │ │ │ │ │ └── Worker Process N (通常 = CPU core数) │ │ │ │ 特徴: 1 Worker = 数千接続、非ブロッキングI/O、低メモリ消費 │ └─────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────┐ │ Apache (プロセス/スレッド駆動) │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ 【prefork MPM】 【worker MPM】 │ │ │ │ Parent Process Parent Process │ │ │ │ │ │ ├── Child Process 1 ── Conn 1 ├── Child Process 1 │ │ ├── Child Process 2 ── Conn 2 │ ├── Thread 1 ── Conn 1 │ │ ├── Child Process 3 ── Conn 3 │ ├── Thread 2 ── Conn 2 │ │ └── ... │ └── Thread N │ │ │ │ │ 1プロセス=1接続 └── Child Process 2 │ │ メモリ消費大 ├── Thread 1 │ │ mod_php利用可 └── Thread N │ │ │ │ 1スレッド=1接続 │ │ preforkより効率的 │ └─────────────────────────────────────────────────────────────────────────┘
| 特性 | Nginx | Apache (prefork) | Apache (worker/event) |
|---|---|---|---|
| 処理モデル | イベント駆動 | プロセスベース | スレッドベース |
| 同時接続 | 数万接続可能 | 数百程度 | 数千程度 |
| メモリ/接続 | ~数KB | ~数十MB | ~数MB |
| 静的ファイル | 非常に高速 | 普通 | 普通 |
| 動的コンテンツ | FastCGI経由 | mod_php内蔵可 | FastCGI推奨 |
| .htaccess | 非対応 | 対応 | 対応 |
| 設定リロード | ダウンタイムなし | graceful restart | graceful restart |
Nginx 実践設定
基本構成
# /etc/nginx/nginx.conf
# Workerプロセス数(通常はCPUコア数に合わせる)
worker_processes auto;
# 1 Workerあたりの最大接続数
events {
worker_connections 4096; # デフォルト: 512
use epoll; # Linux: epoll使用
multi_accept on; # 一度に複数接続受付
}
http {
# ファイル送信最適化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# タイムアウト設定
keepalive_timeout 65;
client_body_timeout 60;
client_header_timeout 60;
send_timeout 60;
# バッファサイズ
client_body_buffer_size 128k;
client_max_body_size 100m; # アップロード上限
# Gzip圧縮
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
include /etc/nginx/conf.d/*.conf;
}リバースプロキシ設定
# /etc/nginx/conf.d/app.conf
upstream backend {
# ロードバランシング(デフォルト: round-robin)
# least_conn; # 最小接続数
# ip_hash; # セッション維持
server 127.0.0.1:8080 weight=3;
server 127.0.0.1:8081 weight=1;
server 127.0.0.1:8082 backup; # バックアップサーバー
# ヘルスチェック(Nginx Plus / OpenResty)
# health_check interval=5s fails=3 passes=2;
keepalive 32; # upstream接続をkeep-alive
}
server {
listen 80;
server_name example.com;
# アクセスログ
access_log /var/log/nginx/app_access.log;
error_log /var/log/nginx/app_error.log warn;
# 静的ファイル
location /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# アプリケーション
location / {
proxy_pass http://backend;
# 重要なヘッダー転送
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# タイムアウト
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# バッファリング
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 32k;
}
# PHP-FPM連携
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# FastCGIタイムアウト
fastcgi_read_timeout 300;
}
# ヘルスチェック用
location /health {
access_log off;
return 200 "OK";
}
}パフォーマンスチューニング
# システム設定(/etc/sysctl.conf) net.core.somaxconn = 65535 # listen backlog上限 net.core.netdev_max_backlog = 65535 # パケットキュー net.ipv4.tcp_max_syn_backlog = 65535 # SYNキュー # ファイルディスクリプタ上限(/etc/security/limits.conf) nginx soft nofile 65535 nginx hard nofile 65535 # Nginx Worker設定 worker_rlimit_nofile 65535; # Worker単位のFD上限
Apache 実践設定
MPM設定
# /etc/apache2/mods-available/mpm_prefork.conf
# mod_php使用時に必要(1プロセス=1リクエスト)
<IfModule mpm_prefork_module>
StartServers 5 # 起動時のプロセス数
MinSpareServers 5 # 最小待機プロセス
MaxSpareServers 10 # 最大待機プロセス
MaxRequestWorkers 150 # 最大同時リクエスト
MaxConnectionsPerChild 0 # 0=無制限(メモリリーク対策で設定推奨)
</IfModule>
# /etc/apache2/mods-available/mpm_event.conf
# PHP-FPM使用時に推奨(高効率)
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25 # 1プロセスあたりのスレッド数
MaxRequestWorkers 400 # 最大同時リクエスト
MaxConnectionsPerChild 0
</IfModule>VirtualHost設定
# /etc/apache2/sites-available/app.conf
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# ログ設定
ErrorLog ${APACHE_LOG_DIR}/app_error.log
CustomLog ${APACHE_LOG_DIR}/app_access.log combined
# ディレクトリ設定
<Directory /var/www/html>
Options -Indexes +FollowSymLinks
AllowOverride All # .htaccess有効化
Require all granted
</Directory>
# PHP-FPM連携(mod_proxy_fcgi)
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
# リバースプロキシ
ProxyPreserveHost On
ProxyPass /api/ http://127.0.0.1:8080/
ProxyPassReverse /api/ http://127.0.0.1:8080/
# タイムアウト
ProxyTimeout 60
</VirtualHost>
# mod_fcgid使用時(レガシー環境)
<IfModule mod_fcgid.c>
FcgidMaxRequestLen 1073741824 # 1GB(大容量アップロード)
FcgidIOTimeout 120 # I/Oタイムアウト
FcgidConnectTimeout 30
FcgidBusyTimeout 300
</IfModule>運用・トラブルシューティング
よくあるエラーと対処
502 Bad Gateway
原因: upstream(アプリサーバー)に接続できない
# 確認コマンド curl -I http://127.0.0.1:8080/health systemctl status php8.2-fpm tail -f /var/log/nginx/error.log | grep upstream
504 Gateway Timeout
原因: upstreamからの応答が遅い
# Nginx: proxy_read_timeout を延長 proxy_read_timeout 300; # PHP-FPM: request_terminate_timeout 確認 ; /etc/php/8.2/fpm/pool.d/www.conf request_terminate_timeout = 300
413 Request Entity Too Large
原因: アップロードサイズ上限超過
# Nginx client_max_body_size 100m; # Apache + mod_fcgid FcgidMaxRequestLen 104857600 # 100MB # PHP upload_max_filesize = 100M post_max_size = 100M
Too many open files
原因: ファイルディスクリプタ枯渇
# 現在の使用状況 ls /proc/$(pgrep -o nginx)/fd | wc -l cat /proc/$(pgrep -o nginx)/limits | grep "open files" # 上限引き上げ(/etc/security/limits.conf) nginx soft nofile 65535 nginx hard nofile 65535
設定変更の適用
# Nginx nginx -t # 設定テスト(必ず実行) nginx -s reload # graceful reload(ダウンタイムなし) systemctl reload nginx # systemd経由 # Apache apachectl configtest # 設定テスト apachectl graceful # graceful restart systemctl reload apache2 # systemd経由
監視すべきメトリクス
| メトリクス | 確認方法 | 閾値目安 |
|---|---|---|
| Active connections | /nginx_status | worker_connections × 80% |
| Request rate | access.log解析 | ベースライン比較 |
| 5xx error rate | error.log監視 | < 1% |
| Upstream response time | $upstream_response_time | p99 < 1s |
Nginx status module有効化
# /etc/nginx/conf.d/status.conf
server {
listen 127.0.0.1:8080;
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
}
# 出力例
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106選定ガイド
Nginxを選ぶケース
- ✓ 高トラフィック(10K+ 同時接続)
- ✓ リバースプロキシ/LB用途
- ✓ 静的コンテンツ配信が多い
- ✓ メモリリソースを節約したい
- ✓ コンテナ環境(軽量)
Apacheを選ぶケース
- ✓ .htaccessが必須(共用ホスティング)
- ✓ mod_rewrite等の複雑なルール
- ✓ レガシーmod_php環境
- ✓ Apache固有モジュールが必要
- ✓ 中小規模サイト
現代的な構成例
Internet
│
▼
CloudFront / ALB (SSL終端、キャッシュ)
│
▼
Nginx (リバースプロキシ、静的配信)
│
├─→ PHP-FPM (PHP)
├─→ Gunicorn (Python)
└─→ Puma (Ruby)