web-dev-qa-db-ja.com

Apacheがサーバー全体をクラッシュさせないようにする方法は?

Apacheを含むいくつかのサービスを備えたGentooサーバーを維持しています。それはかなりローエンドです(2GBのRAMと2コアのローエンドCPU)。私の問題は、私の最善の努力にもかかわらず、オーバーロードされたApacheがサーバー全体をクラッシュさせることです。事実、この時点で私は、Linuxが恐ろしいオペレーティングシステムであり、負荷がかかった状態で安定性を探すのに時間をかける価値がないと確信しているところです。

私が試したこと:

  1. ルートApacheプロセス(およびそのすべての子)のoom_adjを調整します。それはほとんど効果がありませんでした。システムが何かを殺す前にシステムが他のすべてをページアウトしたため、Apacheが過負荷になると、システムはGrindに移行します。
  2. スワップをオフにします。助けにはならなかった、それは/のプロセスと他のファイルのバイナリにページングされたメモリをアンロードし、同じ効果を引き起こしました。
  3. メモリが制限されたcgroupに配置します(512 MBのRAMに制限され、合計の1/4)。これは、少なくとも私自身のストレステストでは「機能しました」-負荷がかかったままサーバーがクラッシュし続ける(基本的に他のすべてのプロセスが停止し、SSH経由でアクセスできないなど)
  4. アイドルI/O優先度で実行します。ディスクのバッファリングされていない部分にアクセスしようとするまでは、システム負荷が無限に(数千に)上昇し、ほとんど目に見える効果はありませんでした。これにより、タスクがフリーズしました。 (良いI/Oスケジューリングにはこれで十分ですか?)
  5. Apacheへの同時接続数を制限する。設定する数が少なすぎると、ほとんどのスロットが長いリクエスト(ファイルのダウンロード)で占有されるため、Webサイトが応答しなくなりました。
  6. さまざまなApache MPMを試しましたが、あまり成功しませんでした(prefork、event、itk)。
  7. Prefork/event + php-cgi + suphpからitk + mod_phpに切り替えます。これによりパフォーマンスは向上しましたが、実際の問題は解決しませんでした。
  8. I/Oスケジューラーの切り替え(cfqから締切)。

これを強調するだけです。Apache自体が負荷でダウンしても気にしないで、システムの残りの部分を安定させておきたいだけです。もちろん、短時間の集中的な負荷の後、Apacheを迅速に回復させることは素晴らしいことですが、一度に1ステップです。

現在、私は人類がこの時代にそのような一見単​​純なタスク(1つのシステムコンポーネントがシステム全体をクラッシュさせないようにする)が実際には不可能であると思われるオペレーティングシステムをどのように設計できるか、または少なくとも非常に非常に困惑していますするのは難しい。

VMや「より多くのRAMを購入する」などの提案はしないでください。


友人の助けを借りて収集されたいくつかの詳細情報:cgroup oom killerが呼び出されると、プロセスがハングします。呼び出しトレースは次のとおりです。

 [<ffffffff8104b94b>]? prepare_to_wait + 0x70/0x7b 
 [<ffffffff810a9c73>] mem_cgroup_handle_oom + 0xdf/0x180 
 [<ffffffff810a9559>]? memcg_oom_wake_function + 0x0/0x6d 
 [<ffffffff810aa041>] __mem_cgroup_try_charge + 0x32d/0x478 
 [<ffffffff810aac67>] mem_cgroup_charge_common + 0x48/0x73 [._ ff>] 81 __lru_cache_add + 0x60/0x62 
 [<ffffffff810aadc3>] mem_cgroup_newpage_charge + 0x3b/0x4a 
 [<ffffffff8108ec38>] handle_mm_fault + 0x305/0x8cf 
?cff_81 schedule + 0x6ae/0x6fb 
 [<ffffffff8101f568>] do_page_fault + 0x214/0x22b 
 [<ffffffff813c7e1f>] page_fault + 0x1f/0x30 

