我从这篇文章中了解到: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)时会出错。错误消息为Connection timed out
。
问题似乎不是文件描述符限制,因为我仍然可以在客户端计算机中打开/读取/写入文件。但任何与任何远程服务器的连接都会超时。
问题不在服务器端,因为服务器可以接受来自不同客户端计算机的更多连接。
看起来有某种设置而不是限制传出连接数的打开文件数。有人可以帮忙吗?
答案 0 :(得分:4)
为了能够从客户端计算机打开超过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;
}