0
サーバー実装いろいろ その1 反復サーバー (iterative server) 並行サーバー (concurrent server)  ・ Fork server  ・ PreFork server
クライアント サーバー リクエスト レスポンス
粒度を細かくすると下記のように (HTTP サーバとブラウザを想定。つまり TCP) クライアント サーバー SYN SYN, ack ack データ(要求) データ(応答) ,  要求の ack 応答の ack FIN ack FIN ack...
 
反復サーバ (iterative server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li></ul><...
Fork サーバ (concurrent server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li></...
余談: pipe(READ, WRITE) 関数 IPC 通信の基礎。親プロセス子プロセスの間で 対話できるようになる。 fork しないとできないわけではなく、より身近な例としてまさしく パイプコマンドがある。「 ls | wc  」 for...
PreFork サーバ (concurrent server) <ul><li>use strict; </li></ul><ul><li>use warnings; </li></ul><ul><li>use IO::Socket; </li...
Net::Server <ul><li>lib </li></ul><ul><li>`-- Net </li></ul><ul><li>|-- Server </li></ul><ul><li>|  |-- Daemonize.pm </li>...
課題 <ul><li>Starman </li></ul><ul><li>Starlet </li></ul><ul><li>Catalyst::Engine::HTTP </li></ul><ul><li>HTTP::Server::PSGI...
参考書籍
Upcoming SlideShare
Loading in...5
×

サーバー実装いろいろ

1,316

Published on

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

No Downloads
Views
Total Views
1,316
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "サーバー実装いろいろ"

  1. 1. サーバー実装いろいろ その1 反復サーバー (iterative server) 並行サーバー (concurrent server)  ・ Fork server  ・ PreFork server
  2. 2. クライアント サーバー リクエスト レスポンス
  3. 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 でブロックするので複数接続あった場合、 最初の接続がリクエストをもたつくと後の接続が待たされる ことになる
  5. 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 サーバー サーバー サーバー サーバー 親 子
  6. 7. 余談: pipe(READ, WRITE) 関数 IPC 通信の基礎。親プロセス子プロセスの間で 対話できるようになる。 fork しないとできないわけではなく、より身近な例としてまさしく パイプコマンドがある。「 ls | wc 」 fork READ WRITE 親 親 子 子 READ WRITE READ WRITE READ WRITE READ WRITE READ WRITE
  7. 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
  8. 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 }
  9. 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>
  10. 11. 参考書籍
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×