仙石浩明の日記

2006年6月29日

jabber サーバの死活確認スクリプト

jabber.jp と Google Talk との相互接続開始」で jabber.jp の紹介をしたのが原因というわけでもないのだろうが、 一時的に jabber サーバが過負荷になってサービス不能状態に陥ってしまった。 この jabber.jp は KLab のサーバマシン群の中では低性能なマシンを使っていたので、 この機会にと、もう少しマシなマシンへ引越しさせた。 が、負荷の問題というよりは、サーバプログラム自体に、 なにかのタイミングでハングするバグがあるようだ。 他のソフトウェアへの乗り換えも含めて対策を検討中であるが、 とりあえずハングしていないかの死活確認は必須だろう。

まず CPAN から Net::Jabber をインストール。 「Google Talk を流れるデータを見る」に、
「Net::Jabberは,インストールしようと思ってもmake testでひっかかってしまってうまくインストールできません.」と書いてあったのが 気になりながら (^^;) 作業していると...

cpan> install Net::Jabber(改行)
        ...
---- Unsatisfied dependencies detected during [R/RE/REATMON/Net-XMPP-1.0.tar.gz] -----
    XML::Stream
Shall I follow them and prepend them to the queue
of modules we are processing right now? [yes] (改行)
Running make test
        ...
t/buildxml......ok
t/load..........ok
t/parse_node....ok
t/parse_tree....ok
t/tcpip.........ok
t/tcpip2ssl.....ok 2/3

ありゃ、止まってしまった。 XML-Stream-1.22/t/tcpip2ssl.t を見ると、

my $status = $stream->Connect(hostname=>"obelisk.net",
                              port=>5223,
                              namespace=>"jabber:client",
                              connectiontype=>"tcpip",
                              ssl=>1,
                              timeout=>10);

などと書いてある。 つまり、jabber サーバである「obelisk.net」を相手に 接続テストを行なおうとして止まってしまっている。 おそらく obelisk.net が相手にしてくれないのだろう (5222番ポートの方は相手をしてくれるようだ)。 とりあえず obelisk.net の代わりに手元の jabber サーバを指定して、 テストを成功させ、無事インストール完了。

とりあえず、さくっと死活確認スクリプトを書いてみる:

#!/usr/bin/perl
@RCPTS = ('jabber-error@gcd.org',);
use Net::Jabber qw(Client);

&ckjabber("jabber.gcd.org", 5222, "test", "XXXXXXXX", "ckjabber.$$");
&ckjabber("jabber.jp", 5222, "test", "YYYYYYYY", "ckjabber.$$");

sub ckjabber {
    my ($server, $port, $username, $password, $resource) = @_;
    my $client = new Net::Jabber::Client();
    my $connected = 0;
    my $authenticated = 0;
    my $recv_subject;
    my $recv_body;
    my $subject = "check $server";
    my $body = "This is a test message from $resource.";
    my $onConnect = sub { $connected++; };
    my $onAuth = sub {
        $authenticated++;
        $client->MessageSend(to => "$username\@$server/$resource",
                             subject=> $subject, body => $body, );
    };
    my $onMessage = sub {
        my ($sid, $message) = @_;
        $recv_subject = $message->GetSubject();
        $recv_body = $message->GetBody();
        $client->Disconnect();
    };
    $client->Connect(hostname => $server);
    $client->SetCallBacks(onconnect => $onConnect, onauth => $onAuth,
                          message => $onMessage, );
    $client->Execute(username => $username, password => $password,
                     resource => $resource,
                     hostname => $server, port => $port,
                     register => 1,
                     connectsleep => 0, connectattempts => 1, );
    my $error;
    if (! $connected) {
        $error = "can't connect to $server";
    } elsif (! $authenticated) {
        $error = "authentication failure";
    } elsif ($recv_subject ne $subject || $recv_body ne $body) {
        $error = "get '$recv_subject' & '$recv_body'";
    }
    if ($error) {
        print STDERR "$server error\n$error\n";
        &mail("$server error", localtime(time) . "\n$error\n", @RCPTS);
    }
}

sub mail {
    my ($subject, $body, @rcpts) = @_;
    open(INJECT,"|/var/qmail/bin/qmail-inject " . join(" ", @rcpts)) || die;
    print INJECT "From: root\nTo: ", join(", ", @rcpts), "\n",
        "Subject: $subject\n\n$body";
    close(INJECT);
    if ($? << 8) {
        print STDERR "Fail to send mail to ", join(", ", @rcpts), "\n";
        exit 1;
    }
}

自分自身にメッセージを送ってみて、 同じ文面が返ってくるか確認するだけの単純なテストスクリプトだが、 jabber サーバがハングしたら検知してメールを送ってくれるだろう。 とりあえず 5 分に一度実行するように cron に仕掛けた。

Filed under: システム構築・運用 — hiroaki_sengoku @ 07:44

No Comments »

No comments yet.

RSS feed for comments on this post.

Leave a comment