在CentOS上增加最大出站连接数

5
我从这篇文章中了解到:如何实现1200万个并发连接:MigratoryData是如何做到的,一个客户端可以通过多个IP建立超过64K的连接。
现在我有一台AWS ec2机器用于测试,它有10个IP。在/etc/sysctl.conf中的配置如下:
fs.nr_open = 2000000
fs.file-max = 2000000

而/etc/security/limits.d/def.conf中的配置为:

*       soft    nofile  2000000
*       hard    nofile  2000000

我启动了一个用C语言编写的进程,并从第一个IP地址创建了60000个连接。一切正常。
然后我启动了另一个进程,试图从第二个IP地址创建60000个连接,但当连接数量达到约7500时(总数:67500),就会出现错误,错误信息为“连接超时”。
问题似乎不是文件描述符限制,因为我仍然可以在客户端机器上打开/读取/写入文件。但是任何对远程服务器的外部连接都会超时。
问题不在服务器端,因为服务器可以接受来自不同客户端机器的更多连接。
看起来限制外部连接数量的是某种设置,而不是打开文件的数量。有人能帮忙吗?

你使用的是哪种EC2实例类型?我在t2.micro、t2.small和t2.medium上遇到了问题,一旦建立了51,300个出站TCP连接,我就无法再进行连接、ping或接收连接(除了本地主机)。这个问题在t2.large实例上不会发生,但我还没有在t2.large上尝试超过62,000个连接;我会尝试一下。我怀疑AWS正在丢弃数据包,但我希望这只是一个配置问题。 - bboe
在t2.large实例上,我们观察到能够建立82441个并发的出站连接,然后才会出现无法建立或接收新连接的情况。 - bboe
1个回答

5
为了能够从您的客户端机器打开超过65536个TCP套接字连接,您需要使用更多的IP地址。然后,对于每个TCP套接字连接,您应该告诉内核使用哪个IP地址和哪个临时端口。因此,在TCP客户端创建套接字并在连接到远程地址之前,TCP客户端应该显式地将可用于客户端机器上的本地IP地址之一绑定到套接字上。MigratoryData基准测试工具是用Java编写的,因此我无法为您提供我们用于在客户端上打开任意数量的TCP连接的确切代码。但是,这里有一个用C++编写的快速示例。假设您的TCP服务器侦听192.168.1.1:8800,并且假设192.168.1.10是您的客户端机器的一个IP地址,则可以使用以下内容从本地IP地址192.168.1.10和临时本地端口(比如12345)创建套接字连接到远程IP地址192.168.1.1和远程端口8800:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<sys/socket.h> 
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    int n, sockfd;
    char buffer[1024];
    struct sockaddr_in localaddr, remoteaddr;


    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    localaddr.sin_family = AF_INET;
    localaddr.sin_addr.s_addr = inet_addr("192.168.1.10");
    localaddr.sin_port = htons(12345); 
    bind(sockfd, (struct sockaddr *) &localaddr, sizeof(localaddr));

    remoteaddr.sin_family = AF_INET;
    remoteaddr.sin_addr.s_addr = inet_addr("192.168.1.1");
    remoteaddr.sin_port = htons(80);
    connect(sockfd, (struct sockaddr *) &remoteaddr, sizeof(remoteaddr));

    n = read(sockfd, buffer, 512);

    // ...

    close(sockfd);

    return 0;
}

这正是我所做的。因此,总出站连接数为67500,而不仅仅是65535。 我的问题是为什么连接数在约67500处停止,而不是65535。 - avhacker
3
在最近的C10M测试中,我们使用MigratoryData Benchsub工具打开了250万个TCP出站连接,步骤如下:使用RHEL 7操作系统;将TCP堆栈内存增加到3M页:sysctl -w net.ipv4.tcp_mem="764535 1019382 3058140";文件处理器和端口:echo 20000500 > /proc/sys/fs/nr_opensysctl -w fs.file-max=20000500ulimit -n 20000000sysctl -w net.ipv4.ip_local_port_range="500 65535";同时禁用了防火墙(firewalld和iptables都被禁用)。如果您的客户端仍然无法正常工作,请建议在AWS EC2之外进行测试,以查看问题是否仍然存在。 - Mihai Rotaru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接