VPSの欠点


ちょっと長くなっちゃった…。

VPS(Virtual private server)は1台のサーバに複数の仮想サーバを起動させて、それをお客さんに提供する仕組みなので、1台の実サーバを用意するよりも安価でいいのですが、1台のサーバでたくさんの仮想サーバが動くのでリソースの制限がなかなかにきついです。
しかも安価なVPSであればあるほど、リソースの制限はきびしぃ。
リソース制限の例として、回線(帯域)、メモリ、CPU、同時起動プロセス数、同時オープンファイル数、TCPの同時接続数と色々あるわけですが、今回取り上げるのは「同時起動プロセス数」。
同時起動プロセス数はその名のとおり、同時に起動できるプロセスの数であり、VPSではこの値が通常のサーバよりもかなり低く設定されている。
このあたりの数値はレンタルサーバによっては、普通に公開されていて、低いところだと60とか、上位プランになれば100とか300とか増えていく。
ちなみにこのサイトが動いているサーバ(正確にはVPSじゃなく、もっと安い共用サーバなんだけど)の、同時起動プロセスは30程度だったりする(もうちょっとあったかな?)。

で、この同時起動プロセスがあまり高くないVPSに、万を越えるメールを一気に送りつけるとだ、どうなるかというと一瞬でプロセスが全て食い尽くされる。例えばプロセス上限が70としたら、70プロセスが常に立ち上がりっぱなしになる。
こうなるとこのVPSに対しては何もすることが出来ない。いや、正確に言うと「プロセスが増える(forkする)処理が伴う、処理」は全て実行できない。
※named(bind)とかの応答は別にプロセスがforkするわけじゃないので、DNSサーバとかは普通に機能する。
困るのは(例外もあるけど)Web、ftp、mail、ssh、telnetとか。というか主要サービスほぼ全てorz
apacheとかはworkerプロセスとかで動かせば大丈夫かもしれないけど、残念ながらたいがいのapacheはpreforkなんです。

それでプロセスを食いつぶされていたら、その原因となっている処理を止める必要があります。メールが大量に送られている場合はsendmailを一時的に止めるとか。
VPSは基本的に外のレンタルサーバから借りてる事がほとんどなので、sendmailを止めるにはまずVPSに対してssh接続をする必要があります。そのとき第一の関門があって、ssh接続もプロセスをforkする処理のため、それ以上プロセスが増やせずに処理に失敗してつながりません\(^o^)/
ただ、プロセスは常に上限に達しているわけではありません。メール受信の嵐の中でも、メールのキュー処理の嵐の中でも、処理は確実に進められています。自分の役割が終わったプロセスはそのまま終了し、同時起動プロセス数に1つ空きができます。そして間髪いれずに次のメールが送られてきたり、メールのキュー処理が始まり、空いたプロセスがすぐに埋まります。
そう、狙うはプロセスが落ちた瞬間。その空いたプロセスは誰のものでもない。早い者勝ち。次のメール要求が来るよりもはやく、ssh接続を行えばよい。
そうするとssh接続が出来る。

…が、悲しい事にssh接続処理中に多分2回くらいプロセスのforkする処理がはいってるっぽい(中の詳しい動きはよくしらない)。なので、2回程、他のプロセス終了の瞬間をばっちり狙う「運」が必要ってことです。
これは非常に確立が低い。
ちなみにtelnet接続もforkしますが、こっちは1回のforkでOKっぽいので、sshより接続できる可能性はぐっと高い。
ただ、こちらは最近の動向ではtelnet利用禁止になる動きがつよく、肝心なときにそもそも利用できない事が多い。でも、ほんとプロセス食いつぶしたときのtelnetは頼みの綱だと個人的に思う。使えないけどorz

と、サーバにログインするところから大変なのですが、運良くssh接続する事ができたとします。とりあえず現状のリソースはどうなってるかと、psやtopコマンドを実行しようとすると、こんな感じのエラーがでて動かない。

No more processes.

psとかも1プロセス立派に使います。なので、これも他のプロセス終了の瞬間を狙わないといけません。狙うというが、ひたすらpsコマンドを連打するしかないんだけども。
ちなみにほとんどのコマンドがなかなか実行できません。lsとかlessとかcatとかnetstatとか全部アウト。
シェル内臓のコマンドになるcdとかechoなら動くので、lsの代用は「echo *」でなんとななったりする裏業もあったりします。

