每当我打开一个套接字通道时。如果客户端接受,则在内部创建 1 个文件描述符,因此我可以在 Linux 中创建最多 1024 个客户端。
但是我想在不增加 Linux 中文件描述符限制的情况下创建更多客户端(ulimit -n 20000) 那么如何在 Java 中创建更多套接字?
6 回答
如果您的会话限制为 1024 个文件描述符,那么您不能使用比单个 JVM 更多的文件描述符。
但是由于 ulimit 是每个进程的限制,您可能可以通过启动更多 JVM 来绕过它(即,要获得 2048 个连接,请启动两个 JVM,每个使用 1024)。
如果您使用的是 UDP,您可以自己在单个本地套接字上进行多路复用吗?您将能够通过源地址和端口分隔传入的数据包。
如果是 TCP,那么你就不走运了,关闭每个套接字后的TIME_WAIT时间段会使事情变得更糟。
限制 RLIMIT_NOFILE 由操作系统强制执行,并限制进程可以创建的最高 fd。一个 fd 用于打开的每个文件、管道和套接字。
有硬限制和软限制。任何进程(如您的 shell 或 jvm)都可以更改软值,但只有特权进程(如 root 用户运行的 shell)可以更改硬值。
a) 如果不允许您更改机器上的限制,请找可以更改的人。
b) 如果您由于某种原因懒得输入 ulimit,我想您可以使用 JNA 调用底层系统调用:man setrlimit(2)。(.exec() 不会这样做,因为它是内置命令)
另请参阅使用 Ulimit
为什么不能增加 ulimit ?这似乎是一种人为的限制。java代码(afaik)无法让您访问系统以重置ulimit - 它需要在进程开始之前设置 - 在启动脚本或类似的东西中。
JBoss 启动脚本在启动 Jboss 之前执行“ulimit -n $MAX_FD”...
伦
我们最近提高了 ulimit,因为我们的 java 进程抛出了很多“打开的文件太多”异常。
现在是 65536,我们没有遇到任何问题。
如果你真的想处理大量的连接,那么实现可扩展的最糟糕的方法是实现一个轻量级的数据服务器进程,它除了接受数据并将数据转发到父进程之外没有任何责任。
这样,当每个数据服务器饱和时,您只需生成一个新实例即可为自己提供另外 1024 个连接。如果需要,您甚至可以让它们存在于单独的机器上。