Linux实现tcp服务器的百万并发出现的问题总结

这是一个linux入门的小项目,让tcp服务器同时创建100w个长连接,主要目的是为了了解网络编程中的一些代码和相关设置。本文将总结整个学习过程的知识点。

学习到的处理连接的两种方式:一请求一线程和io多路复用epoll

一请求一线程

和字面意思一样,每当出现一个新的请求,就创建一个与之对应的线程处理这一连接。但是这样的开销太大了,通常情况下 Linux 线程的栈大小通常为 8MB,请求过多时大量的线程很容易导致内存不足。除此之外还有线程切换的开销等原因。不推荐用这一方法处理请求。

epoll

Linux下的I/O复用技术 — epoll如何使用

建立连接时出现的问题

Connection refused

每一个连接在服务器端都相当于一个socket,也可以说是一个io或者fd。

彻底弄懂 Linux 下的文件描述符(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

linux ulimit soft和hard的区别

*代表针对所有用户,nofile 是代表最大文件打开数。

Too many open files (in system)

fs-max、file-nr和nofile的关系

原因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(

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值