[広告] Plesk + Nginx + wordpress + キャッシュ環境導入支援中
Plesk12でのNginx導入支援案件を頂く事が増えています。Plesk + Nginxの導入支援及びシステム保守を承ります。
前回の記事の続きから
前回の記事:Nginxのインストール 高速軽量WEBサーバー C10K
負荷対策大幅パワーアップ
前回の記事はNginxをインストールする為にシンプルに構築しましたので、これからはよりタフなサーバー構築を。
NginxとApacheの連携
前回の記事でApacheを停止させていましたが、今回はNginxを動かしつつ、Apacheも動かして連携させていきます。
Nginx+php-fpmの構造から
↓
Nginx+php-fpm+proxy cache+Apacheの構造へ
つまり、静的な部分はNginxで処理し、php-fpmでPHPを処理し出力したページはproxy cacheでキャッシュする。また、アプリケーションの実行、動的で複雑な部分はApache本来の役割に専念する。
○nginxユーザのファイルディスクリプタ制限数値を確認
# ulimit -Hn
4096
# ulimit -Sn
1024
@see ファイルディスクプリタとは何か
@see ユーザ空間とカーネル空間
Kernelチューニング
# vi /etc/sysctl.conf
※最終行に追加
#ファイルディスクリプタ制限をアップ
fs.file-max = 50000
開いているファイルの最大数制限の指定
# vi /etc/security/limits.conf
#<domain> <type> <item> <value>
#
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student – maxlogins 4
nginx soft nofile 10000 ←追加
nginx hard nofile 30000 ←追加
noproc 最大プロセス数
nofile オープンできる最大ファイル数
maxlogin 最大ログイン数
data 最大データサイズ
fsize 最大ファイルサイズ
as 最大メモリ空間サイズ
priority ユーザ実行の優先度
stack ユーザ実行の最大スタック
rss ユーザ実行プロセスのメモリサイズ
core コアファイルの最大値
soft/hardの違いは、softが一般ユーザが変更できる上限値で、hardはrootが変更できる
設定の反映
# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
error: “net.bridge.bridge-nf-call-ip6tables” is an unknown key
error: “net.bridge.bridge-nf-call-iptables” is an unknown key
error: “net.bridge.bridge-nf-call-arptables” is an unknown key
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.eth0.accept_ra = 0
fs.file-max = 50000←確認
Nginx全体ファイル編集
[bash] # For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
#worker_processes 1;
worker_processes 3;#CPU数を指定 autoはNginx内部判定に任せる
worker_cpu_affinity 001 010 100;#各CPUに均等に割り振る
pid /var/run/nginx.pid;#マスタープロセスpidを保存するファイル
worker_rlimit_nofile 102400;#ファイルオープン数
events {
worker_connections 5120;#同時接続数を設定 1つのworkerプロセグが開ける最大コネクション数
multi_accept on;#できるだけクライアントからのリクエストを受け取る
accept_mutex_delay 100ms;#ワーカプロセスがMutexを保持していない場合に再取得をまで待機時間。(default@500ms)
use epoll;#Linuxカーネル2.6以上の場合
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
#F5アタック対策
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 5;
keepalive_requests 500000;
client_max_body_size 25m;#POSTで送れる最大サイズ(default@1M)
connection_pool_size 256;
client_header_timeout 10;#クライアントタイム時間短く
client_body_timeout 10;#クライアントタイム時間短く
reset_timedout_connection on;#非アクティブクライアントのコネクションを閉じる
send_timeout 10;#クライアントへの送信タイムアウト
client_header_buffer_size 1k;
large_client_header_buffers 4 2k;
request_pool_size 4k;
if_modified_since before;
ignore_invalid_headers on;
server_tokens off;#エラー画面でバージョン非表示
output_buffers 1 32k;
postpone_output 1460;
#プロキシキャッシュ
proxy_cache_path /var/www/nginx_cache levels=1:2 keys_zone=czone:32m max_size=256m inactive=1440m;
proxy_temp_path /var/www/nginx_tmp;
proxy_hide_header X-Pingback;
proxy_hide_header Link;
proxy_hide_header ETag;
proxy_buffers 8 32k;#コネクション毎に8個の32KBバッファを生成 default@8 4k
proxy_buffer_size 64k;
proxy_connect_timeout 5;
proxy_send_timeout 10;
proxy_read_timeout 120;
proxy_cache_use_stale timeout invalid_header http_500 http_502 http_503 http_504;
#proxy_cache_lock on;
#proxy_cache_lock_timeout 5s;
server {
listen 80;
server_name localhost;
charset utf-8;
# location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO) {
# root /home/user/html/;
# index index.php index.html;
# ssi on;
# break;
# }
location / {
#F5アタック対策
limit_req zone=one burst=5;
proxy_pass http://127.0.0.1:8888;
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;
break;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#gzip on;
gzip_static on;
gzip on;#転送内容をgzipで圧縮
gzip_http_version 1.0;#圧縮httpバージョン
gzip_vary on;
gzip_comp_level 5;#圧縮レベル設定 1-9
gzip_types text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss;
gzip_disable “MSIE [1-6]\.”;#IE1-6の圧縮を禁止
gzip_disable “Mozilla/4”;
gzip_proxied any;#全てのプロキシも圧縮
gzip_buffers 16 8k;
#open_file_cache max=100000 inactive=20s;#キャッシュをオープンする同時に最大数とキャッシュ時間、20秒以上の非アクティブファイルをクリア
open_file_cache_valid 30s;#open_file_cacheの検知間隔時間をチェック
open_file_cache_min_uses 2;#open_file_cacheの非アクティブファイルの最小ファイル数
open_file_cache_errors on;#ファイルのエラー情報もキャッシュする
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
}
[/bash]
eventsディレクティブ内のuse epollについて
多重I/Oとは、複数のプロセスにread(recv)要求を行っている状況において
順番を気にせず、読み込みが完了したプロセスから順次読み込んだデータを使って処理する場合に使う。いわゆるイベント駆動型動作であり、一つでも読み込みが完了していれば
まだ読み込みが終了していないプロセスのread待ちによるブロックがない。例えば100プロセスとの通信で、ファイルディスクリプタを100個所持している状況を考えよう。
1つのプロセスからの入力を待って、入力が来たら、次のプロセスからの入力を待って、・・・として
全てのプロセスからデータを読み込むのは非常に非効率である。そこで100個のファイルディスクリプタを監視して、
読み込みイベントがあったファイルディスクリプタから先に処理ができるようにしたものが
多重I/Oである。多重I/Oを実現する手段として、Linuxにselecet(2),poll(2),epoll(2)がある。
selectは扱えるファイルディスクリプタ数に上限があるので、selectを使うならpollを使った方がよい(マシ)。
pollは扱えるファイルディスクリプタ数を無限にできる。
しかし、select,pollはファイルディスクリプタを一つずつループで見ていく方法で
ファイルディスクリプタを監視するのでO(n)の時間がかかる。一方、epollはファイルディスクリプタの数が無制限なのに加え、ディスクリプタの状態をkernelで管理するため
ファイルディスクリプタの状態が変わったものに対して直接通知ができる。つまり性能としては select<poll<epoll である。
@see epollの使い方
Nginxバーチャルホストファイル編集
# vi /etc/nginx/conf.d/あなたのドメイン.com.conf
[bash] upstream backend {
ip_hash;#同一IPのクライアントからは最初に振り分けたサーバーに振り分け
server 127.0.0.1:8888 max_fails=5 fail_timeout=15s;
##負荷分散する場合のサンプル
#server 192.168.1.3:8888 max_fails=5 fail_timeout=15s weight=5;#1:5:1:1で振り分けられる
#server 192.168.1.4:8888 max_fails=5 fail_timeout=15s;
#server 192.168.1.5:8888 max_fails=5 fail_timeout=15s;
}
server {
# ポートを指定
listen 80 default_server;
#サーバー名を指定
server_name あなたのドメイン.com www.あなたのドメイン.com;
if ($http_host = www.あなたのドメイン.com) {
rewrite (.*) http://あなたのドメイン.com$1;
}
# ドキュメントルート
root /home/あなたのドメイン.com/public_html/;
# インデックスファイル指定
index index.php index.html index.htm;
# 実ファイルがない場合のアクセスファイル パーマリンク対応
try_files $uri $uri/ /index.php?q=$uri&$args;
location ~ .*\.(jpg|JPG|gif|GIF|png|PNG|swf|SWF|css|CSS|js|JS|inc|INC|ico|ICO|flv|swf|mpg|html?) {
root /home/あなたのドメイン.com/public_html/;
index index.php index.html;
expires 30d;#30日でキャッシュ抹消
ssi on;
break;
}
location /wp-admin { proxy_pass http://backend; }
location /wp-login.php { proxy_pass http://backend; }
location / {
#パラメータ処理と404の処理@404
try_files $uri $uri/ /index.php?$args @webapp;#パラメータ処理がないか探索 それでもファイルがない時は404を返す為に内部リダイレクト先の@404
#携帯やスマホによってキャッシュ先を分岐
set $mobile “”;
if ($http_user_agent ~* ‘(DoCoMo|J-PHONE|Vodafone|MOT-|UP\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile
-converter)’) {
set $mobile “@ktai”;
}
if ($http_user_agent ~* ‘(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)’) {
set $mobile “@mobile”;
}
#Wordpressにログインしたユーザーはキャッシュしない
if ($http_cookie ~* “comment_author_|wordpress_(?!test_cookie)|wp-postpass_” ) {
set $do_not_cache 1;
}
proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;
proxy_cache czone;
#proxy_cache_key $scheme$proxy_host$uri$is_args$args;
proxy_cache_key “$scheme://$host$request_uri$is_args$args$mobile”;
proxy_cache_valid 200 301 302 10m;
proxy_cache_valid 200 1d;
proxy_pass http://backend;
## BASIC認証
auth_basic “Restricted”;
auth_basic_user_file /home/あなたのドメイン.com/.htpasswd;
}
## PHP-FPM 設定 末尾.phpのあるファイルについてfastcgiで処理
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
client_max_body_size 3M; #アップロードファイル容量を規定(デフォルト1M)
}
#ファイルが存在しない時の内部リダイレクト受ける先@404
location @404 {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location /contents {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
proxy_cache czone;
#proxy_cache_key $scheme$proxy_host$uri$is_args$args;
proxy_cache_key “$scheme://$host$request_uri$is_args$args$mobile”;
proxy_cache_valid 200 301 302 10m;
proxy_cache_valid 200 1d;
proxy_pass http://backend;
}
location /contents/wp-admin { proxy_pass http://backend; }
location /contents/wp-login.php { proxy_pass http://backend; }
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
[/bash]
Apacheと関連モジュールのインストール/設定
# yum install gcc httpd httpd-devel
# cd /usr/local/src
************************************************
※mod_rpafを使う場合 Apacheへのアクセスログに
NginxのIPが出るので私は非推奨
# mkdir mod_rpaf-0.6
# wget https://raw.github.com/ttkzw/mod_rpaf-0.6/master/mod_rpaf-2.0.c
mod_rpafインストール
# sudo /usr/sbin/apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c
# vi /etc/httpd/conf.d/mod_rpaf.conf
LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 10. 172.16.
RPAFheader X-Forwarded-For
************************************************
extract_forwardedだけでよい
# cd /usr/local/src
# wget http://www.openinfo.co.uk/apache/extract_forwarded-2.0.2.tar.gz
# tar zxf extract_forwarded-2.0.2.tar.gz
# cd extract_forwarded
extract_forwarded]# sudo /usr/sbin/apxs -i -c -a mod_extract_forwarded.c
# vi /etc/httpd/conf/httpd.conf
[bash] LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule version_module modules/mod_version.so
LoadModule extract_forwarded_module modules/mod_extract_forwarded.so←追加
[/bash]
#ServerTokens OS←無効化
ServerTokens Prod←追加
#ServerSignature On←無効化
ServerSignature Off←追加
#DocumentRoot “/var/www/html”←無効化
#
# Use name-based virtual hosting.
#
NameVirtualHost *:8888←行頭の#をとってポートも変更し8888
ポート有効化。
#Listen 80←無効化
Listen 8888←追加
#User apache←無効化
#Group apache←無効化
User nginx←追加
Group nginx←追加
※最終行に以下を追加
MEForder refuse,accept
MEFrefuse all
# Nginx(リバースプロキシ)のIPアドレス
MEFaccept 127.0.0.1
Apacheバーチャルホスト設定
また、リバースプロキシ外のアクセスは拒否する。
# vi /etc/httpd/conf.d/virtualhost_あなたのドメイン.com.conf
<VirtualHost *:8888>
ServerName あなたのドメイン.com
DocumentRoot /home/あなたのドメイン.com/public_html/
ErrorLog logs/virtual-error_log
CustomLog logs/virtual-access_log combined env=!no_log
#mod_rpafを使う場合は必要
#RPAFenable On
#RPAFsethostname On
#RPAFproxy_ips 127.0.0.1
#RPAFheader X-Forwarded-For
<Directory “/home/あなたのドメイン.com/public_html/”>
AllowOverride all
#リバースプロキシ外のアクセスは拒否
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Directory>
</VirtualHost>
<virtualhost *:8888>
ServerName www.あなたのドメイン.com
Redirect / http://あなたのドメイン.com
</virtualhost>
iptablesの設定【port8888を追加する】
# vi /etc/sysconfig/iptables
#New HTTP(Nginx upstream app Apache)
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 8888 -j ACCEPT
# service iptables restart
Apache起動
# chkconfig httpd on
# chkconfig httpd –list
httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
# service httpd restart
# service nginx restart
# service php-fpm restart
お疲れ様です。
なかなか大変ですが、静的な配信が得意なNginxと動的なものが得意なApacheと連携させる方法をご紹介させて頂きました٩(๑❛ᴗ❛๑)۶
Proxy cacheの削除方法
【キャッシュの削除】
# rm -rf /var/www/nginx_cache
# service nginx restart
nginx を停止中: [ OK ]
nginx を起動中:
【宣伝】Wordpressに最適化した高速WEBサーバーの構築
1000万PVオーバーのトラフィック対応
- トラフィックと予算に合わせた適切なサイジングで設計
- クラウドにも対応だから急な増設も安心
- 負荷分散 + トリプル高速キャッシュの軽量設計
- メディアサイト案件多し
- アダルトサイト対応可能
- コンサルティング/運用保守サポート
- DBの冗長構成、自律起動システム対応可能
どれだけ捌けるの?
いくらでも捌けます。可能な限りチューニングを行い、アクセスアップに応じて並列的にサーバーを増やして負荷分散 + 冗長構成を行うのでいくらでも。