<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10japanesefull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>blog.nomadscafe.jp</title>
    <link rel="alternate" type="text/html" href="http://blog.nomadscafe.jp/" />
    
    <id>tag:blog.nomadscafe.jp,2009-07-12://1</id>
    <updated>2010-07-30T14:44:58Z</updated>
    <subtitle>湘南新宿ラインで通勤する Web Engineer のBlog</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.27-ja</generator>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/nomadscafejp" /><feedburner:info uri="nomadscafejp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><logo>http://feeds.feedburner.jp/~fc/nomadscafejp?bg=99CCFF&amp;fg=444444&amp;anim=0</logo><entry>
    <title>Plackアプリケーションのリソースチューニングに必須。Plack::Middleware::ServerStatus::LIteをリリースしました</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/xYIp-kxC_Kc/plackplackmiddlewareserverstatuslite.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.51</id>

    <published>2010-07-30T14:39:50Z</published>
    <updated>2010-07-30T14:44:58Z</updated>

    <summary>以前「StarmanやStarletでmod_statusっぽい情報を得る簡易版...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>以前「<a href="http://blog.nomadscafe.jp/2010/07/starmanstarletmod-statusplackmiddlewareserverstatus.html">StarmanやStarletでmod_statusっぽい情報を得る簡易版Plack::Middleware::ServerStatus</a>」で書いていたPlack::Middleware::ServerStatus::LIteをCPANにリリースしました。</p>

<p><a href="http://search.cpan.org/dist/Plack-Middleware-ServerStatus-LIte/">http://search.cpan.org/dist/Plack-Middleware-ServerStatus-LIte/</a></p>

<p>前回と大きく実装が異なっている箇所があります。１つはプロセスの状態を保持するために<a href="http://search.cpan.org/~kazuho/Parallel-Scoreboard-0.02/lib/Parallel/Scoreboard.pm">Parallel::Scoreboard</a>を使うようになり、$0(PROGRAM_NAME)の書き換えを行わないようになったこと。２つ目はロケタッチを開発しているhideokiさんからの指摘で、アプリケーションが例外を起こしたときにステータスが戻らないという問題への対応をTry::Tinyを使って行っていることが大きな変更点です。</p>

<p>依存は増えましたが、実装は以下のようにシンプル</p>

<pre>
sub call {
    my ($self, $env) = @_;
    $self->set_state("A", $env);
    try {
        if( $self->path && $env->{PATH_INFO} eq $self->path ) {
            $self->_handle_server_status($env);
        }
        else {
            $self->app->($env);
        }
    } catch {
        die $_;
    } finally {
        $self->set_state("_");
    };
}
</pre>

<p>ただし、これだけだと一度もリクエストをさばいていないプロセスはステータス情報が全くなく、Parallel::Scoreboard->read_all()では取得できないので、子プロセスのPID収集のためにpsコマンドだけはそのまま使っています</p>

<p>psコマンドのオプションに方言があったり、Windowsで動かないとか問題はあると思いますので、パッチお待ちしています。</p>

<p>ServerStatus::Liteによるステータス情報は以下のようにとれます</p>

<pre>
 % curl http://server:port/server-status
 Uptime: 1234567789
 BusyWorkers: 2
 IdleWorkers: 3
 --
 pid status remote_addr host method uri protocol
 20060 A 127.0.0.1 localhost:10001 GET / HTTP/1.1
 20061 .
 20062 A 127.0.0.1 localhost:10001 GET /server-status HTTP/1.1
 20063 .
 20064 .
 </pre>

<p><a href="http://github.com/kazeburo/cloudforecast">CloudForecast</a>では、 Apacheで使うHTTPのリソース定義をそのまま使うことができますょ。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/plackplackmiddlewareserverstatuslite.html</feedburner:origLink></entry>

<entry>
    <title>Yokohama.pm #6でcloudforecastについて喋って来た</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/ri04VCO2owo/yokohamapm-6cloudforecast.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.50</id>

    <published>2010-07-26T14:50:22Z</published>
    <updated>2010-07-26T15:00:07Z</updated>

    <summary>Yokohama.pm#6 x Perl Casual#3でcloudforec...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>Yokohama.pm#6 x Perl Casual#3でcloudforecastについて時間を頂いたので喋ってきました。
すてきな会場を貸して頂いた<a href="http://www.naver.jp/">ネイバージャパン株式会</a>社さん、USTREAMを担当してくれた<a href="http://blog.kushii.net/archives/1390545.html">941</a>さんありがとうございます。</p>

<p>発表資料はこちら。</p>

<div style="width:425px" id="__ss_4842209"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/kazeburo/introduction-to-cloudforecast" title="Introduction to cloudforecast">Introduction to cloudforecast</a></strong><object id="__sse4842209" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=intro-cloudforecast-100726094115-phpapp01&stripped_title=introduction-to-cloudforecast" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4842209" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=intro-cloudforecast-100726094115-phpapp01&stripped_title=introduction-to-cloudforecast" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/kazeburo">kazeburo</a>.</div></div>

<p>もうすこし内容がんばって、リソース監視の面白さを伝えられるようにしたい。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/yokohamapm-6cloudforecast.html</feedburner:origLink></entry>

<entry>
    <title>キャッシュを制御してサイトの高速化を実現するAapcheモジュールmod_expiresのPlack版をリリースしました</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/tD1hnJ7SMqY/aapchemod-expiresplack.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.49</id>

    <published>2010-07-21T09:36:05Z</published>
    <updated>2010-07-21T09:41:46Z</updated>

    <summary>レスポンスヘッダにExpiresやCache-Controlを追加することで、ブ...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>レスポンスヘッダにExpiresやCache-Controlを追加することで、ブラウザのキャッシュを有効活用し、ダウンロードの時間をなくす事でウェブの高速化を実現できます。またサーバ側にとってもリクエスト数を減らす事ができ、負荷の削減にもなります</p>

<p>ApacheにはExpiresやCache-Controlを付加する<a href="http://httpd.apache.org/docs/2.2/en/mod/mod_expires.html">mod_expires</a>というモジュールがありますが、Plackにはまだなかったので作ってみました。VarnishのようにWebサーバ機能を持たないリバースプロキシを使う場合には、便利なんじゃないかなぁと思います</p>

<p>CPANにリリース済みです <a href="http://search.cpan.org/dist/Plack-Middleware-Expires/">http://search.cpan.org/dist/Plack-Middleware-Expires/</a></p>

<p>使い方</p>

<pre>
builder {
    enable 'Expires',
        content_type => [ 'text/css', 'application/javascript', qr!^image/! ],
        expires => 'access plus 3 months';
    enable 'Plack::Middleware::Static',
        path => qr{^/(favicon\.ico$|static/)}, root => './htdocs';
    $app;
}
</pre>

