至急近況を報告するように。
秋葉原行ってたよ。お目当ては洋食キッチンジロー。
WX310Kから正式に機種変してきた。お古は母のところへ置いてきました。これに関連してストラップやら2GBのminiSDカードやらクレードル型充電器やら買ったら、けっこうな出費に。
しかし今2GBのminiSDって死ぬほど安いな。2199円(税込)ってなんだよ。半年前に512MBを7000円で買った馬鹿がここにいますよ。トランセンドの割とまともそうな奴で、実際ZERO3でも問題なく使えました。
問題があったのはHPプリンタで、前面端子(カードスロット)で認識しなかった(^^;USBアダプターでは2GB認識しないとかありそうね。最近売ってる奴は問題ないんだろうけど。
以下の文章は素人のヨタ... 馬鹿の戯言 なのであまり信用しないように...。
改めてGoogleMapなどの例を挙げるまでもなく。 GoogleなどのWebアプリケーションの持つ 軽快感はAjax技術による ところが大きいわけです。 しかし、ページ遷移がなく、非同期イベントで軽快に部分部分が書き換わるというAjaxアプリケーションの特性は、 結果的に 大量の通信イベントを引き起こします。 もちろんGoogleのように数万〜数十万台?の分散サーバ(クラウドサーバ)を持つ企業はいいわけですが、 個人サーバだとアクセス数がネックだというお話。
ここ1週間くらいAjaxチャットサーバを作っていたのですが、仲間うちで運用しようとするとどうしようもなく重い。 チャットというのは見掛けよりリアルタイム性の高いアプリケーションなので、けっこう難しいのだ。 無論「チャットごとき」が難しいのは俺のプログラミング能力が低いことによるのだが....。
誰かが文章をタイプしてENTERキーを押したとき、それは一瞬でメンバー全員に同報したい。 昔のWeb掲示板で、F5キーを連打して「更新されないかなー」と待った覚えがある人もいるでしょう。 しかしこれ 簡易DOS攻撃 になりえます。 Re::Monologueさんのまとめが最もわかりやすいです。 ポーリング実装はアレなので回避することにする。
上記ポーリングに対する答えがCometという技術による疑似サーバプッシュです。これは要するに 「サーバにコネクション張りっぱなしにして(データ返さないで)クライアント待たせればいいんじゃね?」 という話。 現実にはクライアントタイムアウトがあるので永続性はないのですが、現状は汎用的なWebブラウザとノンプラグインで サーバプッシュを実装するには、Cometしかないみたい。 JavaScript側のコードについてはCodeZineさんが詳しい。 というか俺はこれをマルパクした(笑)
じゃあCometで万事解決かというと....ようやっと本題なんだけど....
という問題が発生する。というか発生した。CodeZineさんはサーバサイドをネイティブJavaでコーディングしていたが、 俺はApache2 + Perlスクリプト。PerlはIO::Socket select()とSQLite3を使った同期をするわけね。 まあ本質的にこの構造が良くないんだがね....SQLite3は行ロックはおろかテーブルロックですらない DBロック なので(だよね?) 、誰かが使っていると絶対に他の処理はCommit()できない。これに Apache2のCGIの起動の遅さ が加わると 壊滅的になる。
なのでチャット用Webサーバは自作せざるを得ない...という話になる(←それ以前にDBMSを変えろよ)。 最初C言語で書こうと思ったのだが正規表現とかいろいろ面倒くさいし、PerlモジュールのPOE::Component::Server::HTTPを使うことにした。サンプルはこんな感じ。これだけでWebサーバが作れちゃう。 これもココからマルパクですが。
#!/usr/bin/perl use strict; use POE qw( Component::Server::HTTP ); use HTTP::Status; sub root_output { my ($content_type) = @_; return sub { my ($req, $res) = @_; print "IP:" . $req->{connection}->{remote_ip} . "\n"; $res->code(RC_OK); $res->content_type('text/html'); $req->headers->header(Connection => 'close'); $res->headers->header(CacheControl => 'no-cache'); $res->headers->header(Pragma => 'no-cache'); $res->headers->header(Expires => '-1'); my $html = '<html><body>TEST</body></html>'; $res->content($html); return RC_OK; }; } my $servers = {}; my @listenports = (8891); foreach my $serverport (@listenports) { $servers->{$serverport} = POE::Component::Server::HTTP->new( Port => $serverport, ContentHandler => { '/' => &root_output() } ); } POE::Kernel->run(); exit 0;
とりあえず。チャットサーバのステータス画面(SQLite3検索してCGI::FastTemplateでレンダリングして900bytesくらいのHTMLを出力)をApache2(CGI)とPOEで実装し簡単なベンチマークをとってみた。 なかなかいい感じ に見えるがどうだろうか。
![]() |
というか Apache2ってマジ遅い んだな...。
Document Length: 869 bytes Concurrency Level: 16 Time taken for tests: 35.217505 seconds Complete requests: 300 Failed requests: 0 Write errors: 0 Total transferred: 340500 bytes HTML transferred: 260700 bytes Requests per second: 8.52 [#/sec] (mean) Time per request: 1878.267 [ms] (mean) Time per request: 117.392 [ms] (mean, across all concurrent requests) Transfer rate: 9.43 [Kbytes/sec] received
POEだと余計なオーバーヘッドがないので速いと。
Document Length: 869 bytes Concurrency Level: 16 Time taken for tests: 1.584481 seconds Complete requests: 300 Failed requests: 0 Write errors: 0 Total transferred: 326400 bytes HTML transferred: 260700 bytes Requests per second: 189.34 [#/sec] (mean) Time per request: 84.506 [ms] (mean) Time per request: 5.282 [ms] (mean, across all concurrent requests) Transfer rate: 200.70 [Kbytes/sec] received
Googleは1つの検索クエリーに対し、1000台のマシンを使って0.2秒で処理している
ちまちまやってるのがアフォらしくなるわ。
![]() |
Before...
_ Anastasialij [buydig vizion scanwizard5 phonebooks on cd teeth whiteing ..]
_ Evangelineavq [nba live 360 red cd player divorce mediation saltimbanco b..]
_ Jenniferegj [alvar air o swiss 1355 dual microphones swedish chef muppe..]