Linux上最大套接字数

时间:2010-08-07 12:43:42

标签: sockets pthreads

似乎服务器限制在~32720个插座...... 我已经尝试了每个已知的变量来提高这个限制。 但服务器仍然限制在32720打开套接字,即使仍然有4Go的空闲内存和80%的空闲cpu ......

这是配置

~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63931
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 798621
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 2048
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63931
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

net.netfilter.nf_conntrack_max = 999999
net.ipv4.netfilter.ip_conntrack_max = 999999
net.nf_conntrack_max = 999999

有什么想法吗?

8 个答案:

答案 0 :(得分:5)

如果您正在处理openssl和线程,请检查/ proc / sys / vm / max_map_count并尝试提升它。

答案 1 :(得分:2)

你在说哪个服务器?可能是它有一个硬编码的最大值,或者遇到其他限制(最大线程/地址空间等)。

http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1需要进行一些调整以实现大量连接,但如果服务器应用程序以某种方式限制它,它就无济于事。

答案 2 :(得分:2)

在IPV4中,TCP层的目标端口为16位,源端口为16位。

请参阅http://en.wikipedia.org/wiki/Transmission_Control_Protocol

看到你的限制是32K,我希望你实际上看到了你可以做出的出站TCP连接的限制。您应该能够获得最多65K的套接字(这将是协议限制)。这是命名连接总数的限制。幸运的是,为传入连接绑定端口仅使用1.但是,如果您尝试测试来自同一台计算机的连接数,则只能有65K总传出连接(对于TCP)。要测试传入连接的数量,您需要多台计算机。

注意:您可以将socket(AF_INET,...)调用到可用的文件描述符数量,但是 如果不增加可用端口数,就无法绑定它们。要增加范围,请执行以下操作:

echo“1024 65535”>的/ proc / SYS /网/的IPv4 / ip_local_port_range (告诉它你现在有什么 - 默认是32768到61000)

也许是时候新的TCP协议允许32位用于源端口和目标端口?但是有多少应用确实需要超过6.5万个出站连接?

以下将允许在linux mint 16(64位)上的100,000个传入连接 (您必须以root身份运行它来设置限制)

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>

void ShowLimit()
{
   rlimit lim;
   int err=getrlimit(RLIMIT_NOFILE,&lim);
   printf("%1d limit: %1ld,%1ld\n",err,lim.rlim_cur,lim.rlim_max);
}

main()
{
   ShowLimit();

   rlimit lim;
   lim.rlim_cur=100000;
   lim.rlim_max=100000;
   int err=setrlimit(RLIMIT_NOFILE,&lim);
   printf("set returned %1d\n",err);

   ShowLimit();

   int sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   sockaddr_in maddr;
   maddr.sin_family=AF_INET;
   maddr.sin_port=htons(80);
   maddr.sin_addr.s_addr=INADDR_ANY;

   err=bind(sock,(sockaddr *) &maddr, sizeof(maddr));

   err=listen(sock,1024);

   int sockets=0;
   while(true)
   {
      sockaddr_in raddr;
      socklen_t rlen=sizeof(raddr);
      err=accept(sock,(sockaddr *) &raddr,&rlen);
      if(err>=0)
      {
        ++sockets;
        printf("%1d sockets accepted\n",sockets);
      }
   }
}

答案 3 :(得分:1)

如果您正在考虑一个您认为需要打开数千个套接字的应用程序,那么您肯定希望阅读The C10k Problem。该页面讨论了在将客户端连接数量扩展到单个服务器时将面临的许多问题。

答案 4 :(得分:1)

使用检查运行过程的实际限制。

cat /proc/{pid}/limits

nofiles的最大值由内核确定,以下以root为单位将最大值增加到100,000个“文件”,即100k CC

echo 100000 > /proc/sys/fs/file-max

使其永久编辑/etc/sysctl.conf

fs.file-max = 100000

然后您需要服务器要求更多打开的文件,这在每台服务器上是不同的。例如,在nginx中,您可以设置

worker_rlimit_nofile 100000;

重新启动nginx并检查/ proc / {pid} / limits

要对此进行测试,您的客户端需要100,000个套接字,测试中每个IP地址的TCP端口数量是有限的。

将本地端口范围增加到最大...

echo "1024 65535" > /proc/sys/net/ipv4/ip_local_port_range

这为您提供了~64000个可以测试的端口。

如果这还不够,则需要更多IP地址。在localhost上测试时,您可以将源/客户端绑定到127.0.0.1 / localhost以外的IP。

例如,您可以将测试客户端绑定到从127.0.0.1到127.0.0.5中随机选择的IP

使用apache-bench,你可以设置

-B 127.0.0.x

Nodejs套接字将使用

localAddress

/etc/security/limits.conf配置PAM:它通常与服务器无关。

如果服务器使用TCP代理请求,例如使用upstream或mod_proxy,则服务器受ip_local_port_range的限制。这很容易就是32,000的限制。

答案 5 :(得分:0)

在Gnu + Linux上,你写的最多。这个数字(可能)在网络标准中有所说明。我怀疑你真的需要这么多插座。您应该优化使用套接字的方式,而不是一直创建数十个。

答案 6 :(得分:0)

在net / socket.c中,fd在sock_alloc_fd()中分配,调用get_unused_fd()。

查看linux / fs / file.c,fd数量的唯一限制是sysctl_nr_open,仅限于

int sysctl_nr_open_max = 1024 * 1024; /* raised later */

/// later...
sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) &
                         -BITS_PER_LONG;

并且可以使用sysctl fs.nr_open来读取,默认情况下此处为1M。所以fd可能不是你的问题。

编辑您可能也检查了这一点,但是您是否愿意分享

的输出
#include <sys/time.h>
#include <sys/resource.h>
int main() {
    struct rlimit limit;
    getrlimit(RLIMIT_NOFILE,&limit);
    printf("cur: %d, max: %d\n",limit.rlim_cur,limit.rlim_max);
}
跟我们一起?

答案 7 :(得分:0)

通常有太多的实时连接是件坏事。但是,一切都取决于应用程序以及与客户端通信的模式。

我认为客户端必须永久异步连接时才有一种模式,这是分布式解决方案可行的唯一方式。

假设当前负载的内存/ CPU /网络没有瓶颈,请记住,保持空闲的开放连接是分布式应用程序消耗更少资源(例如,连接时间和整体/峰值内存)的唯一方法),整体操作系统网络性能可能高于我们所知道的最佳实践。

很好的问题,它需要一个解决方案。问题是没人能回答这个问题。我建议使用divide&amp;征服技术,当发现瓶颈时,回到我们身边。

请在测试平台上拆开你的应用程序,你会发现瓶颈。