Your SlideShare is downloading. ×
0
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
サーバー実装いろいろ
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

サーバー実装いろいろ

1,292

Published on

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,292
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
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. サーバー実装いろいろ その1 反復サーバー (iterative server) 並行サーバー (concurrent server)  ・ Fork server  ・ PreFork server
  • 2. クライアント サーバー リクエスト レスポンス
  • 3. 粒度を細かくすると下記のように (HTTP サーバとブラウザを想定。つまり TCP) クライアント サーバー SYN SYN, ack ack データ(要求) データ(応答) , 要求の ack 応答の ack FIN ack FIN ack socket,bind,listen accept( ブロック ) accept から戻る read( ブロック ) connect write read( ブロック ) read から戻る サーバが要求を処理 write read( ブロック ) read から戻る close close
  • 4.  
  • 5. 反復サーバ (iterative server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li></ul><ul><li>my $socket = IO::Socket::INET->new( </li></ul><ul><li>Listen => 20, </li></ul><ul><li>LocalPort => 12345 </li></ul><ul><li>) or die; </li></ul><ul><li>while ( my $con = $socket->accept ) { </li></ul><ul><li>my $line = <$con>; </li></ul><ul><li>print $con $line; </li></ul><ul><li>close $con; </li></ul><ul><li>} </li></ul>サーバー リクエスト 確立待ちコネクションキュー 確立済みコネクションキュー Listen キュー 3way hand shake 完了後 accept 問題点: リクエストの read でブロックするので複数接続あった場合、 最初の接続がリクエストをもたつくと後の接続が待たされる ことになる
  • 6. Fork サーバ (concurrent server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li></ul><ul><li>my $socket = IO::Socket::INET->new( </li></ul><ul><li>Listen => 20, </li></ul><ul><li>LocalPort => 12345 </li></ul><ul><li>) or die; </li></ul><ul><li>while ( my $con = $socket->accept ) { </li></ul><ul><li>my $pid = fork; </li></ul><ul><li>if ( $pid == 0 ) { </li></ul><ul><li>## child </li></ul><ul><li>close $socket; </li></ul><ul><li>my $line = <$con>; </li></ul><ul><li>print $con $line; </li></ul><ul><li>exit(0); </li></ul><ul><li>} </li></ul><ul><li>else { </li></ul><ul><li>## parent </li></ul><ul><li>close $con; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>サーバー リクエスト 問題点: accept の度に fork するコスト accept サーバー accept fork サーバー サーバー サーバー サーバー 親 子
  • 7. 余談: pipe(READ, WRITE) 関数 IPC 通信の基礎。親プロセス子プロセスの間で 対話できるようになる。 fork しないとできないわけではなく、より身近な例としてまさしく パイプコマンドがある。「 ls | wc 」 fork READ WRITE 親 親 子 子 READ WRITE READ WRITE READ WRITE READ WRITE READ WRITE
  • 8. PreFork サーバ (concurrent server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li></ul><ul><li>use POSIX 'WNOHANG'; </li></ul><ul><li>my $socket = IO::Socket::INET->new( </li></ul><ul><li>Listen => 20, </li></ul><ul><li>LocalPort => 12345 </li></ul><ul><li>) or die; </li></ul><ul><li>for ( 1 .. 5 ) { </li></ul><ul><li>my $pid = fork; </li></ul><ul><li>if ( $pid == 0 ) { </li></ul><ul><li>## child </li></ul><ul><li>while ( my $con = $socket->accept ) { </li></ul><ul><li>close $socket; </li></ul><ul><li>my $line = <$con>; </li></ul><ul><li>print $con $line; </li></ul><ul><li>close $con; </li></ul><ul><li>} </li></ul><ul><li>exit(0); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>## parent; </li></ul><ul><li>$SIG{CHLD} = sub { </li></ul><ul><li>while ( waitpid( -1, WNOHANG ) > 0 ) { </li></ul><ul><li>} </li></ul><ul><li>}; </li></ul><ul><li>while (1) { </li></ul><ul><li>## 子プロセスの数を調整するなど色々 </li></ul><ul><li>} </li></ul>確立待ちコネクションキュー 確立済みコネクションキュー Listen キュー 子 子 子 accept accept accept
  • 9. Net::Server <ul><li>lib </li></ul><ul><li>`-- Net </li></ul><ul><li>|-- Server </li></ul><ul><li>| |-- Daemonize.pm </li></ul><ul><li>| |-- Fork.pm </li></ul><ul><li>| |-- HTTP.pm </li></ul><ul><li>| |-- INET.pm </li></ul><ul><li>| |-- MultiType.pm </li></ul><ul><li>| |-- Multiplex.pm </li></ul><ul><li>| |-- PreFork.pm </li></ul><ul><li>| |-- PreForkSimple.pm </li></ul><ul><li>| |-- Proto </li></ul><ul><li>| | |-- SSL.pm </li></ul><ul><li>| | |-- SSLEAY.pm </li></ul><ul><li>| | |-- TCP.pm </li></ul><ul><li>| | |-- UDP.pm </li></ul><ul><li>| | `-- UNIX.pm </li></ul><ul><li>| |-- Proto.pm </li></ul><ul><li>| |-- SIG.pm </li></ul><ul><li>| `-- Single.pm </li></ul><ul><li>|-- Server.pm </li></ul><ul><li>`-- Server.pod </li></ul>sub run { ### pass package or object my $self = ref($_[0]) ? shift() : shift->new; $self->_initialize(@_ == 1 ? %{$_[0]} : @_); # configure all parameters $self->post_configure; # verification of passed parameters $self->post_configure_hook; # user customizable hook $self->pre_bind; # finalize ports to be bound $self->bind; # connect to port(s) # setup selection handle for multi port $self->post_bind_hook; # user customizable hook $self->post_bind; # allow for chrooting, # becoming a different user and group $self->pre_loop_hook; # user customizable hook $self->loop; # repeat accept/process cycle ### routines inside a standard $self->loop # $self->accept # wait for client connection # $self->run_client_connection # process client # $self->done # indicate if connection is done $self->server_close; # close the server and release the port # this will run pre_server_close_hook # close_children # post_child_cleanup_hook # shutdown_sockets # and either exit or run restart_close_hook }
  • 10. 課題 <ul><li>Starman </li></ul><ul><li>Starlet </li></ul><ul><li>Catalyst::Engine::HTTP </li></ul><ul><li>HTTP::Server::PSGI </li></ul><ul><li>Hoppy(?) </li></ul><ul><li>socket オプション等をもっと掘り下げる </li></ul><ul><li>non-blocking についてkwsk </li></ul>
  • 11. 参考書籍

×