March 2013 posts

Mar 14, 2013

この前つくった fluent-plugin-ganglia を gem にしてバージョン 0.0.1 をリリースした。

前回のエントリーで書いた時点では、gmond を multicast かつ upd_send_channel を bind_hostname = "yes" として動かしている場合に実はうまくいっていなかった。うごいた!とおもってあのエントリーをよろこびいさんで書いた時点では、1台のホストでしかどうささせていなくて、同じ metric group にはいる他のホストで動かし始めたら全然グラフでてこない、という始末...。

これは gmetric gem の Ganglia::GMetric#send が、

conn = UDPSocket.new
conn.connect(host, port)

conn.send gmetric[0], 0
conn.send gmetric[1], 0
conn.close

こうなってて bind してないからだったようで、Ganglia::GMetric#send は使わずにプラグイン内で、

conn = UDPSocket.new
conn.bind(HOSTADDR, 0) if @bind_hostname
conn.send gmetric[0], 0, @host, @port
conn.send gmetric[1], 0, @host, @port
conn.close

こんなような感じで IPSocket.getaddress(Socket.gethostname) でとってきた IP (HOSTADDR定数のところ) に bind して送るようにしたらうまく行った。まぁ、つまり bind_hostname = "yes" なんで bind しろよ、ということと思われる。gmetric コマンドを strace してみてても bind してたし(というか strace して差分みてて気づいた)。

この multicast + bind_hostname してる環境で metric 送りつけるには、こういう設定。

<match metrics>
  type          ganglia
  host          239.2.11.71
  port          8649
  group         metric_group
  name_keys     metrics.field1,metrics.field2
  bind_hostname true
</match>

bind_hostname true で bind してから送るようになる。multicast だけど bind_hostname してなければいらない。

というのを経ての 0.0.1 はコレの本番環境で絶賛稼働中。unicast での Ganglia はためしたことがないのだけどたぶんうごくとおもうので、もし試せる方おりましたらフィードバックいただけると幸い...。

ご利用ください。

Mar 06, 2013

Plack::Middleware::DefaultDocument というのを作った。

MogileFS のクライアントとしてだけ動く小さな PSGI アプリかいていて、MogileFS になかったらアプリがもってるデフォルトのファイルを 404 ではなく 200 で返したい、ということをやりたかったんだけど、これを実現する方法として、

  • app 側で対応する
    • 汎用的にしたかったのでなし
  • 手前にいる reverse proxy(apache2.2)にやらせる
    • プロキシした結果 404 だったら別の何かを 200 で返す、という方法がわからなかった
    • あったとしても mod_rewrite での対応となると今回はきつい
      • このアプリにプロキシされるまでにすでにカオス RewriteRule をくぐり抜けてきているので...
  • さらに手前にいる varnish / perlbal にやらせる
    • varnish がバックエンドから 404 うけとったら req.url 書き換えて restart、varnish の後ろにいる perlbal の web server につかませる
    • キャッシュがあればバックエンドひと通り巡るコストもなく速いが関係者が増えるのでなんかいや
  • Middleware::ErrorDocument で subrequest なげて Middleware::Static につかませる
    • 404 は普通につかいたいので、それとは別に enable_if { $_[0]->{PATH_INFO} =~ m{/favicon.ico} } ErrorDocument 〜 とかしてわけて、Static で path => sub { s/// } で PATH_INFO 書き換えて特定ディレクトリからさがす
    • 別にこれでよかった(え)

など堂々めぐりした結果、簡単にできるやつをということで作った。

使い方はこんなん感じ。

enable "DefaultDocument",
    '/favicon\.ico$' => '/path/to/htodcs/favicon.ico',
    '/robots\.txt'   => '/path/to/htdocs/robots.txt';

app からのレスポンスコードが 404 だった場合に、PATH_INFO が key の正規表現にマッチしたら value のファイルを返す、という動作をする。404 以外が返っていこうとした場合は何もしない。

MogileFS からファイル探して、なかったらデフォルトのなにかを必要に応じてだす感じだとこういう風の例。

DefaultDocument という名前は英語的、動作の説明的に微妙な気がしないでもない...。そして相変わらずの俺得 module 感...。