この時点で、Apacheメモリーcgroupは実質的にデッドロックされており、syscallsでCPUを燃焼しています(すべて上記の呼び出しトレースを使用)。これはcgroup実装の問題のようです...

6

言いたくないのですが、あなたは間違った質問をしているようです。

これは、Apacheがサーバーを停止するのを止めるのではなく、Webサーバーに毎秒より多くのクエリを提供することです。問題が発生しないように十分です。リフレームされた質問への答えの一部は、高負荷でクラッシュしないようにApacheを制限することです。

その2番目の部分として、Apacheには設定可能ないくつかの制限があります- MaxClients は重要な構成です。これにより、実行できる子供数が制限されます。実行時間の長いプロセス(ダウンロードされる大きなファイルなど)でApacheの負荷を軽減できる場合、それはApacheのもう1つのスロットであり、PHPを提供できます。ファイルのダウンロードをPHPレイヤーで確認する必要がある場合でも、それを行うことができ、静的コンテンツ用にさらに最適化されたWebサーバーに NginXなどを使用してsendfile

一方、最も遅い方法を実行するためにすべての要求ごとにApacheをフォークするPHP-CGIとして(使用するApache MPMに関係なく))-マシンに大量の時間を費やさなくてもコードの実行mod_phpは大幅に最適化されています。

ApacheとPHPレイヤーが適切に最適化されている場合、PHPは大量のトラフィックを実行できます。昨日、2010年12月11日、たとえば、PHPサーバーのペア私は24時間で約1900万ヒットを実行し、そのほとんどは午前7時から午後8時までの期間でした。

ここには他にもたくさんの質問があり、ApacheとPHPの最適化に関する記事は他にもあります。Linux/ ApacheとPHPを非難する前に、まずそれらを読む必要があると思います。

7
Alister Bulman

運用Apacheサーバーを扱う場合、[〜#〜] [〜#〜]は、特にphpの場合、平均プロセスサイズを持っている必要があります。次のことをお勧めします。

  • プロセスの平均メモリ消費量を確認する
  • MaxClientsをAVERAGE_MEMORY/RAM_DEDICATED_TO_Apacheに調整します

ここで、RAM_DEDICATED_TO_Apacheは、TOTAL_RAMからマシンの残りの部分を必要とするRAMを差し引いた別の見積もりである必要があります(同じマシンで1つを実行している場合は、データベースに寛大である必要があります)。

Varnish を使用することをお勧めします。保存マシンの異なるポートで2つのサーバーを簡単に実行し、静的ファイルを専用ファイル(メディア)サーバー(lighthttpd、nginx)またはApacheにルーティングできます。ワーカーを含むインスタンスで、追加のモジュールはありません。そしてもちろん、ワニスで静的コンテンツをキャッチします。

負荷を分割しないと、同じ量のRAMを使用して静的ファイル(1 MB未満が必要)を配信するため、負荷を分割することが重要です。

すべてのRAMを消費しないようにする必要がある場合は、次の行を使用して、2分ごとに(考えられるように、それ以上またはそれ以上)実行する新しいcronjobをインストールし、50最小のRAMの任意の量に設定し、この数を少なくとも30以上に保ちます。サーバーを停止するには、いくつかのRAMが必要です。

vmstat -S M | tail -n 1 | awk 'BEGIN{ "date" | getline date }{if($4 + $6 < 50){ system("/etc/init.d/httpd stop"); system("/etc/init.d/httpd start"); print "Rebooting Apache  on " date >> "/var/log/Apache-reboots.log"}}'

これはRAMを制限する非常に厄介な(汚い)方法ですが、Apacheプロセスごとの平均メモリが本当にわからない場合や、ログファイル( "/ var/log /Apache-reboots.log ")、あなたはあなたのApache MaxClientsMaxRequestsPerChildThreadsPerChildをチューニングして、時間とチューニングで将来のハードリブートを回避する必要があります、あなたはサーバーの正確な構成を持っている。

4
cyraxjoe

あなたが試すことができるいくつかの一般的なこと:

  • 説明から、Apache/Linuxが実際にクラッシュしているのか、それともひどく過負荷になっているのかを見分けるのは困難です。サーバーの負荷が非常に高く、電源を入れ直すだけで効果的な対策を講じることができるサーバーがあると思います。実際のクラッシュの具体的な証拠がない限り、過負荷のサーバーとして問題に取り組みます。サーバーのパフォーマンスを最適化しても実際にクラッシュする場合は、その問題を見つけて対処することができます。
  • 一般的に、サーバー、特にApacheインスタンスが定期的にスワップにヒットするような状態になることは決してありません。サーバーが正常に動作しているが、トラフィックが数パーセント増加すると、スワップとロードスカイロケットの使用が開始され、サイトが遅くなったり、アクセスできなくなったりする、暴走する負荷状況にすぐに入ることができます。 Apacheがスワップを使用しないようにするには、最大クライアント/接続の数を減らすか、不要なモジュールを無効にすることでメモリ使用量を減らします。次のポイントも参照してください。
  • あなたは、Apacheの接続がファイルのダウンロードのような長いリクエストで使用されていると述べました。この問題を軽減するには、2番目のWebサーバー(lighttpなど)を使用して、Apacheがリクエストを転送/リダイレクトする静的コンテンツのみを提供します。これにより、Apacheの接続が解放されて重い作業が行われ、最大クライアント/接続の数を減らすことができます。
  • DoSを防ぐ必要がある場合は、故意であれ偶然であれ、インストールしてセットアップできるさまざまなApacheモジュールがあります。たとえば、mod_evasiveとmod_limitipconnを使用して、悪意のあるタイプのDoSを防ぐのに十分に機能しました。
  • ApacheまたはOSやアプリケーションの他の部分の最適化を却下しないでください。コンピュータはあなたが伝えたとおりのことをするのがとても上手なので、Apacheの設定で「このサーバーよりも多くのリソースを使用する」と書かれていれば、それはまさにそのとおりです。多くのソフトウェアと同様に、Apacheはさまざまなハードウェアとアプリケーションで適切に動作するように設計されていますが、両方に対して正しくセットアップする必要があります。デフォルトの設定は、シンプルでトラフィックの少ないWebサイトでのみ機能します。
  • 少し調整すると、サーバーが高負荷になっても、ログインして確認するのに十分な応答性があるバランスを見つけることができるはずです。この時点で、オプションは、キャッシングレイヤーの追加を含むアプリケーションのプロファイルと最適化、またはより良いハードウェアの取得のいずれかです。この手順は、Apacheを正しくセットアップした後で行う必要があります。
1
uesp

/ proc/sys/vm/overcommit_memoryを2に変更してみましたか?これは、ケネルがスワップ+使用可能なRAMの構成可能なパーセンテージ(proc/sys/vm/overcommit_ratio)よりも多くのメモリを割り当てないことを意味します。

その場合、ApacheはRAMを割り当てることができないために失敗しますが、openSSHなどのすでにロードされているサービスは引き続き機能します。

私はこれを試したことがなく、この設定を今発見しただけであることを付け加えておきます。私はもっ​​と知っている人から連絡をもらいたいです。それ以外の場合は質問に記載されているのとまったく同じ問題があるので、明日これをテストします。

1
ollybee

問題が見つかりました...

メモリ制限されたcgroup全体のoom_adjを15に設定すると、非常に愚かであることが判明しました。 cgroup内のすべてのプロセスの調整済みスコアはすべて1000になりました。cgroupがメモリを使い果たすと、システムはランダムプロセスを強制終了し、通常は正しく動作しませんでした。

oom_adjを設定する行を削除しただけで、システムクラッシュは発生していません。

1

これは少し遅れるかもしれませんが、私はOSを非難することは単に進むべき道ではないと言うことができます。 OSは、いくつかの異なるユースケースシナリオの期待に応えるように設計されているため、要件を満たすように構成する必要があります。

これだけでなく、システムがクラッシュするほどの負荷がかかっている場合は、システムを最適化するか、ネットワークを拡張する必要があります。

過度に最適化しすぎると、後で問題が発生する可能性がありますが、最初から何も最適化しないと、まったく同じ結果になる可能性があります。それはすべてバランスについてです。

ただし、目標はシステムのクラッシュを防ぐことであると主張しますが、ソリューションが機能しなかったと言い続けます。しかし、それらの一部didは機能し、結果に満足できませんでした。

メモリが足りなくなったら、スワップします。または物事がクラッシュします。 物語の終わり。スワップしたくない場合は、次のことを行う必要があります。

a)着信接続を制限します。これは人々をそらす効果があります

b)バックログに送信します。これは、サイトを遅くしたり、死なせたりする効果があります。

c)より多くのメモリを購入します。あなたがしたくなかった

d)ネットワークを拡張します。あなたもやりたくない

e)ロードバランス。 「D」によく似ています

注意深い最適化、微調整、および拡張なしでは、これらすべてのことを防ぐことはできません。

私の経験では、上記のすべてのきめ細かい組み合わせを使用することで、一般的には最終的に問題が解決することがわかりました。

まず、Apache2 + mpm_event + mod_fcgidを使用します。 Apacheが構成する必要があるほぼすべてのオプションを慎重に構成します。これを行うには1つの夜、そして正しくなるにはもう1つかかる場合があります。しかし、それはそれだけの価値があります。

着信接続を処理する準備ができているワーカーのプールが常に1つあることを確認し、それを拡大させますが、このプールにはある程度の制限を設けます。これは速度を犠牲にしますが、安定性をもたらします。

次に、両方のCGroups and IO Priority / CPU Priotiyを使用して、さまざまなサービスグル​​ープをさまざまな優先度にスケジュールします。

100%クリティカルなものは何でも、常にアクセスする必要があり、メモリのブロックが予約されており、より高いIOおよびCPU優先度が設定されています。設定するスクリプトを作成しますこれらの優先度は1時間ごとに発生するため、親が変更された場合、子供はこれらの優先度を継承します。

次にDNS、次にWeb、次にMailです。この順序で。このようにして、何かが正しく動作しない場合、より重要な要素が優先されます。

monitor software,を使用して、オンラインになっているかどうかを確認し、オンラインでない場合は再起動します。 X MBを超えるメモリをXサイクルで使用していて、サービスに接続できない場合(つまり、http://...:80で)、サービスを終了して再起動します。 XサイクルでX回以上再起動する場合は、タイムアウトします(手動検査を通知します)。たまに数人のユーザーを落とすかもしれませんが、少なくともあなたのシステムは安定したままです!

3番目に、専用サーバーがある場合、idはすべてのWebサイトサービスをseparate diskに配置します。 keep IO操作は主に別のコントローラー上で行います。

4番目に、mod_bwmod_qosなどのApacheモジュールを確認してください。 mod_bwは、仮想ホストごとの帯域幅を制限するだけでなく、mod_qos ...これはサービス品質モジュールであり、いくつかの問題を軽減するのに役立ちます。

本格的なQoSモジュールに期待されるものに加えて、DoSによるスロードの防止、NULL接続の制限などに役立ち、サーバーが同時接続の特定のしきい値に達したときにキープアライブをオフにすることもできます。

最後に、いくつかのintelligent caching front endsまたはload balancerを設定します。例:いくつかのVMインスタンスを使用し、多分VarnishまたはNGinxを使用し、静的ファイルを上流にキャッシュします。これにより、Apacheが静的コンテンツを提供するために必要なすべてのオープンスロットがオフロードされます。

あなたがたくさんのトラフィックを得たときにあなたが何が起こると期待するのか本当にわかりません。どちらも安定したままにしておきたいが、ストレスがかかった状態で機能を失いたくないし、何も最適化したくないし、ネットワークをアップグレードまたは拡張したくない。

さて、何も変更したくない場合、問題が解消されることをどのように期待しますか?

0
RapidWebs