新しいblogに移行しました

新ブログ "All Yout Bugs Are Belong To Ass" に移行しました!

2011-03-28

[Perl]Hachioji.pm #3 に参加しました

公式にもレポートがあがってます通り、3/26(土)にHachioji.pm #3が開催されました。

Hachioji.pm #3 開催いたしました! - hachioji.pm

詳細ついては、こことかこちらとかを参照のこと。

じつはかなり酔っ払っていて、あまり細かいことは覚えていないのです。でもまあ、概ね以下のような話題でがやがやと話していたとおもいます(本当に記憶が薄れてるので、覚えてるとこだけ箇条書きでw)

地震と計画停電

・八王子は駅前付近も含めて、ちょくちょく停電が実施されている模様。
・停電のせいで仕事にならない人も。
・今、インフラ系の人は大変ですよね。。。
・データセンターでも、一部では発動機用の燃料を確保するのに大変。
・さくらは大阪なのでさくらVPSはたぶん大丈夫。
・東京23区にお住まいの方はあまり実感がないらしく、「たいへんそうですねー」とコメント。
・八王子はあまりゆれないらしい。uzullaさんのTL見てると「ゆれてなーい」とか言っててうける。
・今回のHachioji.pm開催に際して「不謹慎」等のツッコミが一切なかった。

毎度おなじみ

makamakaさんが遅れて到着(予め遅れるという話はいつもの事)した時に、全員で大きな拍手を持って迎えられてました。

バッドノウハウ

LTで扱った話題とも重複するのですが、「これってバッドノウハウだよねー」というものがいくつかありました。
※決してFUDではないです。

・MySQL
 データベース操作とかチューニングとかレプリケーションとか・・・

・Q4M
 成り立ちからしてバッドノウハウだという意見も。
 >つまりグッドラッパー???

・Apache
 XMLもどきなconfファイルがそもそもバッドノウハウ。
 >名前からして"a patchy"をもじってるので、バッドノウハウの権化といえるのかも。
 ちなみに、いまならnginxでほぼ代替可能でしょう。

・PHP
 多くを語らずとも皆さんが「これはバッドノウハウ」という認識のようでした。。。
 これもapacheと同じで、バッドノウハウの権化となるべくしてなってる感が強いです。
 
・ガラケー向けノウハウ全般
 絵文字周りのノウハウとかは特にバッドノウハウの塊といえるでしょう。
 それに対するグッドラッパーがPerlにもPHPにも豊富なのですが。

・SJIS-win
 PHPで扱うことの出来る文字コードのひとつ。なぜCP932じゃないんだ。。。
 ちなみにPHPにはCP932をまっとうに扱えるライブラリ類が無いんだそうで。

・IE6
 「IE6とガラケー向けノウハウが無くなれば、8割のバッドノウハウは消え失せる」といわれるほどのバッドノウハウの総合商社っぷり。
 これについてはそのままFUDとして受け取ってもらっても構わないでしょうw

しかしuzullaさんも言っていたように、バッドノウハウをうまく利用する/ラップする仕事というのは、大抵お金的においしい仕事だったりします。
バッドノウハウをDISったりするのは、ぶっちゃけ素人でもできるわけです。単にバッドノウハウを忌み嫌うのではなく、バッドノウハウとうまくお付き合いするという考え方は、実はギークの態度として非常に大切なものではないでしょうか。

今後おいしくなる仕事とは何だろう

・バッドノウハウを要する仕事はおいしい
・ソーシャルアプリは100万人単位の登録数がないとあまりおいしくなさそう。
・震災復興特需に期待か。具体的には土木・建築・電力系に関連したお仕事等。

2011-03-24

[Linux]nginxをさくらVPSのCentOS5.5に入れてみた

最近借りた「さくらのVPS(CentOS5.5)」にnginx-0.8.54をインストールしてみました。

nginxとは

nginx - Wikipedia

ダウンロード

http://wiki.nginx.org/InstallJaからダウンロードできます。
CentOSにはrpmforge含めyumパッケージが無いので、ソースからインストールします。
今回は「安定版」とされている0.8系を選択しました。

インストール

僕が試した限り、以下のyumパッケージを予めインストールしておく必要がありました。
  • pcre-devel
  • openssl-devel
その後はtarballを復元し、configure, make, make installの順に実行してあげればOKでした。
コマンドをまとめると、以下の様になるはずです。
# yum -y install pcre-devel openssl-devel
 # tar zxvf ./nginx-0.8.54.tar.gz
 # cd ./nginx-0.8.54
 # ./configure && make && make install
/usr/local/nginxにいろいろ入っていればインストール成功です。

nginxを起動する

では、httpサーバとしてnginxを起動してみます。
# /usr/local/nginx/sbin/nginx
これだけです。

nginxを停止する

停止する場合は
# /usr/local/nginx/sbin/nginx -s stop
と実行するだけです。

