我从这篇文章中了解到:
Scaling to 12 Million Concurrent Connections: How MigratoryData Did It可以从具有多个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)时会出错.错误消息是连接超时.
问题似乎不是文件描述符限制,因为我仍然可以在客户端计算机中打开/读取/写入文件.但任何与任何远程服务器的连接都会超时.
问题不在服务器端,因为服务器可以接受来自不同客户端计算机的更多连接.
看起来有某种设置而不是限制传出连接数的打开文件数.有人可以帮忙吗?
解决方法
为了能够从客户端计算机打开超过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; }