<p>content_typeでヘッダを付加するMIME typeを指定します。
pathを限定するために<a href="http://blog.nomadscafe.jp/2010/07/plackbuilderenable-ifmiddleware.html">Plack::Builder::Conditionals</a>(<a href="http://github.com/kazeburo/Plack-Builder-Conditionals">github</a>)と一緒に組み合わせたら便利かも</p>

<pre>
content_type => 'text/css'
content_type => qr!^image!
content_type => [ 'text/css', 'application/javascript', qr!^image/! ]
</pre>

<p>スカラ値、Regexp、もしくはそれらが入る配列のリファレンスを指定できます</p>

<p>expiresには、Apacheのmod_expiresと同じフォーマットでキャッシュの有効時間を入れます</p>

<pre>
expires => 'M3600' #最終更新時間 + 1時間(3600秒)
expires => 'A86400' # アクセス時間 + 1日
expires => 'modification plus 3 years 3 month 3 day' #最終更新時間 + 3年3ヶ月3日
expires => 'access plus 3 days' #アクセス時間 + 3日
</pre>

<p>などと書けます。最終更新時間はLast-Modifiedヘッダからとるため、Last-Modifiedヘッダが存在しないときには機能が働きません。</p>

<p>また、Expiresが有効となるのは、レスポンスのステータスが200系や300系の時だけで、エラー時には動きません。また既にあるExpiresヘッダを上書きしません。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/aapchemod-expiresplack.html</feedburner:origLink></entry>

<entry>
    <title>Plack::Builderのenable_ifよりも簡単に、指定した条件下でmiddlewareを有効にするモジュール </title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/2jbt__g91Ow/plackbuilderenable-ifmiddleware.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.48</id>

    <published>2010-07-15T16:04:51Z</published>
    <updated>2010-07-15T16:07:13Z</updated>

    <summary>CloudForecastや先日のNoPasteではPlack::Builder...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>CloudForecastや先日のNoPasteではPlack::Builderを使って、デフォルトの機能としてPlack::Middleware::ReverseProxyを有効にしている。</p>