ネームバーチャルを設定する

ドメイン毎にドキュメントルートを変えたりしたかったので、ネームバーチャルを設定しました。
設定ファイルは /usr/local/nginx/conf/nginx.conf です。
server {
        listen 80;
        server_name alpha.ytnobody.net;
        location / {
            root vhosts/alpha;
            index index.html;
        }
    }

    server {
        listen 80;
        server_name beta.ytnobody.net;
        location / {
            root vhosts/beta;
            index index.html;
        }
    }
こんな感じの記述を http { ... } の中に書いてやります。

プロキシとして動作させる

バックエンドでstarmanとか動かしたいので、プロキシとして動作させてみました。
nginx.confに以下のようなネームバーチャルを追加し、ネームバーチャルをまるごとプロキシとしました。
server {
        listen 80;
        server_name lab.ytnobody.net;
        location / {
            proxy_pass http://127.0.0.1:5000;
        }
    }

で、急ごしらえの動確用PSGIアプリを
sub {
    [ 200, 
      [ 'Content-Type' => 'text/html' ], 
      [ '<html><head><title>PLACK</title></head><body>PLACK!</body></html>' ] 
    ];
};
こんな感じででっち上げて、plackupで起こしてやります。
$ plackup ./hoge.pl
これで、lab.ytnobody.netにアクセスすると、PSGIアプリにリクエストが流れます。

ロードバランシングさせる

さきほどのlab.ytnobody.netを改造して、ロードバランサとして設定してみます。
upstream mybalancer {
        server www.google.com:80;
        server www.cpan.org:80;
        server www.yahoo.co.jp:80;
    }

    server {
        listen 80;
        server_name lab.ytnobody.net;
        location / {
            proxy_pass http://mybalancer;
        }
    }
これだけで、upstreamのserver達にリクエストがバランシングされます。

フォアグラウンドで走らせて、daemontoolsに食わせやすくする

nginxをフォアグラウンドで動かすには、
# /usr/local/nginx/sbin/nginx -g 'daemon off;'
のように、グローバル指定子"daemon off;"を指定する必要があります。
しかし、これだけだとログがローテートされません。放っておくと、アホみたいなサイズになってしまいます。
これもdaemontoolsに任せてしまいたいので、どうにかログを標準出力に吐いておきたいところ。
そこで、/dev/stdoutにログを吐いてやるように設定したところ、期待通りの動作となりました。
server {
        listen 80;
        server_name lab.ytnobody.net;
        access_log /dev/stdout;
        location / {
            proxy_pass http://mybalancer;
        }
    }

さいごに

いままでnginx使ってなかった理由がわからない!!!!というほど、簡単に導入できました!!
さようならapache!もう君には(よほどの事がない限り)世話にならないだろう!

2011-03-13

[地震]東京電力より輪番停電のおしらせ

PDF版 https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BwapBcGA1141Y2FkNmU4YWItYTA3My00ODY5LTk0ZTEtYzU4MWI1MjRmN2Nl&hl=ja&pli=1

毎日.jpによるHTML版

第1グループ 6:20~10:00 の時間帯のうち3時間程度
第1グループ 16:50~20:30 の時間帯のうち3時間程度

第2グループ 9:20~13:00 の時間帯のうち3時間程度
第2グループ 18:20~22:00 の時間帯のうち3時間程度

第3グループ 12:20~16:00 の時間帯のうち3時間程度

第4グループ 13:50~17:30 の時間帯のうち3時間程度

第5グループ 15:20~19:00 の時間帯のうち3時間程度

2011-03-04

[Perl]plackアプリとAttribute::Handlersの相性は悪い

先日作ったRouter::Simple::Attributeを使ってPlackベースのWAFを作ろうとしたのですが、どういうわけかrouterの中身がカラッポになってしまい、ちっともまともに動作してくれませんでしたorz

で、よくよく調べてみると、どうやらPlack::SandboxとAttribute::Handlersの相性がよろしくない模様でした。

検証用コード - eg/sample.pl

まあ幾つかツッコミどころが有りますけど、問題の本質とは関連がないものばかりの筈なのでスルー。
use warnings;
use strict;
use lib qw( ../lib ./lib );
use Attribute::Handlers;
use Router::Simple;
use Data::Dumper;

my $router;

BEGIN {
    $router = Router::Simple->new();
}

sub Path :ATTR {
    warn Dumper( @_ );
    my $path = $_[4];
    my $code = $_[2];
    $router->connect( $path, { code => $code } );
}

sub myapp : Path(/) { 
    warn Dumper( @_ );
    [ 200, ['text/html'], ['Hello, world!'] ];
}

warn Dumper( $router, __PACKAGE__ );

sub {
    my $env = shift;
    if ( my $p = $router->match( $env ) ) {
        $p->{ code }->( $p );
    }
    else {
        [404, [], ['no']];
    }
};

