シェアする

  • このエントリーをはてなブックマークに追加

[さくらのVPS]wordpressを動かしているhttpdが落ちまくる件を何とかした

先日こっそりこのブログを、
さくらのレンタルサーバ スタンダードからさくらのVPS512に移行しました。

その結果、遅かったページの表示速度が改善されて、管理画面も前よりもサクサクページが開くようになり、こりゃ快適でいいな?と思っていたのもつかの間・・・

動かした翌日の午前中にhttpdが突然ストップ!
翌日の朝6時頃に気付くまでHappyQualityが表示できなくなっていました…orz
すぐにサーバごと再起動して、その時点ではページは見られるようになりましたが、また昼ごろには同様の現象が起きてしまいました。

とりあえず何が起きているのかログをチェック。
その結果/var/log/messagesにoom-killerの嵐がw
これがその時のログ。

oom-killerの嵐

この時は何が起きているのかわからず正直怖かったですね。killerの文字が。殺し屋かと。

参考:OOM Killer – Linuxキーワード:ITpro

結局調べてみると、httpdがメモリを使いすぎてSwapまで食い尽くしてoom-killer発動!ってことでした。
なので、httpdが消費するメモリを節約するための施策をあれこれ試してみました。

この時点ではtopやpsも使わずに闇雲にいじってました・・・。

最終的な解決方法(ベストとは言えないと思うけど)だけを知りたい方はこちら

同時接続数の設定を見直す

とりあえず問題の張本人であるhttpd(apache)*[1] の設定ファイルを見直しました。
最初の設定は多分こんな感じ*[2]

/etc/httpd/conf/httpd.conf*[3]

<IfModule prefork.c>
StartServers 10
MinSpareServers 10
MaxSpareServers 30
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>

最初はよくわからなくて、topやpsもチェックしないでとりあえずネットに書かれているとおりに設定しました。
で、多分こんな感じにしました。

<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 20
ServerLimit 64
MaxClients 64
MaxRequestsPerChild 1000
</IfModule>

いらないモジュールを外す

最初、モジュールがデフォルトのまま読み込まれててほとんどがONの状態でした。
なので我らがさくらインターネットの社長の記事を参考に次のようにして見ました。

LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_alias_module modules/mod_authn_alias.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
#LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
#LoadModule authz_default_module modules/mod_authz_default.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
#LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
#LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
#LoadModule expires_module modules/mod_expires.so
#LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
#LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
#LoadModule dav_module modules/mod_dav.so
LoadModule status_module modules/mod_status.so
#LoadModule autoindex_module modules/mod_autoindex.so
LoadModule info_module modules/mod_info.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule cache_module modules/mod_cache.so
LoadModule suexec_module modules/mod_suexec.so
#LoadModule disk_cache_module modules/mod_disk_cache.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule mem_cache_module modules/mod_mem_cache.so
#LoadModule cgi_module modules/mod_cgi.so
LoadModule version_module modules/mod_version.so

雑でごめんなさい。詳細はウェブ開発者のための、1時間でできるLAMP環境構築術(CentOS編) – さくらインターネット創業日記で確認していただいたほうが間違い無いです。だって社長だもの。

mod_autoindexを無効にしたので、さくらインターネット創業日記に習って

<IfModule mod_autoindex.c> #ここからIfModuleで囲う
#
# IndexOptions: Controls the appearance of server-generated directory
# listings.
#
IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable

#
# AddIcon* directives tell the server which icon to show for different
# files or filename extensions.  These are only displayed for
# FancyIndexed directories.
#
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip

AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*

AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core

AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^

#
# DefaultIcon is which icon to show for files which do not have an icon
# explicitly set.
#
DefaultIcon /icons/unknown.gif

#
# AddDescription allows you to place a short description after a file in
# server-generated indexes.  These are only displayed for FancyIndexed
# directories.
# Format: AddDescription "description" filename
#
#AddDescription "GZIP compressed document" .gz
#AddDescription "tar archive" .tar
#AddDescription "GZIP compressed tar archive" .tgz

#
# ReadmeName is the name of the README file the server will look for by
# default, and append to directory listings.
#
# HeaderName is the name of a file which should be prepended to
# directory indexes.
ReadmeName README.html
HeaderName HEADER.html

#
# IndexIgnore is a set of filenames which directory indexing should ignore
# and not include in the listing.  Shell-style wildcarding is permitted.
#
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
</IfModule> #ここまで

しました。

もちろん編集後には

$ sudo service httpd restart

をお忘れなく。

とりあえず初日はここまでやって様子をみることにしました。

ダメ。全然ダメ。で、右往左往。

翌朝、やっぱり落ちてる。。。
ログを見ると夜0時ころには落ちてた模様。

前日の同時接続数を減らす施策も、ここまでやれば大丈夫だろうと(根拠もなくw)思っていたので、別のことが原因なんじゃないかと思って余計なことを幾つかやってしましました。ほんと余計なことなので解決策を求めて読んでいるなら飛ばしてもらって結構。熟練者が、こんな奴もいるんだー(藁)みたいに読んでもらえれば本望です。

余計なこと?その1?

httpd.confの中に気になる項目がありました。
その名もKeepAlive。

調べてみるとOnにするかOffにするか、色々と論争があるようです。
TCPコネクションを頻繁に切ったり繋いだりするよりも、繋いだままの方がいいんじゃない?と思ったのでOnにしてみました。だってOffだったから。

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

上記のように設定してみましたが、あまり変化がないような気がします・・・。
もっと調べる必要がありそうですが、後回しということで上記のままにしました。
次のサイトが参考になりそうです。

