Your SlideShare is downloading. ×
  • Like
Mojolicious+redisでチャットを作った
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Mojolicious+redisでチャットを作った

  • 1,225 views
Published

 

Published in Technology , Career
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,225
On SlideShare
0
From Embeds
0
Number of Embeds
4

Actions

Shares
Downloads
4
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Mojolicious+Redisでチャット を作った Mishima.pm #1 @dokechin
  • 2. Mojolicious • Perl のWeb Application Framework • 広大なMojoネーム空間のモジュール群をWeb アプリで使うようにしたもの
  • 3. http://blog2.jamadam.com/?p=808 より引用
  • 4. 私の考えるメリット • 開発コミュニティが世界的に活発 (MojoConf2014 in オスロなど。2015への 積立金もすでにプールされている。) • ドキュメント豊富、サンプルソースも一杯あふ れている • All in One • 環境構築が楽、cpanm Mojolicious
  • 5. 非同期な話 1.MojoliciousとNode.jsは非同期サーバ
  • 6. Mojoliciousでsleepしてみた #!/usr/bin/env perl use Mojolicious::Lite; get '/' => sub { my $self = shift; sleep(10); $self->render('index'); }; get '/hoge' => sub { my $self = shift; $self->render('hoge'); }; app->start;
  • 7. /をGETその後すぐ、/hogeをGET /hogeが先に返ってくるのでは・・ と期待していたが・・・
  • 8. 結果は・・ /が返ってから/hogeが返ってくる! 処理の流れを1つにすることで、サーバー資源を 節約?どこかで聞いたことあるなぁ・・・
  • 9. 非同期な話 2.非同期vs同期ベンチマーク
  • 10. 同期なコード package Test::Web::Example; use Mojo::Base 'Mojolicious::Controller'; use Time::HiRes qw(sleep); sub welcome { my $self = shift; sleep(0.5); $self->render( message => 'Welcome to the Mojolicious real-time web framework!'); } 1;
  • 11. 非同期なコード package Test::Web::Example; use Mojo::Base 'Mojolicious::Controller'; use Time::HiRes qw(sleep); sub welcome { my $self = shift; $self->render_later; Mojo::IOLoop->timer(0.5 => sub { $self->render( message => 'Welcome to the Mojolicious real-time web framework!'); }); } 1;
  • 12. Apache bench ab –c 100–n 1000 http://your_host_name/ サーバ構成 さくらVPS メモリ 1G CPU 仮想2コア nginx1.6+hyponotad 5workers nginx1.6+starman 5workers
  • 13. 結果 0 100 200 300 400 500 600 0 0.2 0.4 0.6 0.8 1 1.2 同期(starman+5workers) 非同期(hyponotad+5worker) 同期(hyponotad+5worker)
  • 14. トレードオフ 容易な同期的プログラ ミング 難しい非同期プログラ ミング サーバリソース大 サーバリソース小
  • 15. その他、ベンチをやって気づいたこと ・starman,startletでは、Mojoliciousの非同期機能 が使えない
  • 16. 非同期な話 3.実践的な非同期コードについて
  • 17. 同期的コード sub mojo4{ my $self = shift; my $ua = LWP::UserAgent->new; my $res = $ua- >get("http://atndfc.dokechin.com"); if ($res->is_success) { $self->render(message => $res->content); } else { die $res->status_line; } }
  • 18. 非同期的コード package Test::Web::Example; #use Mojo::UserAgent; sub mojo{ my $self = shift; $self->ua- >get('http://metacpan.org/search?q=mojo' =>sub{ my ($ua, $tx) = @_; $self->render(message => $tx->res); }); } 1;
  • 19. Mojolicious用各種非同期APIを使う Mojo::Redis(Redis非同期クライアント) Mango(Mongo非同期クライアント)
  • 20. ブロッキングAPIしかない場合 Mojo::IOLoop::ForkCall - run blocking functions asynchronously by forking
  • 21. 非同期な話 3.Callback hellを避けるためには
  • 22. # callback hell code sub mojo{ my $self = shift; $self->render_later; $ua->get('http://yahoo.co.jp/' => sub{ my ($ua, $tx) = @_; my $title1 = $tx->res->dom->html->head- >title->text; $ua->get('http://google.com/' => sub{ my ($ua, $tx) = @_; my $title2 = $tx->res->dom->html->head- >title->text; $self->render(msg => $title1 . $title2); }); }); }
  • 23. # finish sub mojo2{ my $self = shift; $self->render_later; my $delay = Mojo::IOLoop::Delay->new; $delay->on(finish=>sub{ my $delay = shift; my @titles = map { $_->res->dom- >at('title')->text } @_; $self->render(message => "@titles"); }); $self->ua->get( $_ => $delay->begin ) for@urls; }
  • 24. # stepsを利用したコード sub mojo3{ my $self = shift; $self->render_later; my $delay = Mojo::IOLoop::Delay->new; $delay->steps(sub{ my ($delay) = @_; $self->ua->get( "http://www.cpan.org/" => $delay->begin); $self->ua->get( "http://jognavi.com/" => $delay- >begin); }, sub { my ($delay,@args) = @_; my @messages = map {$_->res->dom->at('title')- >text} @args; $self->render(message=> "@messages"); }, ); }
  • 25. チャットを作った話 • まずはデモ
  • 26. morbo W WebSocket WebSocket WebSocketWebSocket UserA UserB UserC UserD ・すべておなじプロセス配下のため、同じ部屋 の発言の通知は可能。 ・スケーラブルでない RoomA RoomB
  • 27. hypnotoad W WebSocket WebSocket WebSocketWebSocket UserA UserB UserC UserD RoomA RoomB Wプロセス間通信の手段が必要
  • 28. Redis(部屋、部屋の入居者管理) W WebSocket WebSocket WebSocketWebSocket W RoomA RoomB Red is UserA UserB UserC UserD
  • 29. Redis-オブジェクトキャッシュ rooms => {“rooma”,”roomb”} rooma=>{“userA”,”userB”} roomb=>{“userC”,”userD”}
  • 30. RedisのPubSub UserA,UserBがRoomAチャンネルを購買。UserA がRoomAチャンネルへ発言、チャンネルAの購 買者(UserA,UserB)に発言内容が通知される。
  • 31. まとめ • 非同期はパフォーマンスがよくなるが、コード は複雑化する。 • Mojoliciousは非同期に動かす仕組み(モジュール、 サーバ)が、備わっている。 • 本番環境での運用を視野にするならば、初めか らRedisなど、Kye-Valueストアを使ったほうが よい?
  • 32. ご清聴ありがとうございました