最近用到了Mina,发现在CentOS6.2 上,当接收到400个来自客户端的TCP连接的时候,新的TCP的连接能建立成功
但是新建立的TCP连接收到的数据,不能再抛给应用层,而一直堵在缓冲区,如下
使用命令:netstat -nat |grep 65534
因为TCP的三次握手是操作系统控制的,所以新的TCP连接能够建立成功。
为什么会这样呢?当找到了真正的原因,只能感叹,作为一个java 使用者,比起c 的使用者,真是苦逼
因为Mina使用的是selector,而在java里,实现的selector会为每一个新的连接,使用2个PIPE(管道)来发送数据
所以当我开辟了400个连接的时候,已经使用了800个管道,而管道的建立在Linux里会占用“文件描述符”
而默认的文件描述符是1024个,所以当有新的连接来到时,可能文件描述符就不够用了
可能你们要问,1024/2=512,应该是能建立512个socket才对啊?
可是事实上不是如此,因为程序本身使用了一些文件描述符和数据库的连接,
然而java 虚拟机也使用了一些PIPE来控制其它事情吧
所以通过lsof可以查看,你的进程到底使用了多少文件描述
lsof -p PID
最后,通过改变用户能够使用的最大文件描述符的个数,方法如下:
vi /etc/security/limits.conf
加上:
* soft nofile 65534
* hard nofile 65534
该问题就迎刃而解了
所以,当我跑3000个客户端的实时连接,也没有任何问题了