psでなんとかプロセスを見る事が出来て、sendmailが大量に起動しているようでしたらとりあえずsendmailプロセスを止めましょう。で、sendmailを止めるコマンドを入力。

No more processes.

まぁ動かないんですよ。しかもsendmailのようなデーモンを止めるコマンドは基本的にスクリプトの塊りで、コマンドの中でも別のコマンドを実行していたりしてます。つまりこれはpsやtopみたいな単純なコマンドに比べて、更に「運」が必要です。というか多分無理、動かない。経験者は語る。

デーモンの再起動がだめならじゃぁOSの再起動だっ。って事で「reboot」実行!

No more processes.\(^o^)/

これはもう説明する必要もないですね。
デーモンの停止もOSの再起動も難しいので次はどうするか?次は問題を起こしているプロセス、つまり今の例ではsendmail。こいつをkillコマンドで殺します。
デーモンの停止コマンドで丁寧にsendmailの停止なんてやってられません。なんど実行しても動かないし。
kill プロセスID で基本的にプロセスは落ちますが、落ちないときはkill -KILL プロセスID でもっと強制的に落とします。
sendmailの場合、メールのロストとかの可能性もありそうで怖いのですが、背に腹は変えられません。多分、sendmailも長年のノウハウの積み重ねで極力メールのロストをしないような設計になっているはずなので、きっと大丈夫なはず。うん。

killで問題のプロセスを落とす事ができたら、同時に起動しているプロセスもかなり減って、快適に各コマンドを実行できるようになります。その間に色々とプロセスを増大させない対策をします。
メールの大量受信が原因だったら、こんな感じでいくつか対応方法がありそう。

・送信元のメールサーバに大量配信をやめてもらう(これは事前にお願いしててもいいかな)
・大量に発生したメールのキューでいらないのを消す
・大量配信元のメールサーバからの受信を拒否するようにiptablesに記述
・問題のユーザ宛のメールを一時的に/dev/nullに行くように仕向ける
・問題のユーザを消してみる

対策が終わったらsendmailを改めて起動。あとプロセス数が頭打ちした歳、変なゾンビプロセスとか残っている可能性があるので、可能なら一度VPSの再起動をしたほうがいいかも。

と、気づいたら長くなってしまったけど、これはVPSにおける最大の欠点だと思う。ssh接続をしたいのに出来ないジレンマ、やっと接続できたのにコマンドが実行できないジレンマ、その間に発生するお客からの問い合わせ。

でも、VPSは安いんだよなぁ。。。うん。

作成日:2009/09/10 02:49:27
トラックバック  ※トラックバックは承認後に表示されます。
TrackbackURL:このページのトラックバックの受付は終了しています。

トラックバックはありません。
コメント
1
うほホッパ@徳川店員 10Sep2009 09:05AM
わけわからんwww
先日、北海道から戻ってまいりますた。
さて・・・今日から働くか・・・。
2
sendmailは使わないかっし~ 12Sep2009 01:12PM
あえてsendmailをつかっている意味がわからんのですがその辺詳しく
Postfix使っていればプロセス数の制限もできるし、流通速度の制御とかも出来たり
同時起動プロセスが制限されているサーバであればそれなりのサービスの仕方にしかならないと思うんですけどね
外的要因によってプロセスの起動されるデーモンは大概プロセス数を指定できると思うんですけどsendmailはできないのかな?
3
そうし 13Sep2009 01:55AM
> 徳川店員
呪文のごとき日記ですまぬw
おぉ、北海道に帰ってたのですね。
北海道の大自然は徳さんの疲れた体を大いに癒してくれたと思います。
お仕事ファイトですっw

> かっし~
sendmail使っている理由かぁ、それは実に簡単で、VPSサービス独自の管理ツールと連動しているので、簡単にpostfixに変更できないという理由です。
管理ツールを捨てればpostfixに出来なくはないけど、管理する人は自分だけでもないし、VPSもひとつではないからね。
もうリスクは覚悟して使うしかない。
言い方は悪いけど安かろう悪かろうって感じかな。。。
ちなみにsendmailでもプロセス制御できるはず。前に調べた。

あと話はpostfixにずれるけど、postfixのメール送信制御はもう一歩。同一ドメインに対するメール送信の制御がもうちょっと細かくなればうれしいんだけどなぁ。。。
(同時接続数は制限できるけど、1分間に5通以内といった制御はできないはず)
って最近postfixの最新版追っかけてないので、もしかしたら実装しているかも。
名前:

タイトル:

コメント: