1

Perl スクリプトをサーバー上で安定して実行できません。これが問題です。

スクリプトが 1 秒間に 5 回以上アクセスされると、サーバーがフリーズします。そしてしばらくすると、サーバーが永久にハングします。SSH が応答しないため、サーバーを再起動する必要があります。

でApacheを使用していmod_perlます。

スクリプトは、Ubuntu の下の仮想専用サーバーでホストされます。SSHで操作しています。これらはサーバー パラメータです CPU: 400 MHz RAM: 256 MB

スクリプトの最大実行時間は 200 ミリ秒です。

「top」ユーティリティを使用してサーバーの負荷を監視しました。問題は表示されません。これは、1 秒あたり 5 つのスクリプトのロード中の CPU 統計です。

CPU: 12.1%us、0.6%sy、0.0%ni、0.0%id、0.0%wa、0.0%hi、0.0%si、87.2%st

スクリプトを問題なく動作させるために必要なオプションは何ですか?

これは、ps aux | fgrep perlロードの瞬間の結果です。

ps補助 | fgrep パール
www データ 2925 0.3 6.5 45520 17064 ? R 17:00 0:01 /var/www/perl/loa -k start
www データ 2926 0.2 6.5 45520 17068 ? R 17:00 0:01 /var/www/perl/loa -k start
www データ 2927 0.4 6.5 45676 17060 ? R 17:00 0:01 /var/www/perl/loa -k start
www データ 2928 0.3 6.5 45676 17060 ? R 17:00 0:01 /var/www/perl/loa -k start
www データ 2929 0.2 6.5 45676 17060 ? R 17:00 0:01 /var/www/perl/loa -k start
www データ 2931 0.4 6.5 45740 17076 ? R 17:00 0:01 /var/www/perl/loa -k start
root 2968 0.0 0.2 3196 656 ポイント/0 R+ 17:06 0:00 fgrep perl

アップデート

ボトルネックを発見しました。コードの周りでDateTimeモジュールを何度も使用しています。次の DateTime モジュール メソッドは非常に遅いようです。

  • 新着()
  • 今()
  • 設定(...)
  • デルタ_ミリ秒(...)

それらを高速なアナログに置き換えます。

もう一つの懸念。mod_perl インスタンスは大量のメモリを消費します。そして、私には理由がわかりません。モジュールをインポートしない単純な perl スクリプトを実行しようとしました。Apacheの再起動直後に実行します。スクリプトは 37M のメモリを必要とします。なぜそれが起こるのですか?mod_perl が余分なメモリを使用しないようにする方法を知っていますか?

mod_perl をサポートしない通常の perl スクリプトは、3 ~ 5M のメモリを必要とします。

みんな、本当に助けてくれてありがとう、こんなに素晴らしい反応を期待していなかった!

更新 2

もう1つの事実を見つけました。5 秒間待機するだけの単純な perl スクリプトを作成しました。

#!/usr/bin/perl
use CGI;

my $query= new CGI;
my $content = "5 second delay...\n";

$query->header(
    '-Content-type' => "text/plain",
    '-Content-Length' => length($content)
);

print $content;

sleep(5);

次に、これらのスクリプトを同時に多数生成します。トップ ユーティリティのステルス時間 (st) は 0% から 80% に跳ね上がり、スクリプトが完了するまで高いままです。

この負荷はどこから来るのですか?

また、すでに述べたように、各 perl インスタンスは 36M のメモリを必要とします。

4

4 に答える 4

5

からの数値はtop、VM 外の他のプロセスが CPU を調整していることを示しているようです。最後の数値87.2%stに注意してください。これは、CPU 時間の約 87% がハイパーバイザーによって VM 外のタスクに割り当てられていることを示しています。 VM には、実行したいものがあります。これがあなたの問題に関連しているかどうかはわかりません。

