サーバーに対してテストするスクリプトを作成しました (100K を超える同時 TCP ソケットが可能です)。65536 に達した後、クライアントは接続のセットアップの試行を停止しました。なぜだろう。
use AnyEvent;
use EV;
use AnyEvent::Handle;
use IO::Socket::UNIX;
use Time::HiRes qw( gettimeofday );
use Data::Dumper;
my $count = 0;
my @hds = ();
my $cv = AnyEvent->condvar;
my $ips = ["192.168.1.11", "192.168.1.12","192.168.1.13","192.168.1.14"];
my $i;
my $j = 0;
for ($i=0; $i<1000; $i++) {
kickoff();
}
$cv->recv;
sub kickoff {
my $hdl = new AnyEvent::Handle
connect => ["192.168.1.1", 80],
on_error => sub {
my ($hdl, $fatal, $msg) = @_;
print "error when count=$count, $!\n";
$hdl->destroy;
$cv->send;
},
on_connect => sub {
$count ++;
if ($count > 65000) {
print "$count\n";
} elsif (($count % 1000) == 0) {
print "$count\n";
}
if ($count >= 100000) { return; }
kickoff();
},
on_prepare => sub {
my $hdl = shift;
#print Dumper($hd); exit;
mybind($hdl->{fh}, $ips->[$j%4]);
$j ++;
},
on_read => ::handleData;
push @hds, $hdl;
}
sub getTS {
my ($seconds, $microseconds) = gettimeofday;
return $seconds + (0.0+ $microseconds)/1000000.0;
}
sub mybind {
my ($sock, $ip) = @_;
my $local_host=inet_aton($ip) or return undef;
my $local = sockaddr_in(0, $local_host);
bind($sock,$local) or print 'Couldn\'t bind to local\n';
}
記録のために、Ubuntu 14.04 (linux 3.19.0) でルートとして実行し、ulimit -a
100000 を示しています。
理由はありますか?
更新1
コメントに基づいていくつかの更新。みんなありがとう。
- 1 つの IP のみを使用すると、27000 の同時 TCP 接続に簡単に到達できます。ポート範囲 (ホストごと) は、4 つのホストで 100,000 の接続を許可する必要があります。
fs.nr_open = 1048576
net.ipv4.netfilter.ip_conntrack_max の構成はありますが、ありません- 最大数「65536」は多くのことを意味します: 1) ホスト上のポートの最大数 2) 2 バイトの短整数の数値の数。だから関連している可能性があります。どこで制限を再定義できるか、または再定義できるかどうか疑問に思います。
- 番号が 65536 に達すると、新しい接続の作成の試行が停止しました。