您好我构建了一个非常简单的HTTP服务器,并且只对POE模块进行压力测试。
以下是我测试它的方式:
for x in {1..10000}; do
curl xxxxx:12342 --retry-delay 5 --retry 3 -d randombytes$x
done
当我这样做时,我通过对等消息看到多个“连接重置”,因此对于这个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;
答案 0 :(得分:5)
您可能会发现每个进程都会出现"文件描述符"限制。默认情况下为1024。
$ ulimit -n
1024
如果要处理10,000个并发连接,那么显然每个连接至少需要一个文件描述符。考虑到这个过程的一些额外费用以及一些额外的过时空间,您可能希望将其设置为大约11k。
只有root可以增加FD限制:
$ sudo -s
Password:
# ulimit -n 11000
# ulimit -n
11000
此时您现在可以运行您的服务器了。 (不要忘记切换回所需的UID,以免以root用户身份运行。)
通过IO::Async
运行如此大量的连接时,您可能希望使用比默认的内置poll
或基于select
的循环更好的内容。例如,在Linux上,您可能希望安装epoll
循环以及linux
循环,以便自动加载。
$ cpan IO::Async::Loop::Epoll
$ cpan IO::Async::Loop::linux