unwindで提案されているようにサーバーをアップグレードするだけでなく、 zoulで提案されている永続的なプロセス環境を使用すると、プロセスが CPU バウンドではなく、ネットワークやディスク アクセスなどの IO バウンドである可能性があります。メモリバウンド。スクリプトが呼び出されたときに実際に何を行っているかについての詳細がなければ、なんとも言えません。

編集:各プロセスが45MのRAMをすべて必要とし、さらに17Mを共有しているため、メモリ使用量に関する情報を含む更新された質問が明らかになりました。5 つまたは 6 つのプロセスが実行されているだけで、使用可能な RAM の量を超えています。これはバニラの Perl スクリプトが使用するのに十分な量のメモリですが、それで何をしているのでしょうか?

于 2009-10-09T13:09:10.523 に答える
3

それは非常に大きなサーバーではありません。Perl インタプリタを生成するだけでひざまずくのでしょうか? perl (喜んで 1 MB 以上だと思います) を 1 秒間に 5 回ロードすると、負荷がかかりすぎる可能性があります。

もちろん、キャッシュする必要がありますが、実行するには初期化が必要です。

于 2009-10-09T12:46:50.890 に答える
1

今日の基準では、サーバーの仕様は印象的ではありませんが、同様のハードウェアでかなり複雑なものを同時に実行しました。ただし、必要最小限の FreeBSD 構成のみを実行するようにしました。(ArchLinux を使用して達成できることと同様)。多くのカスタム構成を行っておらず、それらの仕様に対して重すぎる可能性があるUbuntuのデフォルトを受け入れたと思います。

現在、Linode 360​​ で遊んでいますが、パフォーマンスは良好です。

さて、これはすべて明白なことを述べるためのものです: 私たちはあなたが私たちと共有していないあなたが持っている情報を必要としています. Web サーバーの構成、スクリプト + インタープリターのメモリ フットプリント、開いているファイルの数など。まだ問題が発生している最小のスクリプトを提供するか、より多くの情報を提供してください。

更新:あなたが使用していることがわかっmod_perlたので:1)スクリプトに必要なすべてのライブラリがサーバーの起動時にプリロードされていることを確認しましたか?2)variable won't stay sharedログにメッセージはありますか? 3) mod_perl Performanceを読みましたか? ( Chapter 10: Sharing Memoryは特に関連があるかもしれません)。

一般に、Apache サーバーの起動時に共通ライブラリをプリロードする必要があります。非常に単純化された経験則として、より多くのものが共有されているほど、サーバーからより多くのものを引き出すことができます. 実用的な mod_perlのスタートアップ ファイルを参照してください。

さらに、サーバーあたり 35MB は少し多いと思います。不要なモジュールを Apache 構成から削除すれば、それを削減できると思います。ただし、35MB がすべて共有されていて、最大の子プロセスが 50MB であると言えなくても、一度に約 20 のクライアントに対応できるはずです。

あなたがテストしているスクリプトに気付きました。CGI本当に、次の行を に追加して、サーバーの起動時にプリロードしてみてくださいstartup.pl

use strict;
use warnings;

use CGI();

次に、そのスクリプトを次のように変更します

#!/usr/bin/perl

use strict;
use warnings;
use CGI ();

$| = 1;

handle_request();

sub handle_request {
    my $cgi = CGI->new;

    my $content = "5 second delay...\n";

    print $cgi->header('text/plain'), $content;

    sleep(5);
}

元のスクリプトではヘッダーを送信していないことに注意してください (CGIインスタンスの呼び出しも嫌いな$queryので、自由に変更することもできました)。Perl リファレンスも参照してください。

その後、メモリ使用量を報告します。

最後に、なぜ5秒間寝ているのですか?私の知る限り、Apache のスクリプトのデフォルトのタイムアウトは 3 秒です。

于 2009-10-09T13:11:15.950 に答える
0

スクリプトはどのようなインターフェイスを使用しますか? perlたとえばFastCGIを使用して、実行可能ファイルを何度も実行することを避けることができれば、確実にパフォーマンスが向上します。

于 2009-10-09T12:50:26.717 に答える