![Page 1: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/1.jpg)
How to build a High Performance PSGI/Plack Server
PSGI/Plack・Monocerosで学ぶハイパフォーマンス
Webアプリケーションサーバの作り方
YAPC::Asia 2013 TokyoMasahiro Nagano / @kazeburo
![Page 2: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/2.jpg)
Me• 長野雅広 Masahiro Nagano
• @kazeburo
• PAUSE:KAZEBURO
• Operations Engineer, Site Reliability
• LINE Corp. Development support LINE Family, livedoor
![Page 3: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/3.jpg)
livedoorBlogOne of the largest Blog Hosting Service in Japan
![Page 4: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/4.jpg)
livedoorBlog uses
![Page 5: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/5.jpg)
Perl (5.16 and 5.8)
![Page 6: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/6.jpg)
Carton
![Page 7: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/7.jpg)
Plack/PSGI and mod_perl
![Page 8: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/8.jpg)
$ curl -I http://blog.livedoor.jp/staff/| grep Server
Server: Plack::Handler::Starlet
![Page 9: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/9.jpg)
Starlet handles1 Billion(10億) reqs/day
![Page 10: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/10.jpg)
To get over this burst traffic,
We need to improvePerformance
across all layersこの負荷を乗り切るために様々なレイヤーで最適化をしています
![Page 11: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/11.jpg)
Layers
Hardware / Network
OS
App Server
Routing
Cache Logic
SQL
Template Engine
RDBMS
Cached Web Server
![Page 12: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/12.jpg)
Hardware / Network
OS
Routing
Cache Logic
SQL
Template Engine
RDBMS
Cached Web Server
Today’s Topic
![Page 13: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/13.jpg)
Hardware / Network
OS
Routing
Cache Logic
SQL
Template Engine
RDBMS
Cached Web Server
Today’s Topic
App Server
![Page 14: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/14.jpg)
By the way..
![Page 15: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/15.jpg)
“Open & Share”is our driver
for excellence.And LOVE CPAN/OSS
Open & Share は私たちの目指すところです。CPAN/OSSを多く使い、また貢献もしています
![Page 16: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/16.jpg)
Improving Performance of livedoorBlog
directly linkedPerformance of Plack/Starlet
on CPAN
livedoorBlogのパフォーマンス改善で行った事はCPAN上のPlack/Starletにも当然影響してきます
![Page 17: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/17.jpg)
0
3500
7000
10500
14000 13083
6241
“Hello World” Reqs/Sec
Plack 1.0016 1.0029Starlet 0.16 0.20
2013/02 2013/09
mod_perl era plack era
![Page 18: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/18.jpg)
Monoceros
![Page 19: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/19.jpg)
Monoceros isa yet another
Plack/PSGI Serverfor Performance
![Page 20: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/20.jpg)
the Goal
![Page 21: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/21.jpg)
Reduce TCP 3way hand shake
betweenProxy and PSGI Server
![Page 22: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/22.jpg)
ReverseProxy
AppServer
GET / HTTP/1.1Host: example.com
SYNACK
SYN+ACK
HTTP/1.1 200 OKContent-Type: text/html
FINACK
GET /favicon.ico HTTP/1.1Host: example.com
SYNACK
SYN+ACK
HTTP/1.1 404 NOT FOUNDContent-Type: text/html
FINACK
![Page 23: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/23.jpg)
HTTP/1.0-1.1 have KeepAlive
![Page 24: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/24.jpg)
ReverseProxy
AppServer
GET / HTTP/1.0Host: example.comConnection: keep-alive
SYNACK
SYN+ACK
HTTP/1.0 200 OKContent-Type: text/htmlConnection: keep-alive
Content-Length: 941
GET /favicon.ico HTTP/1.1Host: example.com
HTTP/1.1 200 OKContent-Type: image/vnd.microsoft.icon
Transfer-Encoding: chunked
GET /site.css HTTP/1.1Host: example.com
HTTP/1.1 200 OKContent-Type: text/css
Content-Length: 1013
![Page 25: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/25.jpg)
C10K problem
![Page 26: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/26.jpg)
nginx
C10KReadyReverseProxy
nginx
nginx
StarletStarman
AppServer
KeepAlive Req
KeepAlive Req
KeepAlive Req
![Page 27: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/27.jpg)
Starman, Starlet’sPreforking model requires1 connection per 1 process
By defaultStarman: 5 procs Starlet: 10 procs
![Page 28: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/28.jpg)
Monoceros adoptsPreforking model,
But C10K ready
![Page 29: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/29.jpg)
WorkerProcess
WorkerProcess
WorkerProcess
WorkerProcess
ManagerProcess
SOCK
Client
GET / HTTP/1.1Host: example.com
200 OKContent-Type: text/html
![Page 30: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/30.jpg)
WorkerProcess
WorkerProcess
WorkerProcess
WorkerProcess
ManagerProcess
SOCK
Client
GET / HTTP/1.1Host: example.com
200 OKContent-Type: text/html
![Page 31: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/31.jpg)
WorkerProcess
WorkerProcess
WorkerProcess
WorkerProcess
ManagerProcess
SOCK
Client
GET / HTTP/1.1Host: example.com
200 OKContent-Type: text/html
GET / HTTP/1.1Host: example.com
Event Driven
![Page 32: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/32.jpg)
WorkerProcess
WorkerProcess
WorkerProcess
WorkerProcess
ManagerProcess
SOCK
Client
GET / HTTP/1.1Host: example.com
200 OKContent-Type: text/html
GET / HTTP/1.1Host: example.com
200 OKContent-Type: text/html
Event Driven
![Page 33: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/33.jpg)
Monoceros Workersthat inherits “Starlet”
not C10K ready
![Page 34: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/34.jpg)
Event DrivenManager Process
C10K readybuilt with AnyEvent
![Page 35: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/35.jpg)
KeepAlive Benchmarklike a Browser
1) connect2) do requests certain number
3) leave alone a socket4) timeout and close
![Page 36: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/36.jpg)
250 conn / 200 reqs
Starlet Monoceros
Total time (sec) 54.51 8.74
Failed reqs 971 0
![Page 37: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/37.jpg)
Plack/PSGI Basics
![Page 38: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/38.jpg)
PSGI = speci"cationPlack = implementation
![Page 39: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/39.jpg)
PSGI Interface
my $app = sub { my $env = shift; ... return [200, [‘Content-Type’ => ‘text/html’], [‘Hello World’] ];};
![Page 40: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/40.jpg)
PSGI environment hash
* CGI keys REQUEST_METHOD,SCRIPT_NAME, PATH_INFO,REQUEST_URI, QUERY_STRING,SERVER_PROTOCOL,HTTP_*
* PSGI-specific keys psgi.version, psgi.url_scheme, psgi.input, psgi.errors, psgi.multiprocess, psgi.streaming psgi.nonblocking
$env->{...}
![Page 41: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/41.jpg)
PSGI Response (1) ArrayRef
[200, #status code [ ‘Content-Type’ => ‘text/html’, ‘Content-Length => 10 ], [ ‘Hello’, ‘World’ ]];
![Page 42: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/42.jpg)
PSGI Response (1’) arrayref+IO::Handle
open my $fh, ‘<’, ‘/path/icon.jpg’;
[200, [ ‘Content-Type’ => ‘image/jpeg’, ‘Content-Length => 123456789 ], $fh];
![Page 43: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/43.jpg)
PSGI Response (2)Delayed and Streamingsub { my $env = shift; return sub { my $responder = shift; ... $responder->([ 200, $headers, [$body] ]); }};
![Page 44: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/44.jpg)
PSGI Response (2’)Delayed and Streamingreturn sub { my $responder = shift; my $writer = $responder->([200, $headers]); wait_for_events(sub { my $new_event = shift; if ($new_event) { $writer->write($new_event->as_json . "\n"); } else { $writer->close; } });};
![Page 45: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/45.jpg)
Role of “PSGI Server”
![Page 46: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/46.jpg)
PSGI Server“A PSGI Server is a Perl program
providing an environment for a PSGI application to run in”
![Page 47: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/47.jpg)
PSGIServer
App$env
$res
Apache
Nginx
Apache
ProxyBrowser
CGI
mod_perl
FCGI
HTTP
Perl direct
![Page 48: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/48.jpg)
PSGI Serveris called
“Plack Handler”
![Page 49: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/49.jpg)
Plack HandlerAdaptor interface Plack and PSGI Server.
Make PSGI Server to runwith “plackup”
![Page 50: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/50.jpg)
e.g. Starman
Starman::Server= PSGI Server
Plack::Handler::Starman= Plack Handler
![Page 51: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/51.jpg)
Make
PSGI/PlackServer
a High Performance
![Page 52: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/52.jpg)
Tiny StandalonePSGI Web Server
![Page 53: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/53.jpg)
my $null_io = do { open my $io, "<", \""; $io };
my $app = sub { my $env = shift return [200,['Content-Type'=>'text/html'],['Hello','World',"\n"]];};
my $listen = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 5000, ReuseAddr => 1,);
while ( my $conn = $listen->accept ) { my $env = { SERVER_PORT => '5000', SERVER_NAME => 'localhost', SCRIPT_NAME => '', REMOTE_ADDR => $conn->peerhost, 'psgi.version' => [ 1, 1 ], 'psgi.errors' => *STDERR, 'psgi.url_scheme' => 'http', 'psgi.run_once' => Plack::Util::FALSE, 'psgi.multithread' => Plack::Util::FALSE, 'psgi.multiprocess' => Plack::Util::FALSE, 'psgi.streaming' => Plack::Util::FALSE, 'psgi.nonblocking' => Plack::Util::FALSE, 'psgi.input' => $null_io, }; $conn->sysread( my $buf, 4096); my $reqlen = Plack::HTTPParser::parse_http_request($buf, $env);
my $res = Plack::Util::run_app $app, $env;
my @lines = ("HTTP/1.1 $res->[0] @{[ status_message($res->[0]) ]}\015\012"); for (my $i = 0; $i < @{$res->[1]}; $i += 2) { next if $res->[1][$i] eq 'Connection'; push @lines, "$res->[1][$i]: $res->[1][$i + 1]\015\012"; } push @lines, "Connection: close\015\12\015\12";
$conn->syswrite(join "",@lines); Plack::Util::foreach($res->[2], sub { $conn->syswrite(shift); }); $conn->close;}
60 lines
![Page 54: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/54.jpg)
Listen and Accept
![Page 55: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/55.jpg)
my $listen = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 5000, ReuseAddr => 1,);
while ( my $conn = $listen->accept ) { ...}
![Page 56: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/56.jpg)
Read a request
![Page 57: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/57.jpg)
use Plack::HTTPParser qw/parse_http_request/;my $null_io = do { open my $io, "<", \""; $io };
while ( my $conn = $listen->accept ) {
my $env = { SERVER_PORT => '5000', SERVER_NAME => 'localhost', SCRIPT_NAME => '', REMOTE_ADDR => $conn->peerhost, 'psgi.version' => [ 1, 1 ], 'psgi.errors' => *STDERR, 'psgi.url_scheme' => 'http', 'psgi.multiprocess' => Plack::Util::FALSE, 'psgi.streaming' => Plack::Util::FALSE, 'psgi.nonblocking' => Plack::Util::FALSE, 'psgi.input' => $null_io, };
$conn->sysread(my $buf, 4096); my $reqlen = parse_http_request($buf, $env);
![Page 58: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/58.jpg)
Run App
![Page 59: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/59.jpg)
my $res = $app->($env);
or
my $res = Plack::Util::run_app $app, $env;
![Page 60: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/60.jpg)
Write a response
![Page 61: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/61.jpg)
use HTTP::Status qw/status_message/;
my $res = ..
my @lines = ("HTTP/1.1 $res->[0] \ @{[ status_message($res->[0]) ]}\015\012");
for (my $i = 0; $i < @{$res->[1]}; $i += 2) { next if $res->[1][$i] eq 'Connection'; push @lines, "$res->[1][$i]: $res->[1][$i + 1]\015\012";}push @lines, "Connection: close\015\12\015\12";
$conn->syswrite(join "",@lines);
foreach my $buf ( @{$res->[2]} ) { $conn->syswrite($buf);});
$conn->close;
![Page 62: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/62.jpg)
This PSGI Serverhas some problem
* handle only one at once* no timeout
* may not fast
![Page 63: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/63.jpg)
Increase concurrency
![Page 64: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/64.jpg)
Multi ProcessIO Multiplexing
orBoth
![Page 65: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/65.jpg)
Preforking modelSimple, Scaling
![Page 66: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/66.jpg)
Manager
![Page 67: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/67.jpg)
Manager
bind
listen
![Page 68: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/68.jpg)
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Manager
bind
listen
fork fork fork fork
![Page 69: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/69.jpg)
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Manager
bind
listen
fork fork fork fork
Client Client ClientClient
![Page 70: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/70.jpg)
use Parallel::Prefork;
my $listen = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 5000, ReuseAddr => 1,);
my $pm = Parallel::Prefork->new({ max_workers => 5, trap_signals => { TERM => 'TERM', HUP => 'TERM', }});
while ( $pm->signal_received ne 'TERM') { $pm->start(sub{ while ( my $conn = $listen->accept ) { my $env = {..}
![Page 71: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/71.jpg)
NO Accept Serialization
![Page 72: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/72.jpg)
os/kernel
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Manager
bind
listen
Zzz.. Zzz.. Zzz.. Zzz..
![Page 73: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/73.jpg)
os/kernel
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Client
Manager
bind
listen
Zzz.. Zzz.. Zzz.. Zzz..
![Page 74: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/74.jpg)
os/kernel
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Client
Manager
bind
listen
Zzz.. Zzz.. Zzz.. Zzz..
![Page 75: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/75.jpg)
os/kernel
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Client
Manager
bind
listen
Thundering Herd突然の負荷
WakeUp WakeUp WakeUp WakeUP
![Page 76: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/76.jpg)
os/kernel
Worker
accept
Worker
accept
Worker
accept
Worker
accept
Client
Manager
bind
listen
Thundering Herd突然の負荷
WakeUp WakeUp WakeUp WakeUP
![Page 77: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/77.jpg)
Thundering Herdis an old story
![Page 78: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/78.jpg)
Worker
accept
Worker
accept
Worker WorkerManager
bind
listen accept accept
Client
Zzz.. Zzz.. Zzz..Zzz..
![Page 79: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/79.jpg)
Worker
accept
Worker
accept
Worker WorkerManager
bind
listen accept accept
Client
Zzz.. Zzz.. Zzz..Zzz..
![Page 80: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/80.jpg)
Worker
accept
Worker
accept
Worker WorkerManager
bind
listen accept accept
Client
modern os/kernel
Zzz.. Zzz.. Zzz..Zzz..
![Page 81: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/81.jpg)
Worker
accept
Worker
accept
Worker WorkerManager
bind
listen accept accept
Client
modern os/kernel
Zzz.. Zzz.. Zzz..Zzz..
![Page 82: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/82.jpg)
Worker
accept
Worker
accept
Worker WorkerManager
bind
listen accept accept
Client
modern os/kernel
Zzz.. Zzz..Zzz..WakeUp
![Page 83: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/83.jpg)
NO Accept Serialization(except for multiple interface)
![Page 84: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/84.jpg)
TCP_DEFER_ACCEPT
![Page 85: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/85.jpg)
Wake up a process when DATA arrived
not established
コネクションが完了したタイミングではなく、データが到着した段階でプロセスを起こします
![Page 86: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/86.jpg)
clientA
clientB
GET / HTTP/1.0Host: example.comConnection: keep-alive
SYNACK
SYN+ACK
SYNACK
SYN+ACK
GET / HTTP/1.0Host: example.comConnection: keep-alive
default defer_accept
Accept
RunApp
blockto
read
![Page 87: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/87.jpg)
RunApp
clientA
clientB
GET / HTTP/1.0Host: example.comConnection: keep-alive
SYNACK
SYN+ACK
SYNACK
SYN+ACK
GET / HTTP/1.0Host: example.comConnection: keep-alive
default defer_accept
Accept
RunApp
Accept
blockto
read
![Page 88: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/88.jpg)
RunApp
clientA
clientB
GET / HTTP/1.0Host: example.comConnection: keep-alive
SYNACK
SYN+ACK
SYNACK
SYN+ACK
GET / HTTP/1.0Host: example.comConnection: keep-alive
default defer_accept
Accept
RunApp
Accept
blockto
read
idle
![Page 89: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/89.jpg)
RunApp
clientA
clientB
GET / HTTP/1.0Host: example.comConnection: keep-alive
SYNACK
SYN+ACK
SYNACK
SYN+ACK
GET / HTTP/1.0Host: example.comConnection: keep-alive
default defer_accept
Accept
RunApp
Accept
RunApp
Accept
RunApp
Accept
blockto
read
idle
![Page 90: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/90.jpg)
use Socket qw(IPPROTO_TCP);
my $listen = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 5000, ReuseAddr => 1,);
if ($^O eq 'linux') { setsockopt($listen, IPPROTO_TCP, 9, 1);}
![Page 91: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/91.jpg)
timeout to read header
![Page 92: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/92.jpg)
alarm
![Page 93: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/93.jpg)
my $READ_TIMEOUT = 5;
eval { local $SIG{ALRM} = sub { die "Timed out\n"; }; alarm( $READ_TIMEOUT ); $conn->sysread(my $buf, 4096);};alarm(0);
next if ( $@ && $@ =~ /Timed out/ );
my $reqlen = parse_http_request($buf, $env);
![Page 94: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/94.jpg)
nonblocking + select
![Page 95: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/95.jpg)
use IO::Select;my $READ_TIMEOUT = 5;
while( my $conn = $listen->accept ) {
$conn->blocking(0);
my $select = IO::Select->new($conn); my @ready = $select->can_read($READ_TIMEOUT); next unless @ready;
$conn->sysread($buf, 4096);
my $reqlen = parse_http_request($buf, $env);
![Page 96: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/96.jpg)
alarmvs.
nonblocking + select
![Page 97: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/97.jpg)
Fewer syscalls is good
![Page 98: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/98.jpg)
Hardwares
User Application
OS/Kernel
system callslisten,fork, accept, read, write, select, alarm
Worker Worker Worker Worker Worker
![Page 99: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/99.jpg)
alarm
![Page 100: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/100.jpg)
rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0rt_sigaction(SIGALRM, {0x47e5b0, [], SA_RESTORER, 0x7ff7d6e0cba0}, {SIG_DFL, [], SA_RESTORER, 0x7ff7d6e0cba0}, 8) = 0rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0alarm(5) = 0read(7, "GET / HTTP/1.1\r\nUser-Agent: curl"..., 65536) = 155rt_sigprocmask(SIG_BLOCK, [ALRM], [], 8) = 0rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER, 0x7ff7d6e0cba0}, {0x47e5b0, [], SA_RESTORER, 0x7ff7d6e0cba0}, 8) = 0rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0alarm(0) = 5 9 syscalls
![Page 101: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/101.jpg)
non-blocking + select
![Page 102: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/102.jpg)
fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0select(8, [5], NULL, [5], {300, 0}) = 1 (in [5], left {299, 999897})read(5, "GET / HTTP/1.1\r\nUser-Agent: curl"..., 131072) = 155
4 syscalls
![Page 103: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/103.jpg)
Parse a request with “C”
![Page 104: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/104.jpg)
$ cpanm HTTP::Parser::XS
Plack::HTTPParser uses H::P::XS if installed
![Page 105: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/105.jpg)
TCP_NODELAY
![Page 106: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/106.jpg)
When data was writtenTCP packets does not
immediately send
“TCP uses Nagle's algorithm to collect small packets
for send all at once by default”
![Page 107: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/107.jpg)
write(“foo”)
write(“bar”)
os/kernel networkinterfaceApplication
buffering
“foobar”
![Page 108: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/108.jpg)
write(“foo”)
write(“bar”)
os/kernel networkinterfaceApplication
“foo”
TCP_NODELAY
“bar”
![Page 109: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/109.jpg)
Take care of excessive fragmentation of TCP
packets
![Page 110: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/110.jpg)
Write in oncejoin content in Server
![Page 111: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/111.jpg)
my @lines = ("HTTP/1.1 $res->[0] @{[ status_message($res->[0]) ]}\015\012");
for (my $i = 0; $i < @{$res->[1]}; $i += 2) { next if $res->[1][$i] eq 'Connection'; push @lines, "$res->[1][$i]: $res->[1][$i + 1]\015\012";}push @lines, "Connection: close\015\12\015\12";
$conn->syswrite(join "",@lines, @{$res->[2]});
![Page 112: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/112.jpg)
accept4, writev
![Page 113: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/113.jpg)
Choose PSGI/Plack
Server
![Page 114: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/114.jpg)
CPAN has manyPSGI Server &
Plack::Hanlder:**
![Page 115: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/115.jpg)
Standalone(HTTP::Server::PSGI)
Default server for plackupSingle process Web Server
For development
![Page 116: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/116.jpg)
Starman
Preforking Web ServerHTTP/1.1, HTTPS,
Multiple interfaces, unix-domain socket,
hot deploy using Server::Starter
![Page 117: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/117.jpg)
Starlet
Preforking Web ServerHTTP/1.1(0.20~)
hot deploy using Server::StarterSimple and Fast
![Page 118: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/118.jpg)
Monoceros
C10K Ready Preforking Web ServerHTTP/1.1
hot deploy using Server::Starter
![Page 119: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/119.jpg)
Twiggy
based on AnyEventnonblocking, streaming
Single Process
![Page 120: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/120.jpg)
Twiggy::Prefork
based on Twiggy and Parallel::Prefork
nonblocking, streamingMulti Process
hot deploy using Server::Starter
![Page 121: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/121.jpg)
Feersum
Web server based on EV/libevnonblocking, streaming
Single/Multi Process
![Page 122: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/122.jpg)
How to choosePSGI Server
![Page 123: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/123.jpg)
SingleProcess
MultiProcess
CPU Intensive -Starlet
StarmanMonoceros
RequiresEvent Driven
TwiggyFeersum
Twiggy::PreforkFeersumTy
pe o
f Web
App
licat
ion
![Page 124: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/124.jpg)
Finding Bottlenecks of Performance
![Page 125: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/125.jpg)
use Devel::NYTProf
![Page 126: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/126.jpg)
![Page 127: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/127.jpg)
Flame Graph is awesome
Pro"le nytprof.out.{PID}for preforking server
$ nytprofhtml -f nytprof.out.1210$ open nytprof/index.html
![Page 128: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/128.jpg)
use strace or dtrusstrace syscalls
![Page 129: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/129.jpg)
$ strace -tt -s 200 -p {pid} \ 2>&1 | tee /tmp/trace.txt
![Page 130: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/130.jpg)
Process 30929 attached - interrupt to quit16:13:46.826828 accept(4, {sa_family=AF_INET, sin_port=htons(43783), sin_addr=inet_addr("127.0.0.1")}, [16]) = 516:13:48.916233 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.916392 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.916493 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.916573 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.916661 fcntl(5, F_SETFD, FD_CLOEXEC) = 016:13:48.916873 fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)16:13:48.916959 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 016:13:48.917095 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 016:13:48.917362 read(5, "GET / HTTP/1.0\r\nHost: 127.0.0.1:5005\r\nUser-Agent: ApacheBench/2.3\r\nAccept: */*\r\n\r\n", 131072) = 8216:13:48.917613 brk(0x1e8e000) = 0x1e8e00016:13:48.917746 gettimeofday({1379402028, 917802}, NULL) = 016:13:48.917953 write(5, "HTTP/1.1 200 OK\r\nDate: Tue, 17 Sep 2013 07:13:48 GMT\r\nServer: Plack::Handler::Starlet\r\nContent-Type: html\r\nConnection: close\r\n\r\nhello", 133) = 13316:13:48.918187 close(5) = 016:13:48.918428 accept(4, {sa_family=AF_INET, sin_port=htons(43793), sin_addr=inet_addr("127.0.0.1")}, [16]) = 516:13:48.923736 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.923843 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.923924 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.924461 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.924600 fcntl(5, F_SETFD, FD_CLOEXEC) = 016:13:48.924762 fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)16:13:48.924853 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 016:13:48.924939 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 016:13:48.925162 read(5, "GET / HTTP/1.0\r\nHost: 127.0.0.1:5005\r\nUser-Agent: ApacheBench/2.3\r\nAccept: */*\r\n\r\n", 131072) = 8216:13:48.925445 gettimeofday({1379402028, 925494}, NULL) = 016:13:48.925629 write(5, "HTTP/1.1 200 OK\r\nDate: Tue, 17 Sep 2013 07:13:48 GMT\r\nServer: Plack::Handler::Starlet\r\nContent-Type: html\r\nConnection: close\r\n\r\nhello", 133) = 13316:13:48.925854 close(5) = 016:13:48.926084 accept(4, {sa_family=AF_INET, sin_port=htons(43803), sin_addr=inet_addr("127.0.0.1")}, [16]) = 516:13:48.930480 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.930626 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.930744 ioctl(5, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff2fb61730) = -1 EINVAL (Invalid argument)16:13:48.930838 lseek(5, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)16:13:48.930915 fcntl(5, F_SETFD, FD_CLOEXEC) = 016:13:48.931070 fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)16:13:48.931170 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 016:13:48.931383 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 016:13:48.931536 read(5, "GET / HTTP/1.0\r\nHost: 127.0.0.1:5005\r\nUser-Agent: ApacheBench/2.3\r\nAccept: */*\r\n\r\n", 131072) = 8216:13:48.931748 gettimeofday({1379402028, 931791}, NULL) = 016:13:48.931869 write(5, "HTTP/1.1 200 OK\r\nDate: Tue, 17 Sep 2013 07:13:48 GMT\r\nServer: Plack::Handler::Starlet\r\nContent-Type: html\r\nConnection: close\r\n\r\nhello", 133) = 13316:13:48.932078 close(5) = 016:13:48.932256 accept(4, {sa_family=AF_INET, sin_port=htons(43813), sin_addr=inet_addr("127.0.0.1")}, [16]) = 5
![Page 131: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/131.jpg)
in conclusion
![Page 132: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/132.jpg)
PSGI Server get Faster.
![Page 133: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/133.jpg)
PSGI/Plack RocksStable, Fast
Found problems?RT, GitHub Issue, PullReqs
IRC #perl @kazeburo
![Page 134: How to build a High Performance PSGI/Plack Server](https://reader033.vdocuments.mx/reader033/viewer/2022051107/540ddff38d7f72927e8b4a4a/html5/thumbnails/134.jpg)
#"n. Thank you!