参考:keep-aliveのことをちゃんと考える | 株式会社インターオフィス

余計なこと?その2?

メモリが足りてないということはわかっていたので、じゃあPHPのメモリ使用量減らそうやwと考えました。

memory_limit = 64
↓
memory_limit = 16

あゝ、なんてチープな設定なの・・・とハンカチを涙で濡らしつつも背に腹は代えられないのでPHP4時代のlimitに設定。
ところがその途端、サイトが全く開かなくなってしまいました(笑)
ページを開いても真っ白。リロードを繰り返すとかろうじて5回に1回くらい表示されるという有様。

これはやりすぎたねと、次は32Mに。今度はページは表示されることが多くなりましたが、管理画面では相変わらず真っ白の割合が多い。特にダッシュボードはほとんど表示できませんでした。*[4]

これでは使い物にならないため、結局もとの64Mに戻しました。*[5]

余計なこと?その3?

php.iniの設定中に見つけたzlib.output_compressionの名前の響きだけでこれってイイんじゃね?って思ってOnにしてみました(笑)
compressionってなんとなく小さくしてくれそうな、節約してくれそうなイメージありません?

ということで、入れてみたんですが全然だめでした。WP-SuperCacheには怒られるし。
調べたらhttpの出力をgzip圧縮で出力することでした。余計メモリ食いそうですね。

闇雲にやってもダメだと知った

結局どれだけhttpdがメモリを使っていてどういうタイミングで落ちるのか調べないとダメだと思って、調べながらやってみました。

まず、プロセスが使っているメモリの使用量をtopコマンドでチェック
shift+m(大文字M)でメモリ使用量順にソートされます。

top - 22:40:25 up 11:15,  1 user,  load average: 0.01, 0.03, 0.00
Tasks:  91 total,   2 running,  89 sleeping,   0 stopped,   0 zombie
Cpu(s): 18.9%us,  1.2%sy,  0.0%ni, 78.9%id,  0.3%wa,  0.3%hi,  0.3%si,  0.0%st
Mem:    509792k total,   409552k used,   100240k free,     2668k buffers
Swap:  2048276k total,   243392k used,  1804884k free,    81996k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 8282 apache   15   0  315m  86m  35m S 23.0 17.5   0:03.41 httpd
 8286 apache   16   0  313m  84m  35m R 15.6 17.1   0:01.63 httpd
 7898 apache   15   0  313m  84m  35m S  0.0 16.9   0:09.06 httpd
 8280 apache   15   0  307m  79m  35m S  0.0 15.9   0:03.92 httpd
 8139 apache   15   0  306m  77m  35m S  0.0 15.5   0:05.88 httpd
 8046 apache   15   0  291m  62m  35m S  0.0 12.6   0:10.09 httpd
 8165 apache   15   0  312m  43m  35m S  0.0  8.8   0:03.27 httpd
 ・
 ・
 ・

調べてみて(゜o゜;
1プロセスあたり80M以上使ってる!
ということは7プロセスで560MB超え?*[6]

この時の感想はWordPressって凄いメモリを消費するんだなぁと。
で、ついでにtailf /var/log/access_logを開きつつtopを眺めて、実際にMenが枯渇しSwapを使い果たすところを目撃いたしました。

(キャプチャを取ってないので想像してみてください)

messagesログを見てみると見事にoom-killer発動!httpdは敢え無く帰らぬ人に。(帰ってくるけど)

最終的に落ち着いた設定

プロセスのメモリ、Swap使用量とアクセスログを見ながらhttpd.confの同時接続数を調整して、途中@yashiroさんのありがたい助言をいただきつつ、最終的に次のような設定に落ち着きました。

<IfModule prefork.c>
StartServers       5
MinSpareServers    5
MaxSpareServers    10
ServerLimit        16
MaxClients         16
MaxRequestsPerChild  100
</IfModule>

はじめに比べるとなんて貧祖な設定でしょう。
でもとりあえずこれで落ちることは無くなりました。
あとは、限界をチェックしつつ設定を緩くしていこうと思います。

またWordPressを動かすにはnginxのほうが断然いいということもわかったので、最終的にはnginx化することも検討したいと思います。

わかる方からすれば(某)「おまえは何を言っているんだ」ということなんでしょうけれども、僕も恥を偲んで書きました。

書いてある事の正しさは保証できませんが、悩み右往左往するさまを残すことで同じ悩みを抱えた方の助けに(主に精神面の。こんな奴もいるじゃんみたいな)なれれば良いなということと、あとで自分が見返したとき、自分の歩いた道程の長さ険しさに自ら賞賛を与えんがために書いたのです。

よって、この記事の内容は大して当てになりませんので自己責任でやってね♪ということでオチますか?お後がよろしいようで。

※この記事は酩酊状態で書かれた記事です。

クラウドテンプレート・ワードプレスプラチナプラン

  1. これなんでapacheじゃなくてhttpdになるの?慣れれば関係ないけど、最初は戸惑う気がするんだけど > 偉い人 []
  2. ログ見たわけじゃないけど多分こんな感じでした。今思えば完全に無茶です。 []
  3. (環境によって異なると思いますがボクはこう。わからなければ find / -name “httpd.conf” で探せます。 []
  4. 後でわかったことですがWordPress管理画面のダッシュボードって色々なデータを引っ張ってくるので、かなりサーバ側のメモリを喰うんですね。 []
  5. WordPressのように大飯食らいじゃなければ使える方法ではあると思います []
  6. この時ツイートで思いっきり計算間違っていたのは内緒w4 []

シェアする

  • このエントリーをはてなブックマークに追加

フォローする