嗯,IO :: Async甚至无法处理10k连接?

dai*_*isy 2 linux perl networking io-async

嗨,我构建了一个非常简单的HTTP服务器,只对POE模块进行压力测试.

这是我测试它的方式:

for x in {1..10000}; do
  curl xxxxx:12342 --retry-delay 5 --retry 3 -d randombytes$x 
done
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我通过对等消息看到多个"连接重置",因此对于这个10k连接,我总共丢失了大约1200个请求.

反正有没有提高它的表现?在同一台服务器上测试了nginx,在此期间没有更改内核参数,根本没有连接重置消息.

编辑

我已经增加了max fileno/per user max fileno,前者是fs.file-max = 3246455,而后者是10240

附加源代码:

use strict;
use warnings;
use feature 'say';

use Net::Async::HTTP::Server;
use IO::Async::Loop;

use HTTP::Request;
use HTTP::Response;
use Data::Dumper;

my $loop = IO::Async::Loop->new();

my $httpserver = Net::Async::HTTP::Server->new(
    on_request => sub {
        my ($self, $req) = @_;
        my ($code, $result) = (200, "It works\n");

        my $response = HTTP::Response->new ($code);
        $response->add_content ($result);
        $response->content_type ("application/json");
        $response->content_length (length $response->content);

        $req->respond($response);
    },
);

$loop->add( $httpserver );

$httpserver->listen(
    addr => { family => "inet", socktype => "stream", port => 8080 },
    on_listen_error => sub { die "Cannot listen - $_[-1]\n" },
);

say 'Listening normally on ', 8080;

$loop->run;
Run Code Online (Sandbox Code Playgroud)

Leo*_*erd 5

你可能会发现你正在提出"每个进程的文件描述符"限制.默认情况下为1024.

$ ulimit -n
1024
Run Code Online (Sandbox Code Playgroud)

如果要处理10,000个并发连接,那么显然每个连接至少需要一个文件描述符.考虑到一些额外的过程和一些额外的陈旧过时空间,你可能想要设置为约11k.

只有root才能增加FD限制:

$ sudo -s
Password:
# ulimit -n 11000
# ulimit -n
11000
Run Code Online (Sandbox Code Playgroud)

此时,您现在可以运行您的服务器了.(不要忘记切换回所需的UID,以免以root用户身份运行).

通过IO::Async你运行如此大量的连接时,你可能想要使用比默认的内置pollselect基于循环更好的东西.例如在Linux上你可能想要安装epoll循环,以及linux它将自动加载.

$ cpan IO::Async::Loop::Epoll
$ cpan IO::Async::Loop::linux
Run Code Online (Sandbox Code Playgroud)