轻松支持5W并发的webserver

前面的文章说过,用libevent这类事件机制,写个server支持几万并发并不难。
libev是libevent的改进版,EV是libev的Perl封装模块,作者基于EV实现了一个很NB的事件框架,叫做AnyEvent。
用AnyEvent写个简单webserver,支持几万并发很轻松。

如下是示例代码:

use AnyEvent::HTTPD;

my $httpd = AnyEvent::HTTPD->new (port => 9090);

$httpd->reg_cb (
   ‘/’ => sub {
      my ($httpd, $req) = @_;

      $req->respond ({ content => [‘text/html’,
         “<html><body><h1>Hello World!</h1>”
         . “<a href=\”/\”>test page by pyh</a>”
         . “</body></html>”
      ]});
   },
);

$httpd->run;

把上述代码存为httpd.pl,运行perl httpd.pl,一个webserver就产生了,侦听在9090端口。

为了支持更高并发,在web服务器上,Linux内核简单调整如下参数:

net.core.somaxconn = 1024                # 挂起请求最大数量
net.core.netdev_max_backlog = 3000       # 进入包最大设备队列
net.ipv4.tcp_max_syn_backlog = 81920     # syn队列长度
net.ipv4.tcp_wmem = 8192 436600 873200   # TCP写缓存
net.ipv4.tcp_rmem = 32768 436600 873200  # TCP读缓存
我们用ab做压力测试,由于ab默认最大支持2W并发,因此如下修改ab源代码:
(1)
        /* catch legitimate fatal apr_socket_recv errors */
        else if (status != APR_SUCCESS) {
            err_recv++;
            if (recverrok) {
                bad++;
                close_connection(c);
                if (verbosity >= 1) {
                    char buf[120];
                    fprintf(stderr,”%s: %s (%d)\n”, “apr_socket_recv”, apr_strerror(status, buf, sizeof buf), status);
                }
                return;
            } else {
                apr_err(“apr_socket_recv”, status);
                bad++;
                close_connection(c);
                return;
            }
        }
上述橙色标明的是新增加的部分。
(2)
#define MAX_CONCURRENCY 50000   //最大并发数,原来是20000,改为50000
改完后,重新编译ab。
用ab对webserver执行压力测试,共50000个请求,50000个并发:
./ab -n 50000 -c 50000 http://example.com:9090/
测试结果如下图。50000个请求全部成功,每秒请求1150个,服务器端压力几乎为0.
所以,事件驱动的网络服务,高并发说明不了什么问题。
此条目发表在Common分类目录,贴了, 标签。将固定链接加入收藏夹。