mala氏の Studying HTTP with Perl を見ながら書いたノートの清書
- リクエストを 5000/sec とかするときのための
- 200/secでよければ別にLWP使ってればいいよマジで、実際便利だし。
非並列なhttpアクセス
LWP::RobotUA | robots.txt見たりするので行儀が良い |
URI::Fetch | キャッシュとかする、インターフェースがいい |
HTTP::Lite | 依存モジュールなし、どこでも使えるよ |
LWPx::ParanoidAgent | ローカルIPは弾く、WEB魚拓的サービスに |
並列なhttpアクセス
AnyEvent::HTTP | 簡単 |
Coro::LWP | コルーチン、黒魔術(なにをしてるか理解して使おう) |
AnyEvent::Curl | curlのオプションを覚えなくてはダメ |
- Coro::LWPはLWPをcoro使用に全て置き換えるから注意。
- coroそのものを知りましょう
perlで並列処理をする場合
イベント駆動+prefork が最適解
- I/O待ち
- 非同期
- 重い処理
- worker
- ブロッキング
- forkして別プロセス
preforkは諸問題あるからイベント駆動がおすすめ
いちおう、処理時間、アクセス時間が完璧に計算出来るのであればpreforkの方がいい。
早いパーサ
HTTP::Response::Parser
- ヘッダとかLastModifiedの速度とかbodyを分けるためのパーサ
- 既存の重い
- PurePerlでがんばって、XSした
- picohttpparser(とても優秀) を使った
- 欠点:今は不安定(関連libのせい、verupなど待ち
DNS解決が遅い
RPC
プロトコルを作るな、httpでいい。httpは充分早いし。汎用性高いし。
テスト手法
タイムアウトサーバのコード
app => sub { my $env = shift; my $req = Plack::Request->new($env); sleep 2; return [ 200, [ 'Content-Type' => 'text/plain' ], ["Hellow World after 2 sec"] ]; },
クライアント側の方
client => sub { my $cb = shift; my $req = HTTP::Request->new(GET => "http://localhost/hello"); my $cv = $cb->($req, sub{}, {timeout => 1}); my $res = $cv->recv; ok( !$res->is_success, "fail by timeouot" ); is( $res->code, 500, "check status code"); is( $res->{error}, WWW::Curl::Easy->new->strerror(CURLE_OPERATION_TIMEDOUT), "error str" ); }
おわり