这是一个linux入门的小项目,让tcp服务器同时创建100w个长连接,主要目的是为了了解网络编程中的一些代码和相关设置。本文将总结整个学习过程的知识点。
学习到的处理连接的两种方式:一请求一线程和io多路复用epoll
一请求一线程
和字面意思一样,每当出现一个新的请求,就创建一个与之对应的线程处理这一连接。但是这样的开销太大了,通常情况下 Linux 线程的栈大小通常为 8MB,请求过多时大量的线程很容易导致内存不足。除此之外还有线程切换的开销等原因。不推荐用这一方法处理请求。
epoll
建立连接时出现的问题
Connection refused
每一个连接在服务器端都相当于一个socket,也可以说是一个io或者fd。
linux文件系统默认的每个进程fd的个数是1024,32位系统1024,64位系统65535。服务器端的fd数到上限了,分配不了新的fd,就出现了连接被拒绝的错误。
可以通过命令ulimit -a查看,通过ulimit -n xxx临时修改(需要先执行sudo su获取root权限),如:ulimit -n 1048576。系统重启后复原。
永久修改需要修改/etc/security/limits.conf文件,sudo vim /etc/security/limits.conf,在文件末尾# End of file前添加
* hard nofile 1048576
* soft nofile 1048576
*代表针对所有用户,nofile 是代表最大文件打开数。
Too many open files (in system)
原因fd的个数超过了是file-max的值,file-max和nofile不一样。file-max是所有进程最大的文件数,nofile是单个用户或进程能够打开的文件描述符数量。
修改file-max的值:sudo vim /etc/sysctl.conf 打开sysctl.conf,文件末尾添加fs.file-max=1048576
Cannot assign requested address
一个socket对应一个五元组(远程ip,远程端口,本地ip,本地端口,协议)如果服务器只开一个端口,那客户端的端口号很容易就耗尽了,无法分配新的端口,就出现了这个错误。解决方法:增加服务器端监听的端口数。
Connection time out
连接超时,但这里的原因其实是连接数超过net.netfilter.nf_conntrack_max,系统无法为新的连接创建连接跟踪条目。nf_conntrack_max是一个Linux的内核参数。修改内核参数都要在sysctl.conf中修改。
sudo vim /etc/sysctl.conf 打开sysctl.conf,文件末尾添加net.nf_conntrack_max=1048576。保存退出后执行sudo sysctl -p使参数生效。
如果此时报错nf_conntrack_max: No such file or directory,需要添加一个包sudo modprobe nf_conntrack
服务器内存不足
同样在/etc/sysctl.conf中修改tcp_mem, tcp_wmem, tcp_rmem
详解TCP中的tcp_mem、tcp_rmem、tcp_wmem定义及计算方式
net.ipv4.tcp_mem=252144 524288 786432
net.ipv4.tcp_wmem=1024 1024 2048
net.ipv4.tcp_rmem=1024 1024 2048
但是我改了之后还是内存不够,然后把虚拟机的内存改到了8g(