<pre>
my @frontproxy = map { s/\s//g } split(/,/, $ENV{FRONT_PROXY} || "");
foreach my $ip ( @frontproxy ) {
    my $netip = Net::IP->new($ip) or die;
    push @frontproxies, $netip;
}
buider {
    enable_if {
        my $addr = $_[0]->{REMOTE_ADDR};
        my $netip;
        if ( defined $addr && ($netip = Net::IP->new($addr)) ) {
            for my $proxy ( @frontproxies ) {
                my $overlaps = $proxy->overlaps($netip);
                return 1 if ( $overlaps == $IP_B_IN_A_OVERLAP || $overlaps == $IP_IDENTICAL );
            }
        }
        return;
    } "Plack::Middleware::ReverseProxy";
    $app;
}
</pre>

<p>このように環境変数FRONT<em>PROXYにReverse ProxyのIP帯域(アドレス)をいれ、Plack::Builderのenable</em>ifを使って、REMOTE_ADDRがその帯域にあれば、Middlewareを有効にするような方法をとっている。</p>

<p>このようなenable_ifはなんども書きそうなので、モジュールにしておいた方がいいんじゃないかと思い、書いてみた。</p>

<p>github: <a href="http://github.com/kazeburo/Plack-Builder-Conditionals">http://github.com/kazeburo/Plack-Builder-Conditionals</a></p>

<p>使い方は</p>

<pre>
use Plack::Builder;
use Plack::Builder::Conditionals;
# exports "match_if, addr, path, method, header, any, all"

builder {
    enable match_if addr(['192.168.0.0/24','127.0.0.1']),
        "Plack::Middleware::ReverseProxy";
    $app
 }
</pre>

<p>な、感じ。コードの見通しが良くなりました。</p>

<p>Plack::Builder::Conditionalsを利用するには、enableのあとに、match<em>if をおきます。match</em>ifは内部的にPlack::Middleware::Conditionalを使っていてあとに続く条件によってMiddlewareを有効にするかの判断をします。</p>

<p>条件でとして、REMOTE<em>ADDRの検証を行う「addr」、PATH</em>INFOをみる「path」、REQUEST_METHODの「method」、そして任意のヘッダを確認するための「header」のメソッドが用意されています。これに加えて複合的な条件の実現するための「all」と「any」もあります。</p>

<pre>
# REMOTE_ADDRの帯域を調べる
addr([qw!192.168.0.0/24 127.0.0.1!]);

# PATH_INFO
path('/')
path(qr!^/(\w+)/!)

#REQUEST_METHOD
method('GET')
method(qr!/^(get|head)$/!)

# 任意のヘッダ
header('User-Agent',qr/iphone/i)
header('If-Modified-Since') #ヘッダがあれば真

# REQUEST_METHODがGETかつ、PATH_INFOが/static以下
all( method('GET'), path(qr!^/static!) )

# PATH_INFOが/static以下もしくは、/favicon.ico
any( path(qr!^/static!), path('/favicon.ico') )
</pre>

<p>このように任意の条件を組み合わせても使えます。また、否定の条件の場合は</p>

<pre>
addr('!','127.0.0.1'); #localhostではない
path('!', qr!^/private($|/)!) #/private以下ではない
method('!','GET')
header('!', 'User-Agent',qr/MSIE/)
</pre>

<p>最初の引数として、「!」を渡します。</p>

<p>非常に簡単なメソッド名を利用しているため、アプリケーションによっては重なってしまうことも考えられます。その際はimport時に
メソッド名にprefixを追加することができます。</p>

<pre>
use Plack::Builder::Conditionals -prefx => 'c'; #prefixに「c」追加
# exports "c_match_if, c_addr, c_path, c_method, c_header, c_any, c_all"
</pre>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/plackbuilderenable-ifmiddleware.html</feedburner:origLink></entry>

<entry>
    <title>バスのミニカー買った</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/c5m8HkNLE64/post-6.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.47</id>

    <published>2010-07-11T13:14:49Z</published>
    <updated>2010-07-11T13:21:15Z</updated>

    <summary>乗り物好きな息子に、トミカのバスを買ってみた。 「三菱ふそうエアロスター 路線バ...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>乗り物好きな息子に、トミカのバスを買ってみた。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="R0013211.jpg" src="http://blog.nomadscafe.jp/2010/07/11/R0013211.jpg" width="500" height="375" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></p>

<p>「三菱ふそうエアロスター 路線バス」、どうみても都営バス。ちゃんと東京都交通局許諾済みとパッケージに書いてあります。<a href="http://blog.nomadscafe.jp/2010/06/post-5.html">電車</a>ほどはずっと握りしめたままではないけど、気にってくれたみたい。</p>

<p>ヨドバシカメラで260円だった。しかし安いな</p>

<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&nou=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=nomadscafejp-22&o=9&p=8&l=as1&m=amazon&f=ifr&md=1X69VDGQCMF7Z30FM082&asins=B000GTAX84" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/post-6.html</feedburner:origLink></entry>

<entry>
    <title>CloudForecastのリソース監視定義モジュールの作り方</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/6k6lr336zn8/cloudforecast-2.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.46</id>

    <published>2010-07-09T07:43:17Z</published>
    <updated>2010-07-09T07:52:00Z</updated>

    <summary>CloudForecastでリソース監視をする際の情報取得方法、グラフの設定を行...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>CloudForecastでリソース監視をする際の情報取得方法、グラフの設定を行うモジュールの作り方の紹介です。<a href="http://blog.nomadscafe.jp/2010/07/gearman-worker-process.html">前のエントリー</a>で紹介したgearman-starter.plのスコアボードによるステータス情報を取得してグラフにしてみます。</p>

<p>まず、gearman-starter.plのステータスを再確認します。telnetでみるとこんな感じです。</p>

<pre><code>% telnet localhost 7005
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
System: gearman_servers: 127.0.0.1:7004 class: MyWorker
Uptime: 20
BusyWorkers: 0
IdleWorkers: 10
--
pid       Status Counter Comment
1630           . 0
1631           . 0
1632           . 0
1633           . 0
1634           . 0
1635           . 0
1636           . 0
1637           . 0
1638           . 0
1639           . 0
</code></pre>

<p><br />
前回より若干情報が増えてます。このうち、BusyWorkersとIdleWorkersの値がグラフにできそうです。BusyとIdleの組み合わせは、Apacheの監視と同じです。Apacheのグラフは以下のイメージ。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/07/09/apache-graph.png"><img alt="apache-graph.png" src="http://blog.nomadscafe.jp/assets_c/2010/07/apache-graph-thumb-500x189-46.png" width="500" height="189" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>gearman-starterのグラフはstarterの機能に(max|min)<em>spare</em>workersがないので上限値の移動はしませんが、これとほぼ同じになります。次に、モジュールの作成です。</p>

<p>cloudforecastに独自にリソース定義モジュールを追加する時は、site-libディレクトリを作成し、その中にファイルを入れるのがおすすめです。各種のscriptで既にライブラリパスに追加されてたり、ファイル更新を検知しての自動再起動モードの対象にも入っています。</p>

<pre><code>% cd path/to/cloudforecast
% mkdir -p site-lib/CloudForecast/Data
</code></pre>

<p><br />
このディレクトリの中にモジュールを入れます。名前はGearmanstarter.pmとします。ソース全文は<a href="http://gist.github.com/469203">gist</a>にあげました。</p>

<pre><code>package CloudForecast::Data::Gearmanstarter;

use CloudForecast::Data -base;
use IO::Socket::INET;
</code></pre>

<p><br />
パッケージ宣言をし、CloudForecast::Dataを「-base」引数付きで読み込みます。</p>

<pre><code>rrds map { [$_,'GAUGE'] } qw/busy idle/;
</code></pre>

<p><br />
グラフやリソース取得の設定はDSLっぽく書いていきます。まず「rrds」ではデータを保存していくRRDtoolのスキーマを設定します。</p>

<pre><code>rrds ['データソースタイプ','名前'], [], [], ..;
rrds 'データソースタイプ', '名前';
</code></pre>

<p><br />
どちらのフォーマットでも記述可能です。複数のステータスを保存する場合には、rrdsを複数回書くこともできます。「データソースタイプ」はいくつかの種類があります。詳しくは<a href="http://www.itmedia.co.jp/enterprise/articles/0705/30/news022_2.html">ITmediaの記事</a>や<a href="http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html">RRDtoolsの公式のドキュメント</a>が参考になります。よく利用するタイプとして、</p>

<ul>
<li>GAUGE - その瞬間の値。グラフではそのままの値が利用される</li>
<li>COUNTER - カウンターのように時刻が進むと増え続けていく値。グラフでは差分をとる</li>
</ul>

<p>この2種類を覚えておけば大丈夫です。一度作成されたスキーマは変更できないので注意してください</p>

<pre><code>graphs 'status' =&gt; 'worker status';
</code></pre>

<p><br />
これは、グラフの設定です。グラフを区別するためのキーワードやラベルです。</p>

<pre><code>graphs 'key', 'label';
graphs 'foo', 'foo usage';
</code></pre>

<p><br />
一つのリソース定義で複数のグラフを作成する事もできます。この場合は複数回graphsを書きます。</p>

<p>いよいよ、データを取得する部分。</p>

<pre><code>fetcher {
    my $c = shift;

    my $host = $c-&gt;address;
    my $port = $c-&gt;args-&gt;[0] || 9000;

    my $sock = IO::Socket::INET-&gt;new(
        PeerAddr =&gt; $host,
        PeerPort =&gt; $port,
        Proto    =&gt; 'tcp',
        Timeout  =&gt; 5,
    );

    die "could not connecet to $host:$port" unless $sock;
    my $raw_stats;
    $sock-&gt;sysread( $raw_stats, 8192 );

    my $busy = -1;
    my $idle = -1;
    foreach my $line ( split /[\r\n]+/, $raw_stats ) {
        if ( $line =~ /^Busy.+: (\d+)/ ) {
            $busy = $1;
        }
        if ( $line =~ /^Idle.+: (\d+)/ ) {
            $idle = $1;
        }
    }
    return [$busy,$idle];
};
</code></pre>

<p><br />
普通のperlのコードで書けます。</p>

<pre><code>fetcher sub { };
</code></pre>

<p><br />
IO::Socketでgearman-starterの管理ポートに接続をし、ステータスをパースしています。最後に、取得したデータを、rrdsに登録した順序で配列のリファレンスで返します。$cはCloudForecast::Data::Gearmanstarterのオプジェクトで、以下のメソッドも利用できます。</p>

<ul>
<li>$c->hostname - サーバ一覧で設定したサーバのホスト名</li>
<li>$c->address - サーバ一覧で設定したIPアドレス</li>
<li>$c->detail - サーバ一覧で設定したコメント</li>
<li>$c->args->[0,,,] - リソース定義のオプション。配列のリファレンス</li>
<li>$c->component() - 共通で使えるデータ取得ライブラリ</li>
</ul>

<p>argsは、監視項目設定の値です。監視項目で</p>

<pre><code>- modue_name:option1:option2:..
</code></pre>

<p><br />
と書いた場合にコロンで区切った値が配列として入ってきます。Gearmanstarterでは、管理ポートの番号を渡す事にします。</p>

<pre><code>- gearmanstarter:9001
</code></pre>

<p><br />
最後にグラフの設定です。<strong>DATA</strong>以下に@@ graphs_keyで区切って書いていきます。</p>

<pre><code>@@ status
DEF:my1=&lt;%RRD%&gt;:busy:AVERAGE
DEF:my2=&lt;%RRD%&gt;:idle:AVERAGE
AREA:my1#00C000:Busy  
GPRINT:my1:LAST:Cur\: %4.1lf
GPRINT:my1:AVERAGE:Ave\: %4.1lf
GPRINT:my1:MAX:Max\: %4.1lf
GPRINT:my1:MIN:Min\: %4.1lf\c
STACK:my2#0000C0:Idle  
GPRINT:my2:LAST:Cur\: %4.1lf
GPRINT:my2:AVERAGE:Ave\: %4.1lf
GPRINT:my2:MAX:Max\: %4.1lf
GPRINT:my2:MIN:Min\: %4.1lf\c
</code></pre>

<p><br />
これはApacheの定義モジュールと全く同じです。&lt;%RRD%>と書かれた部分がrrdtoolのデータサイズファイルのパスに自動で置き換わります。グラフの細かいオプションはほかのリソース定義や<a href="http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html">ドキュメント</a>を参考にしてください</p>

<p>これでモジュールが完成しました。あとはCloudForecastの監視項目のカスタマイズ方法で書きました、監視項目設定ファイルに追加すればすぐに使えます。</p>

<p>リソース監視定義モジュールでは、ここで説明したデータの取得とグラフ化だけではなく、システムの情報を取得、保存し、Web画面に表示するカスタマイズも可能です。これは別途解説します。</p>

<p>あとは、テストをどうやって書くか悩み中</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/cloudforecast-2.html</feedburner:origLink></entry>

<entry>
    <title>CloudForecastの監視項目のカスタマイズ方法</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/BKawle6TH1s/cloudforecast-1.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.45</id>

    <published>2010-07-09T07:35:51Z</published>
    <updated>2010-07-09T07:40:06Z</updated>

    <summary>CloudForecastっていうリソース監視のツール／フレームワーク作ったにお...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p><a href="http://blog.nomadscafe.jp/2010/05/cloudforecast.html">CloudForecastっていうリソース監視のツール／フレームワーク作った</a>において、CloudForecastのインストールとCPUやメモリー、トラフィックなど基本的な監視ができるところまで記事にしましたが、今回はその監視項目のカスタマイズの方法を紹介します。</p>

<p>前回記事の最後では、監視対象となるサーバはlocalhostだけが登録されている状態です。server_list.yamlは以下のようになっています。</p>

<pre><code>--- #HOME
servers:
  - config: basic.yaml
    hosts:
      - 127.0.0.1 server1 my great server
</code></pre>

<p>configで指定しているが監視項目の設定ファイルです。cloudforecast.yamlのhost_config_dirで指定されたディレクトリ内に保存されています。監視項目のカスタマイズにあたり、新規にhost_config_dirを作成します。</p>

<pre><code>% cd path/to/cloudforecast
$ mkdir my_host_config
</code></pre>

<p>ここにbasic.yamlをコピーします。ついでに名前も変えます。</p>

<pre><code>$ cp host_config/basic.yaml my_host_config/localhost.yaml
</code></pre>

<p>設定ファイルの名前は自由に決められますが、あとでわかるものがいいでしょう。そして、cloudforecast.yamlのhost_config_dirと、server_list.yamlのconfigを変更します。</p>

<pre><code>---
config:
  gearman_enable: 0
  (略)
  host_config_dir: my_host_config @ココ@
component_config:
  (略)


--- #HOME
servers:
  - config: localhost.yaml @ココ@
    hosts:
      - 127.0.0.1 server1 my great server
</code></pre>

<p>これで準備が整ったので、localhost.yaml を変更します。</p>

<p>localhostでは、Apacheが80ポートで起動して、memcachedを11212ポートで利用しているので、これらを追加します。</p>

<pre><code> ---
 component_config:
 resources:
   - traffic:eth0
   - basic
   - http:80:/server-status?auto @ポート80のApache@
   - memcached:11212 @ポート11212のmemcached@
</code></pre>

<p>resourcesのところに追加して行きます。http:80とmemcached:11212が足した監視項目です。</p>

<pre><code> - modue_name:option1:option2:..
</code></pre>

<p>module_nameは一文字目を大文字にして、CloudForecast::Data以下のリソース定義モジュールが読み込まれます。また「:」で区切ったオプション部分もモジュールに渡されます。Apacheの監視ではCloudForecast::Data::Httpがよばれ、「80」と「/server-status?auto」が渡されます。どのようにオプションが使われるのかは、リソース定義モジュールによって変わります。Httpモジュールでは1つ目がポート、2つ目がserver-stautsを取得するURLとなります。ドキュメントはまだ整備中^^</p>

<p>蛇足ですがserver-stautsはApacheであれば</p>

<pre><code>&lt;Location /server-status&gt;
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost
&lt;/Location&gt;
</code></pre>

<p>のように設定できます。</p>

<p>CloudForecastにはHttpやmemcachedの他にも、標準でDisk使用量、DiskIO数、MySQL、MySQL InnoDB、Nignx、Squidなどのモジュールが含まれています。また新たにリソース監視定義モジュールを作成し追加することもできます。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/cloudforecast-1.html</feedburner:origLink></entry>

<entry>
    <title>gearman の worker processのスコアボードをネットワーク越しに見えるようにした</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/N91Uwa5NyFI/gearman-worker-process.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.44</id>

    <published>2010-07-07T02:17:12Z</published>
    <updated>2010-07-07T02:20:52Z</updated>

    <summary>tokuhiromのgearman の worker process にスコアボ...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>tokuhiromの<a href="http://d.hatena.ne.jp/tokuhirom/20100705/1278324297">gearman の worker process にスコアボードをつけてみる</a> (<a href="http://github.com/tokuhirom/gearman-starter.pl/blob/master/gearman-starter.pl">git</a>) のスコアボードをネットワーク越しに確認できるようにしてみた。</p>

<p>git: <a href="http://github.com/kazeburo/gearman-starter.pl">http://github.com/kazeburo/gearman-starter.pl</a></p>

<p><br />
具体的にはworkerのloopに入る前に指定したportをlistenするプロセスをforkして、そいつにアクセスすることで、ステータス(スコアボード)を取得できる。</p>

<p>ステータスを表示するために&#8212;port と &#8212;listen の2つのオプションを追加した。起動は</p>

<pre><code>% perl -Ieg/lib ./gearman-starter.pl -s 127.0.0.1:7004 --scoreboard-dir /tmp/test --listen localhost --port 7005 MyWorker
</code></pre>

<p>な感じ。telnetでport 7005にアクセスすると、すぐにステータスが返ってくる</p>

<p>起動直後</p>

<pre><code>% telnet localhost 7005
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
BusyWorkers: 0
IdleWorkers: 10
--
pid       Status Counter Comment
15785          . 0
15786          . 0
15787          . 0
15788          . 0
15789          . 0
15790          . 0
15791          . 0
15792          . 0
15793          . 0
15794          . 0

Connection closed by foreign host.
</code></pre>

<p>clientを動かすと、</p>

<pre><code>BusyWorkers: 1
IdleWorkers: 9
--
pid       Status Counter Comment
15785          _ 2
15786          _ 4
15787          . 0
15788          . 0
15789          . 0
15790          A 1 127.0.0.1:7004//H:vs1-1:94425
15791          . 0
15792          . 0
15793          . 0
15794          . 0
</code></pre>

<p>のように変化する。pidが「15790」がActive(Busy)になってるのがわかる。</p>

<p>これで監視ができるゥ。</p>

<p>あと、Gearman::Worker->workは内部で無限ループする。ループを止めるにはstop_ifのcallbackを渡す必要があるので注意</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/gearman-worker-process.html</feedburner:origLink></entry>

<entry>
    <title>NoPasteを作るためにsinatraライクなWAFを書いてみた</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/-wBbdLOZ9FI/nopastesinatrawaf.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.43</id>

    <published>2010-07-06T16:48:16Z</published>
    <updated>2010-07-06T16:54:20Z</updated>

    <summary>社内にNoPaste的なものがなくてカッとなって作っていたらsinatraライク...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>社内にNoPaste的なものがなくてカッとなって作っていたらsinatraライクなフレームワークを作っていた。何を言っているか(ry </p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/07/07/nonopaste.png"><img alt="nonopaste.png" src="http://blog.nomadscafe.jp/assets_c/2010/07/nonopaste-thumb-500x425-44.png" width="500" height="425" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>NoNoPasteソースコード: <a href="http://github.com/kazeburo/NoNoPaste">http://github.com/kazeburo/NoNoPaste</a></p>

<p>元々、<a href="http://github.com/kazeburo/cloudforecast">CloudForecast</a>には、tokuhiromの<a href="http://github.com/tokuhirom/MojaMoja">MojaMoja</a>やyusukebeの<a href="http://github.com/yusukebe/Hitagi">Hitagi</a>からコピペをしつつ作ったフレームワークがあり、NoPaste的なものを作成するにあたりCloudForecastからWAF部分だけを切り出して作り直した。</p>

<p>今回のWAFのコードはまだNoPasteのパッケージ内にある。名前はShirahata。</p>

<p>Shirataha.pm: <a href="http://github.com/kazeburo/NoNoPaste/blob/master/lib/Shirahata.pm">http://github.com/kazeburo/NoNoPaste/blob/master/lib/Shirahata.pm</a></p>

<p>特徴は</p>

<ol>
<li>sinatraライクなURLの組み立て</li>
<li>typesterさんの<a href="http://search.cpan.org/~typester/Text-MicroTemplate-DataSection-0.01/">Text::MicroTemplate::DataSectionEx</a>を利用して<strong>DATA</strong>にテンプレートを書きつつ、継承などをサポート</li>
<li>組み込みfillinformサポート</li>
<li>Modelはナシ</li>
</ol>

<p>あとはCatalyst風な&#8221;$c&#8221;も特徴かな。利用イメージとしてはCloudForecastのWeb画面のようなちょっとした管理ページ系かな</p>

<p>以下は簡単なサンプル</p>

<pre><code>package MyApp;

use Shirahata -base;

get '/' =&gt; sub {
    my ( $self, $c )  = @_;
    # $c-&gt;req, $c-&gt;res, $c-&gt;stash, $c-&gt;args
    $c-&gt;render('index')
}

__DATA__
@@ base.mt
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;My App&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;&lt;a href="&lt;?= $c-&gt;req-&gt;uri_for('/') ?&gt;"&gt;MyApp&lt;/a&gt;&lt;/h1&gt;
? block content =&gt; sub { }
&lt;/body&gt;
&lt;/html&gt;

@@ index.mt
? extends 'base'
? block content =&gt; sub {
&lt;h2&gt;Content&lt;/h2&gt;
? fillinform( $c-&gt;req, sub {
&lt;form method="post" action="/submit" id="submitf"&gt;
&lt;label for="nick"&gt;nick&lt;/label&gt;
&lt;input type="text" id="nick" name="nick" value="" size="21" /&gt;
&lt;input type="submit" id="submitb" value="POST" /&gt;
&lt;/form&gt;
? })
? } #block content
</code></pre>

<p>呼び出すためのpsgi。</p>

<pre><code>use strict;
use warnings;
use Cwd qw/realpath/;
use File::Basename qw/dirname/;
use MyApp;

my $root_dir = dirname( realpath(__FILE__) );
my $web = MyApp-&gt;new($root_dir);
$web-&gt;psgi;
</code></pre>

<p><br />
<br />
Xslateも試してみていて、<strong>DATA</strong>をtempdirに書き出して、Xslateに読み込ませるとか考えたんだけど、一時ディレクトリの掃除が大変なのでやめた。DataSectionのXslate版はgfx曰く「絶賛考え中です！」なので楽しみにしている</p>

<p>CloudForecastにbackportするかどうか考え中</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/nopastesinatrawaf.html</feedburner:origLink></entry>

<entry>
    <title>CloudForecast Updates</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/i4anazKWq7w/cloudforecast-updates.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.42</id>

    <published>2010-07-02T15:09:21Z</published>
    <updated>2010-07-02T15:45:51Z</updated>

    <summary>1ヶ月前ほどにBlogに書いたサーバリソースの監視ツール CloudForeca...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>1ヶ月前ほどにBlogに書いたサーバリソースの監視ツール CloudForecastは弊社でも導入前提で試験をしつつ、さまざまなアップデートを行っているのでその紹介です</p>

<p>大きく変わったのはWeb画面の見た目です。</p>

<p>サーバ一覧</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/07/03/sample-list2.png"><img alt="sample-list2.png" src="http://blog.nomadscafe.jp/assets_c/2010/07/sample-list2-thumb-500x419-37.png" width="500" height="419" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>各サーバのグラフページ</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/07/03/sample-server2.png"><img alt="sample-server2.png" src="http://blog.nomadscafe.jp/assets_c/2010/07/sample-server2-thumb-500x437-39.png" width="500" height="437" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>多くのサーバを監視するにあたり、通常は見ないサーバに関してはグループ名をクリックすることで畳んでしまうことができます。見たくないサーバはこれで桶。また、各サーバのグラフページでは、デフォルトでMonthlyとYearlyのグラフの表示をやめています。通常ブラウザの画面には入りきらないと思いますし、参照することも24時間、1週間のグラフに比べて少ないだろうという判断です。表示速度も高速化される期待もあります。月間年間のグラフを参照したい時はワンクリックで表示できるので不便はないと思います</p>

<p>加えて、日時指定でグラフを表示することができます。Pickerには<a href="http://www.ama3.com/anytime/">Any+TIme DatePicker/Timer Picker</a>というJavaScriptライブラリを利用し、障害が起きたり負荷の高まった時間帯だけを切り出することも可能です。ただし、日付の古いデータに関してはRRDToolで数値が丸められていくのでどれだけ意味のあるグラフになるのかは疑問があったりします。</p>

<p>システム情報</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/07/03/mysql-info.png"><img alt="" src="http://blog.nomadscafe.jp/assets_c/2010/07/mysql-info-thumb-500x205-41.png" width="500" height="205" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>もう一つ付け加えた機能として、リソース情報の取得時にシステムの設定情報などを抜き出して保存し、Web画面に表示することができるようになりました。上の例で行けば、MySQLのグラフにMySQLのthread<em>cacheやmax</em>connectionがどのような値に設定されているかを一緒に表示しています。InnoDBではbuffer<em>poolやflush</em>methodなどを表示するため、チューニングのガイドとしても役に立つかもしれません。</p>

<p>このシステム情報を取得、保存、表示するために、SQLiteに依存するようになりました。RRDToolとYAMLだけのNoSQLシステムから、SQLも利用するようになりました</p>

<p>今後の展開とか</p>

<p>社内でも利用し始めていることもあり、まだまだ改善、変更していくと思われます。今は100台程度のサーバを監視していますが、数百台となった場合や、このWeb画面を参照する開発者が増えていく中でも利用しやすいように工夫していきます。ただし、設定ファイルのフォーマットやrrdtoolの定義に関しては変更を行わないようにします。今までに貯めたリソースデータが無駄にならないことが必須条件だと考えています。この部分では安心してCloudForecastを利用して頂けると良いかと思います。
その上で今後の展開ですが、一覧ページの使い勝手の向上、メモ機能、ドキュメントとかドキュメントとかドキュメントを充実して行きたいところです</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/cloudforecast-updates.html</feedburner:origLink></entry>

<entry>
    <title>StarmanやStarletでmod_statusっぽい情報を得る簡易版Plack::Middleware::ServerStatus</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/HHqQ1jzh6YY/starmanstarletmod-statusplackmiddlewareserverstatus.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.41</id>

    <published>2010-07-01T15:53:31Z</published>
    <updated>2010-07-01T16:02:05Z</updated>

    <summary>最近、弊社でもいくつかのサービスでStarmanが動き始めてます。リソース監視厨...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>最近、弊社でもいくつかのサービスでStarmanが動き始めてます。リソース監視厨として<a href="http://search.cpan.org/dist/Starman/">Starman</a>や<a href="http://search.cpan.org/dist/Starlet/">Starlet</a>といったPreforkなPlackサーバにおいてもApacheの<a href="http://httpd.apache.org/docs/2.2/en/mod/mod_status.html">mod_status</a>同様、使用されているプロセス数、アイドル中のプロセス数を当然知りたいわけです。CloudForecastでグラフにしたいわけです。</p>

<p>すでにcho45氏が<a href="http://subtech.g.hatena.ne.jp/cho45/20100525/1274765056">その機能を実現して</a>います。cho45++です。ただ、ステータス表示を行うMiddlewareの他にステータス情報の変更を行うためにStarmanやStarletの本体に手を入れており、若干使いにくいという印象を持っていました。そこでMiddlewareだけで、Middlewareのできる範囲でステータスを変更・表示する<a href="http://github.com/kazeburo/Plack-Middleware-ServerStatus-Lite">Plack::Middleware::ServerStatus::Lite</a>を書いてみました。ソースコードはgithubにpushしてあります。</p>

<p><a href="http://github.com/kazeburo/Plack-Middleware-ServerStatus-Lite">http://github.com/kazeburo/Plack-Middleware-ServerStatus-Lite</a></p>

<p>仕組みは簡単です。cho45氏の実装をまねて $0 ($PROGRAM_NAME)を変更し、それをpsコマンド経由で収集し、表示します。</p>

<p>$0を変更する実装は以下の様な感じ</p>

<pre><code>sub call {
    my ($self, $env) = @_;

    $0 = sprintf("server-status-lite[%s] %s",getppid, "A"); #Active

    $res = $self-&gt;app-&gt;($env);

    $0 = sprintf("server-status-lite[%s] %s",getppid, "_"); #Idle

    return $res;
}
</code></pre>

<p>このようにappを実行する前後でステータスをActive(Busy) or Idleで変更しているだけです。Apacheのmod_statusやcho45氏のhackではリクエストの読み込み、書き込み、KeepAliveなどの様々なステータスがとれるのに対してServerStatus::Liteでは2種類の状態しかとることができません。ただ、実際のStarmanやStarletのProduction環境では、リバースプロキシーを全面に設置するため読み込み、買い込みは十分に早くでき、またKeepAliveは無効にしていると思われるので、この簡単なステータスでも十分に焼くに立つのではないかと予想しています。</p>

<p>このように書き換えたステータスをpsコマンドの結果から収集して、Active(Busy)のプロセス数、Idleのプロセス数を数えます。必要なプロセスをすべて調査するために「親プロセスのPIDが同じ」であるプロセスを探しています。</p>

<p>以下は実際にStarlet(max-process=10)でアプリケーションを起動してabでアクセスしている状態のpsの結果(一部)</p>

<pre><code> PPID   PID COMMAND
20337  1022  \_ /bin/zsh
 1022 20582  |   \_ /usr/bin/perl /usr/local/bin/plackup -r -Ilib -p 5003 -s Starlet -a nonopaste.psgi
20582 20583  |       \_ /usr/bin/perl /usr/local/bin/plackup -r -Ilib -p 5003 -s Starlet -a nonopaste.psgi
20583 20803  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 20804  |           \_ server-status-lite[20583] A 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 20806  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 20808  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21153  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21156  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21158  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21163  |           \_ server-status-lite[20583] _ 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21165  |           \_ server-status-lite[20583] A 127.0.0.1 localhost:5003 GET / HTTP/1.0
20583 21168  |           \_ /usr/bin/perl /usr/local/bin/plackup -r -Ilib -p 5003 -s Starlet -a nonopaste.psgi
</code></pre>

<p>最も左側の項目が親プロセスのPIDで、ここが20583になっているプロセスがPreforkされているプロセスです。6行目と13行目のプロセスが動いているプロセス。一番下のプロセスはまだ一度もアクセスを処理していないので、元のプログラム名のままとなっています。このようなプロセスはIdleのプロセスとカウントしています</p>

<p>このステータス情報はApacheのmod_status同様http経由で取得可能です。おしゃれなHTMLに整形されていたりしませんが以下のように取得可能です</p>

<pre><code> % curl -v http://localhost:5003/server-status
 （略）
 &lt; HTTP/1.0 200 OK
 &lt; Date: Thu, 01 Jul 2010 15:38:49 GMT
 &lt; Server: Plack::Handler::Starlet
 &lt; Content-Type: text/plain
 &lt; Content-Length: 30
 &lt; 
 BusyWorkers: 3
 IdleWorkers: 7
</code></pre>

<p>このMiddlewareを有効にするには、Plack::Builderを利用して</p>

<pre><code>builder {
    enable "Plack::Middleware::ServerStatus::Lite",
        path =&gt; '/server-status',
        allow =&gt; [ '127.0.0.1', '192.168.0.0/16' ];
    $app;
};
</code></pre>

<p>のように設定します。pathはhttpで取得するする場合のURI。allowはアクセス制御用。何も書かないと一切アクセスできません。</p>

<p>このMiddlewareは新サービスで使ってもらえる予定で、リソース監視も当然行う予定になっています。あとはpsgi.multiprocessのflagぐらいは確認した方がいいかなぁと思っています。 ただpsgi.multiprocessがTRUEなmod_perl1で動かすとどうやらセグフォルするようですが。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/07/starmanstarletmod-statusplackmiddlewareserverstatus.html</feedburner:origLink></entry>

<entry>
    <title>鉄道博物館行ってプラレール買ってきた</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/sbylcevH9ec/post-5.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.40</id>

    <published>2010-06-28T04:03:52Z</published>
    <updated>2010-06-28T04:13:13Z</updated>

    <summary>奥さんの会社の人と一緒に家族で鉄道博物館行ってきた。 なにげに初さいたま 電車の...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>奥さんの会社の人と一緒に家族で鉄道博物館行ってきた。
なにげに初さいたま</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/06/28/R0013162.jpg"><img alt="R0013162.jpg" src="http://blog.nomadscafe.jp/assets_c/2010/06/R0013162-thumb-500x375-33.jpg" width="500" height="375" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>電車のおもちゃがなかったので、プラレール買った。<br />
こちらも初プラレール</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/06/28/R0013166.jpg"><img alt="R0013166.jpg" src="http://blog.nomadscafe.jp/assets_c/2010/06/R0013166-thumb-500x375-35.jpg" width="500" height="375" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>最初のプラレールはN700系新幹線だろと思っていたのだが、息子はレールがあってもまだまだ破壊するだけなので、セットは買わずに車両単品のE217系東海道線車両。普段親が通勤で使っている電車ということで、これを選んだ。</p>

<p>とりあえず、一両目だけ渡してみた。気に入ってくれたみたい</p>

<p>*自分が利用している湘南新宿ラインは<a href="http://www.takaratomy.co.jp/products/fan/tomipla/tettei_p/03_02_pte/index.htm">E231</a>が正しいらしい</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/06/post-5.html</feedburner:origLink></entry>

<entry>
    <title>株式会社ライブドアに入社しました</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/6xofI_k3ASs/post-4.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.39</id>

    <published>2010-06-02T15:15:46Z</published>
    <updated>2010-06-02T15:19:38Z</updated>

    <summary>先月末にミクシィを退職し、6月1日より株式会社ライブドアにて働かせていただくこと...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>先月末に<a href="http://blog.nomadscafe.jp/2010/05/post-3.html">ミクシィを退職</a>し、6月1日より株式会社ライブドアにて働かせていただくことになりました。</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/06/03/joinlivedoor.png"><img alt="joinlivedoor.png" src="http://blog.nomadscafe.jp/assets_c/2010/06/joinlivedoor-thumb-500x220-31.png" width="500" height="220" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p><em>出社日2.0日目的な意味で。</em></p>

<p>ライブドアには以前からの知り合いのエンジニアも多くいたり、先月には<a href="http://mt.endeworks.jp/d-6/2010/05/post-158.html">JPAの代表の牧さん</a>が(再)就職をしていたり、同日入社にはアノPerlエンジニアもいます。それぞれが高い技術をもっている楽しみな職場です。ライブドアでの主な業務内容は前職に引き続きシステム運用を見ることになります。</p>

<p>Blogをはじめとするlivedoorのメディア、サービスを運用やスケーラビリティといった立場から支えて行きたいと思いますので、これからもよろしくお願いします。</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/06/post-4.html</feedburner:origLink></entry>

<entry>
    <title>CloudForecastっていうリソース監視のツール／フレームワーク作った</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/94Na7SVpLSc/cloudforecast.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.38</id>

    <published>2010-05-31T02:15:27Z</published>
    <updated>2010-06-07T03:55:52Z</updated>

    <summary>「クラウド」って言ってみたかった。今は反省していr 上のグラフは前回のエントリー...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p>「クラウド」って言ってみたかった。今は反省していr</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20100528traffic.jpg" src="http://blog.nomadscafe.jp/2010/05/31/20100528traffic.jpg" width="497" height="188" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></p>

<p>上のグラフは前回のエントリーを公開したときの、当blogを配信しているサーバのトラフィックグラフです。記事を公開した17時にぴょーんとトラフィックが伸びています。4時にも増えているけどこちらは謎。</p>

<p>実はこのグラフもCloudForecastを利用して取得しています。CloudForecastはサーバ等のリソース監視を行うツールもしくはフレームワークで、rrdtoolの薄いラッパーとして動作し、小規模から大規模なサーバ群を一括で管理できるように設計してあります。tokuhirom曰く、「perlが書けてrrdtoolがつかえるsysadminの人だったら使いやすいと思われる」というのがもっともしっくりくるような気がします。Perlとrrdtoolが使える運用者によるカスタマイズ前提なのがフレームワークと呼んでいる所以です。</p>

<p>CloudForecastはもともとミクシィで使われていた古いPerl4ライクなスクリプトをモダンな設計に書き直し、gearmanに対応させることで監視処理を分散させることを実現しています。監視項目は大規模ウェブサイトのmixiで使われているものをサービスに依存する部分を除き、ほぼそのまま受け継いでいます。今回オープンソースとして公開することで負荷の高いウェブサイトの運用ノウハウも広めていくことができるのではないかと思います。</p>

<p>ソースコードはgithubにて公開しています <a href="http://github.com/kazeburo/cloudforecast">http://github.com/kazeburo/cloudforecast</a></p>

<p><br />
このエントリーではインストール方法を簡単に紹介します。</p>

<p>本体のインストール前に、rrdtoolやSNMPのperl bindingが必要になります。これは各OSのパッケージで入れてしまうのが楽です。</p>

<pre><code># ubuntu
$ sudo apt-get install librrds-perl libsnmp-perl
# CentOS
$ sudo yum install net-snmp-perl
# rrdtoolはEPELを利用
$ sudo yum install rrdtool-perl
</code></pre>

<p>CloudForecastのソースコードはgithubから落とします</p>

<pre><code>$ git clone git://github.com/kazeburo/cloudforecast.git
$ cd cloudforecast
$ cpanm -l extlib --installdeps .
</code></pre>

<p><em>＊extlibにlocal::libを利用して依存モジュールを入れることができます</em></p>

<p>他にMySQLを監視したい場合は、DBD::mysqlなどを入れておくといいでしょう。</p>

<p>次に設定ファイルです。sampleをコピーして編集します</p>

<pre><code># 設定ファイル
$ cp cloudforecast_sample.yaml cloudforecast.yaml
# サーバ一覧ファイル
$ cp server_list_sample.yaml server_list.yaml
</code></pre>

<p><br />
サンプル設定ファイル(cloudforecast_sample.yaml)の中身</p>

<pre><code>---
config:
# gearmanを利用する場合、enableを1にして、germandのhost名とportを指定します
  gearman_enable: 0
  gearman_server:
    host: localhost
    port: 7003
# rrdのファイルを設置する場所。「/」から始まると絶対パスとなります
  data_dir: data
# 監視項目の設定ファイルを設置するディレクトリ。「/」から始まると絶対パス
  host_config_dir: host_config

component_config:
# SNMPでデータを取得する時のオプション。communityとversion
  SNMP:
    community: public
    version: 2
# MySQLを監視する場合のuser名とパスワード
  MySQL:
    user: root
    password: ""
</code></pre>

<p><br />
サンプルサーバ一覧ファイル(server<em>list</em>sample.yaml)の中身</p>

<pre><code>--- #Dev
# --- #Hogeと書くことでサーバ一覧を区切ることができます
# configはhost_config内の監視項目の設定ファイル名
# hostsは 「IPアドレス[space]ホスト名[space]コメント」です。コメント内にはスペースがあってもかまいません
servers:
  - config: basic.yaml
    hosts:
      - 192.168.55.10 dev1 develop
      - 192.168.55.11 dev2 develop

--- #Production
servers:
  - config: httpd.yaml
    hosts:
      - 192.168.51.10 web1 web memcached
      - 192.168.51.11 web2 web memcached
  - config: mysql.yaml
    hosts:
      - 192.168.51.60 db1 mysql master
      - 192.168.51.61 db2 mysql slave
      - 192.168.51.62 db2 mysql slave
  - config: basic.yaml
    hosts:
      - 192.168.51.90 batch1 batch
</code></pre>

<p><br />
とりあえず、サーバ一覧ファイルを編集し、監視したいサーバだけにします。localhostをSNMP経由で基本的な監視を行うなら</p>

<pre><code>--- #HOME
servers:
  - config: basic.yaml
    hosts:
      - 127.0.0.1 server1 my great server
</code></pre>

<p>となるでしょう。</p>

<p>localhostのsnmpdが設定されているとして（別途どこかで説明します)、巡回デーモンとWebサーバを起動します。</p>

<pre><code># 巡回デーモン。5分ごとにリソースデータの取得を行います
$ ./cloudforecast_radar -c cloudforecast.yaml -l server_list.yaml
# Webサーバ
$ ./cloudforecast_web -p 5000 -c cloudforecast.yaml -l server_list.yaml
</code></pre>

<p>巡回が2回ほど行われるとグラフの描画が始まります。ブラウザで確認できます。画像は自宅サーバで動いているものになります</p>

<p>サーバ一覧画面</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/05/31/serverlist.jpg"><img alt="serverlist.jpg" src="http://blog.nomadscafe.jp/assets_c/2010/05/serverlist-thumb-500x390-27.jpg" width="500" height="390" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>リソースグラフ画面</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/05/31/resourcegraph.jpg"><img alt="resourcegraph.jpg" src="http://blog.nomadscafe.jp/assets_c/2010/05/resourcegraph-thumb-500x390-29.jpg" width="500" height="390" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>カスタマイズはまたブログなどで説明したいと思います。今年のYAPC::Asiaはこのネタでしゃべりたい!<br />
さっそく試してくれた nekokak++ tokuhirom++</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/05/cloudforecast.html</feedburner:origLink></entry>

<entry>
    <title>株式会社ミクシィを退職しました</title>
    <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/nomadscafejp/~3/x6TWWhTaPMg/post-3.html" />
    <id>tag:blog.nomadscafe.jp,2010://1.37</id>

    <published>2010-05-27T07:57:53Z</published>
    <updated>2010-05-27T08:02:45Z</updated>

    <summary>  昨日tweetした通り、株式会社ミクシィを退職しました。正確には今月末までと...</summary>
    <author>
        <name>Masahiro Nagano</name>
        <uri>http://blog.nomadscafe.jp/</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://blog.nomadscafe.jp/">
        <![CDATA[<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.nomadscafe.jp/2010/05/27/nau.jpg"><img alt="nau.jpg" src="http://blog.nomadscafe.jp/assets_c/2010/05/nau-thumb-500x239-24.jpg" width="500" height="239" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span> </p>

<p>昨日tweetした通り、株式会社ミクシィを退職しました。正確には今月末までとなり、今は少ない有給消化期間です。次の会社は既に決まっていて、6月1日から新しい会社となります</p>

<p>ミクシィには<a href="http://blog.nomadscafe.jp/archives/000686.html">ちょうど</a>4年間在籍しました。その間mixiはPVにして10倍以上という驚異的な成長をし、会社としてのミクシィも上場をするなどさまざまな経験をさせて頂きました。</p>

<p>自分だけでやったことではなく、もちろん他のエンジニアの協力のもとで行ったことですが、4年間の間に自分のミクシィでやっていたことをBlog等ですでに紹介したものを中心にいくつか書くと</p>

<ul>
<li>アプリケーションレベルでのDBのフェイルオーバ</li>
<li>Apache mod<em>proxy</em>balancerの導入</li>
<li>デプロイツールの作成</li>
<li>サーバ設定のバージョン管理化</li>
<li>Squid COSSの検証導入</li>
<li>プロフィール画像などSquid CARPを利用した分散構成対応</li>
<li>Nginxの検証</li>
<li>Varnishの検証・導入</li>
<li>Nagiosの設定簡略化スクリプト</li>
<li>RSSクローラ</li>
<li>各種rpmの作成と大量のモジュールのインストール方法</li>
<li>memcached周りのあれこれ</li>
<li>Q4Mの検証導入、非同期処理フレームワーク作成</li>
<li>リソース監視ツール(cloudforecast)</li>
</ul>

<p>あたりが上げられます。この他にも</p>

<ul>
<li>WEB+DB PRESSやSoftware Designでの執筆</li>
<li>YAPC::Asia 2008,2009での講演</li>
</ul>

<p>などもさせて頂きました</p>

<p>4年間このような業務に携わってきましたが、今回、転職を決意した理由として、自分の技術のガラパゴス化を防ぎたいということがあります。どうしてもほぼ単一のサービスであるミクシィに運用も特化してしまい、技術の幅が広がらないのではないかという気がしています。そのためにもミクシィの外へで様々なサービスに触れたいと思っています。また、サービスとしての良い悪いではありませんが、自分がここまでやって来れたのはBlogやtwitterなどオープンなメディアがあったからであり、SNSよりもそのオープンなメディアを支えたいという考えもあります。</p>

<p>次の職場でも主な業務はかわらず、運用といった側面からサービスのスケーラビリティを支えていくことになります。これまでお世話になってきた方にはこれからもお世話になることとなると思いますが、よろしくお願いします</p>
]]>
        

    </content>
<feedburner:origLink>http://blog.nomadscafe.jp/2010/05/post-3.html</feedburner:origLink></entry>

</feed>