perlコマンドから直接実行して見た場合

$ perl eg/sample.pl 
Useless use of reference constructor in void context at eg/sample.pl line 35.
$VAR1 = 'main';
$VAR2 = \*::myapp;
$VAR3 = sub { "DUMMY" };
$VAR4 = 'Path';
$VAR5 = '/';
$VAR6 = 'CHECK';
$VAR7 = 'eg/sample.pl';
$VAR8 = 24;
$VAR1 = bless( {
                 'routes' => [
                               bless( {
                                        'pattern_re' => qr/(?-xism:^\\/$)/,
                                        'pattern' => '/',
                                        'capture' => [],
                                        'dest' => {
                                                    'code' => sub { "DUMMY" }
                                                  },
                                        'name' => undef,
                                        'on_match' => undef
                                      }, 'Router::Simple::Route' )
                             ]
               }, 'Router::Simple' );
$VAR2 = 'main';
一応、Pathアトリビュートのトリガが引かれていることが確認できてます。

plackupした場合

では、今度はeg/sample.plをplackupで起こしてみます。
$ plackup eg/sample.pl 
$VAR1 = bless( {
                 'routes' => []
               }, 'Router::Simple' );
$VAR2 = 'Plack::Sandbox::eg_2fsample_2epl';
HTTP::Server::PSGI: Accepting connections at http://0:5000/
こんな感じで、Pathアトリビュートのトリガが引かれません。

誰かおしえてください

そんなわけで、plackupからでも問題なく使用できるメソッドアトリビュートハンドラを探しています。
どなたかご存知の方、教えてください。よろしくお願いしますm(_ _)m


教えていただきました!

Twitterで、色々な方にご教示頂きました!この場を借りて、改めて御礼申し上げます。
まとめると、僕は「Attribute病」:) に罹患していたらしく、

・PSGIアプリではINIT/CHECKなどが呼ばれないため、アトリビュートはほぼ動かない。
・アトリビュート使うと、第3者からみて「何してるかわからないコード」になってしまい、おすすめできない。
・Attr::Handlers sucks, and Perl5 attribute sucks too. で FA。

ということらしいです。従って結論は

アトリビュートを使うのはお止しなさい

2011-03-03

[Perl]Router::Simple::Attributeというものをつくったものの、筋が悪い物だった

最近、そろそろ自前のWAFが欲しいと思い始めているのですが、いかんせん設計がまとめきれていないので、作っては棄てを繰り返しています。
そんな中、Router::Simpleを弄っていて、「毎度newするの面倒だなあ。connectって毎度書くのも億劫だしぃ。。。」とか思っちゃって、じゃあAttributeにパス書けるようにしたらどうだろうということで、Router::Simple::Attributeなるものをつくってみました。

使い方

use MyApp;
  use Router::Simple::Attribute;
  
  sub root : Path(/) {
      return 'root';
  }
  
  sub home : Path(/home/:myname) {
      return 'ok, '. shift->{ myname }. '!';
  }
  
  router->do( '/' );              # >>> 'root'
  router->do( '/home/ytnobody' ); # >>> 'ok, ytnobody!'

podをコピってきただけなんですけど、とりあえず簡単に説明。

Pathアトリビュートのついたサブルーチンを作ると、Router::Simple->connect相当のことをやってくれます。アトリビュートオプションには、Router::Simple流のパス文字列を渡してやるといいです。

それから、router()という関数が使えるようになります。こいつはRouter::Simpleのインスタンスを返しますが、これにはdoというメソッドが追加されています。

doメソッドは、Router::Simple::match()の返り値(=HashRef)の要素{code}をコードリファレンスとして実行するものです。
素のRouter::Simpleの場合、
$router->connect( '/path/:user', { code => sub { ... } } )

...

if ( my $p = $router->match( $env ) ) {
    $p->{code}->( ... );
}
else {
    ...
}
こんなふうに { code => sub { ... } } のところとか if文のくだりが若干冗長に感じますが、R::S::Attributeなら、
sub user :Path(/path/:user) { ... }

...

return router->do( $env ) || [ 404, [], ['not-found'] ];
みたいな書き方が可能です。

但し書き

当然ですが、Router::Simpleに処理を追加しているモジュールなので、Router::Simpleより遅いです。
あと、例によってテストが少なく、自分でもまだ実戦投入できていないものなので、信頼性については「?」という具合です。とはいえ、R::S::Attribute自体のコード量は非常に少なく、Router::Simpleが安定しているので、何か問題があったとしても、トレースはしやすいとおもいます。

2011-3-4 追記
どうやら、Plack::Sandbox::*とAttribute::Handlersの相性が悪いらしく、plackupからうまく利用できませんでした。
この辺を調査した時の記録は、こちらの記事に書きました。
一つ言えるのは、Attribute::Handlers や Perl5のアトリビュートを使うのは筋がよろしくないということです。