2

嗨,我建立了一个非常简单的 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;
4

1 回答 1

5

您可能会发现您遇到了“每个进程的文件描述符”限制。默认情况下为 1024。

$ ulimit -n
1024

如果您想处理 10,000 个并发连接,那么显然每个连接至少需要一个文件描述符。考虑到一些额外的进程和一些额外的空间用于陈旧的,您可能希望将其设置为大约 11k。

只有 root 可以增加 FD 限制:

$ sudo -s
Password:
# ulimit -n 11000
# ulimit -n
11000

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

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

$ cpan IO::Async::Loop::Epoll
$ cpan IO::Async::Loop::linux
于 2014-04-20T12:55:14.413 回答