本帖最后由 laputa73 于 2018-03-07 13:40 编辑
顺便安利一个高性能的perl http sever.
一般的印象里面,脚本语言的web框架就是低效的代名词。
引入一波事件驱动以后,这个性能普遍有了突飞猛进。
当初做web服务框架选型的时候,一个小兄弟选中了这个
AnyEvent::HTTP::Server;
https://github.com/Mons/AnyEvent-HTTP-Server-II
作者的benchemark可以参考。
Benchmarks
Example app HTTP server on port 8080, which should reply with string "Good" All files are located under benchmaks/
AnyEvent::HTTP::Server-II (1 worker) finished in 1 sec, 295 millisec and 127 microsec, 7721 req/s, 912 kbyte/s AnyEvent::HTTP::Server-II ( 4 workers) finished in 0 sec, 552 millisec and 381 microsec, 18103 req/s, 2139 kbyte/s AnyEvent::HTTP::Server (previous) finished in 3 sec, 421 millisec and 143 microsec, 2922 req/s, 278 kbyte/s AnyEvent::HTTPD (v0.93t) finished in 18 sec, 622 millisec and 941 microsec, 536 req/s, 99 kbyte/s Twiggy (v0.1021) finished in 1 sec, 630 millisec and 908 microsec, 6131 req/s, 272 kbyte/s Starman (--workers 1) (v0.3006) finished in 2 sec, 469 millisec and 571 microsec, 4049 req/s, 511 kbyte/s Starman (--workers 4) (best for my 4 core) finished in 1 sec, 102 millisec and 631 microsec, 9069 req/s, 1161 kbyte/s Pyton Twisted (I'm not a python programmer, so code may be not efficient) finished in 4 sec, 122 millisec and 587 microsec, 2425 req/s, 355 kbyte/s Node.js finished in 1 sec, 766 millisec and 696 microsec, 5660 req/s, 790 kbyte/s Nginx location / { perl 'use nginx; sub { $_[0]->send_http_header(q{text/plain}); $_[0]->print(q{Good}); return OK; }'; } finished in 0 sec, 290 millisec and 380 microsec, 34437 req/s, 5515 kbyte/s Raw TCP/HTTP server (perl+ev with no logic or parsing) For source look into benchmarks/ev-raw.pl finished in 0 sec, 306 millisec and 259 microsec, 32652 req/s, 2678 kbyte/s
注意 ,这个只是个webserver,性能的主要瓶颈其实是在后面的业务代码。而且,这个server并不遵循psgi规范。 同样,这个也可以和coro整合 - #!/bin/env perl
- #AEHTTP+coro+AE::ping(ok)
- use Coro;
- use Coro::EV;
- use AnyEvent;
- use Coro::AnyEvent;
- use AnyEvent::Ping;
- use AnyEvent::HTTP::Server;
- use EV;
- sub pingr($){
- my ($ip) = @_;
- return if not defined $ip;
- my $ping = AnyEvent::Ping->new;
- #push @coro, async {
- $ping->ping($ip, 1, Coro::rouse_cb );
- my @result = Coro::rouse_wait;
- print "Result($ip): ", $result[0][0][0]," in ", $result[0][0][1], " seconds\n";
- #}
- }
- my $ipn=0;
- my $s = AnyEvent::HTTP::Server->new(
- host => '127.0.0.1',
- port => 5000,
- cb => sub {
- my $req = shift;
- #$ipn++; //放在这里是不安全的。事件处理不是协程,不是顺序的。
- #return sub { //这样不行
- return unblock_sub { #这样可以
- my ($is_last, $bodypart) = @_;
- #Coro::AnyEvent::sleep 1;
- $ipn++; //放在这里是协程安全的
- pingr("192.168.6.".$ipn);
- $req->reply(200, "<h1>Reply message:$ipn</h1>", headers => { 'content-type' => 'text/html' });
- }
- }
- );
- $s->listen;
- $s->accept;
- EV::loop();
复制代码
|