高負荷の時どうなる?どうする?

あくまで非力なH/Wでしかも1台しかない状況で一人しかいないんだけど色々都合があって24時間は貼り付いていられない状況で何とかしないといけないけどどうしたものかという人向けで。

負荷が高い状態でジャンジャンリクエスト受け付けてCPUくってswapくって瀕死になるっていうパターンでよくサーバーが落ちてる訳なんですが(落ちるというか応答不能)ロードアベレージが高い時には503(Service Unavailable)を返すようにしようかなと思案。

CPANで探したら
Sys::CpuLoad
というのが有ったんですがファイルかパイプ読む込むという作りになってたのでちょっといやだなぁと。
結局ダンコーガイ
BSD::getloadavg
でいってみます。

という訳でCGI作ってみました。(SWAPも考慮対象にしたいんだけどちょっと後回し)

load.cgi

#!/usr/local/bin/perl

use strict;
use warnings;

package Matsumo::Load;

use base qw(Class::Accessor);

use Sys::MemInfo qw(totalswap freeswap);
#use Sys::CpuLoad qw(load);
use BSD::getloadavg;
use CGI::Simple  ();
use Perl6::Say;

our $LA_MAX = 5;

sub q { return shift->{cgi_simple} \|\|= CGI::Simple->new() }

sub used_swap() {
    my $used = (Sys::MemInfo::totalswap() - Sys::MemInfo::freeswap()) / 1024;
    return int($used);
}

sub process {
    my $self = shift;
#    my ($load) = Sys::CpuLoad::load;
    my ($load) = getloadavg();
    if ($LA_MAX <= $load) {
        print $self->q->header('text/html', '503 Service Unavailable');
        print "<h1>503 Service Unavailable</h1>";
    } else {
        print $self->q->header('text/plain');
        say "Load Average : $load";
        say "Used Swap : @{[used_swap]} KB";
    }
}

package main;

Matsumo::Load->new->process;

ほんでぶっ叩かれそうな以下のコード実行でLAを上げて確認。よしよし。

$ perl -MClass::Accessor -e "push @list, Class::Accessor->new() while (1)"

という訳でこんな感じで仕込もうかどうか悩み中・・・・。
アラート上げるだけとかのが良いかなぁ。

まとめ
と書き終えた後にmod_loadaverage_actionという素晴らしいモジュールがある事を発見orz
http://blog.clouder.jp/archives/000722.html