当前位置:网站首页>TCP百万并发服务器优化调参
TCP百万并发服务器优化调参
2022-08-01 16:52:00 【qq_42120843】
C语言TCP服务器百万并发调参优化
文章目录
背景
结合之前完成的C语言TCP服务端程序,其能够接受的最大并发数较低,故我们希望进行一些编码上或者是系统参数上的改变来实现提高TCP服务器的最大并发数
注:这里说的最大并发数(或称最大并发量),**是指客户端的数量(**即通信socket的数量)
而不是每秒请求的数量qps,注意区别!
本实验最后的结果也并未达到百万并发,只接近80w,故本博客重点在于调优的参数和代码的修改有哪些。
实验准备
准备四台虚拟机 版本皆为 20.04
服务器:4g内存,双核
三台客户端:2g内存,单核
若想要修改Ubuntu静态IP地址可参考:https://blog.csdn.net/baidu_39332177/article/details/123131601
优化调参
出现Connection refused错误
描述
当建立1024个socket的clientfd之后,别的客户端再想连接就出现Connection refused错误
问题原因
通过ulimit -a
查看服务器端默认的open files
参数数量只有1024个
解决办法
修改open files
数量,方法如下
- 方法一:临时修改,输入
sudo ulimit -n 1048576
,但是重启后又恢复原来设置值 - 方法二:永久修改,输入
sudo vim /etc/security/limits.conf
然后在文件结尾位置添加相关设置
hard
指警告的设定,可以超过这个值,但是超过后有警告
soft
指严格的设定,不允许超过这个值
客户端连接服务器时候产生Too many open files错误
描述
原因和解决办法
由于我们只在服务器端修改了open files的数量,必须要在客户端也将open files设置为1048576
出现Cannot assign requested address错误
描述
原因分析
首先,问题是不能分配客户端地址还是服务器地址?sockfd和网络地址之间有什么关系?
根据socket可以找到一个五元组 socket–>(远程IP,远程端口,本机IP,本机端口,协议),socket和五元组是一对一关系,通过这个五元组可以通过recv
和send
函数来收发数据。
所以该问题原因就是五元组的组合被耗尽,服务器的本机IP以及远程IP和远程端口号已经确定,所以唯一能够利用的就是增添本机端口数量来增加socket的数量。
注意:本机端口数量最大只能有65535
解决办法
使用100个端口号与服务器地址和socket的绑定,得到100个监听的fd,并将其上epoll树,由epoll来监控事件到来,关键代码的修改如下:
int epfd = epoll_create(1); // 1.创建一个监视事件的管理员fd
int sockfds[MAX_PORT] = {
0}; // listen fd集合
int i = 0;
//开MAX_PORT个端口进行监听
for(i = 0;i < MAX_PORT; ++i)
{
//创建监听的文件描述符,相当于酒店门口迎宾的人员
//为客户提供服务由其他服务员来做
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));//清空结构体
addr.sin_family = AF_INET;
addr.sin_port = htons(port + i); //主机字节序转换为网络字节序 8888, 8889....8987
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
{
perror("bind");
return -2;
}
//利用sockfd进行监听
//第二个参数指定能处理的最大连接请求
if(listen(sockfd, 5) < 0)
{
perror("listen");
return -3;
}
printf("tcp server listen on port: %d\n", port + i);
struct epoll_event ev;
//有数据到来socketfd,表示可读了,则会触发EPOLLIN
//对端(客户端)读取了一些数据走,则表示可以往这个socketfd写了,则会触发EPOLLOUT
ev.events = EPOLLIN;
ev.data.fd = sockfd;
//EPOLL_CTL_ADD:在epoll的监视列表中添加一个文件描述符(即参数fd),指定监视的事件类型(参数event)
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
sockfds[i] = sockfd;
}
Connection timed out 错误
描述
这个问题在ubuntu20.04上不存在,但还是记录一下。
原因与解决方案
首先查看file-max
参数值是否不足100w
file-max : sets the maximum number of file-handles that the Linux kernel will allocate.
[email protected]:~$ cat /proc/sys/fs/file-max
9223372036854775807
已经大于100w,故接着检查nf_conntrack_max
(设置连接跟踪的最大值)
[email protected]:~$ sudo modprobe ip_conntrack #这句用来启动ip_conntrack,不加则下面语句失败
[email protected]:~$ cat /proc/sys/net/netfilter/nf_conntrack_max
262144
这里我们可以看出连接跟踪最大值只有262144,没有到100w,所以解决方法就是将该参数设置为100w之上
sudo vim /etc/sysctl.conf
将net.nf_conntrack_max = 1048576
添加进配置文件
然后输入下方语句生效配置
sudo sysctl -p
Cannot open /proc/meminfo:Too many open files in system file-max
遇到该问题说明file-max
不够大,在etc/sysctl.conf
修改参数即可
[email protected]:~$ sudo modprobe ip_conntrack #这句用来启动ip_conntrack,不加则下面语句失败
[email protected]:~$ sudo vim /etc/sysctl.conf
添加下面的语句
然后输入下面的语句生效配置
sudo sysctl -p
内存回收设置的调优
以下配置代码都是添加到etc/sysctl.conf
文件中,注意开始要加上sudo modprobe ip_conntrack
第一个参数:tcp协议栈内存
net.ipv4.tcp_mem = 252144 524288 786432
tcp_mem(3个INTEGER变量):low, pressure, high
low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。
pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。
high:允许所有tcp sockets用于排队缓冲数据报的页面量,当内存占用超过此值,系统拒绝分配socket,后台日志输出“TCP: too many of orphaned sockets”第二个参数:tcp发送缓冲区
net.ipv4.tcp_wmem = 1024 1024 2048
表示tcp连接(socket)的发送(write)缓存区的最小、默认、最大值,分别为1KB ,1KB,2KB
第三个参数:tcp接收缓冲区
net.ipv4_tcp_rmem = 1024, 1024, 2048
表示tcp连接(socket)的接受(recive)缓存区的最小、默认、最大值,分别为1KB ,1KB,2KB
这样设置之后,默认的1个socket的file descriptor大小为2KB(rmem + wmem),百万个fd就大概是2g内存。
杂项
- 最后测试的时候,我这个配置也只能最多到82万左右,不知道什么原因,也加大了客户端和服务端的内存
- 大量客户机断开连接宕机时候,处理器使用率会飙升
- 内存和CPU使用率最好维持在80%一下
注意
本实验主要目的是了解百万并发所需要的优化,故代码就不详加给出了。如果面试时候,如果别人问起这个服务器调优,就和面试官说清楚解决了哪几个问题,不要没有达到100w就唯唯诺诺,不敢回答。
边栏推荐
猜你喜欢
京东软件测试面试题,仅30题就已经拯救了50%的人
我的新书销量1万册了!
70后夫妻给苹果华为做“雨衣”,三年进账7.91亿
Ant discloses the open source layout of core basic software technology for the first time
软件测试谈薪技巧:同为测试人员,为什么有人5K,有人 20K?
My new book has sold 10,000 copies!
ROS2系列知识(5):【参数】如何管理?
阿里官方 Redis 开发规范
C语言:表达式求值详解
MySQL's maximum recommended number of rows is 2000w, is it reliable?
随机推荐
GridControl helper class for DevExpress
工业制造行业的低代码开发平台思维架构图
moxa串口服务器配置说明(moxa串口驱动)
【建议收藏】技术面必考题:多线程、多进程
关于2022年深圳市福田区支持高端服务业发展项目的申报通知
C#的路径帮助类
C # Excel helper classes
比对软件-blastN结果详解
泰国 好产品推荐!2022年最好的胶原蛋白评测有哪些? 喝出健康和美丽适合需要改善肌肤
暑气渐敛,8月让我们开源一夏!
深圳市商务局2022年度中央资金(跨境电子商务企业市场开拓扶持事项)申报指南
C#中关于DevExpress的常用操作和帮助类项目工程内容说明
Bugku-Misc-贝斯手
【R语言】对图片进行裁剪 图片批量裁剪
The site is not found after the website is filed. You have not bound this domain name or IP to the corresponding site! The configuration file does not take effect!
C#的DateTime帮助类
The anxiety of the post-90s was cured by the vegetable market
AntDB数据库亮相24届高速展,助力智慧高速创新应用
Vulnhub target drone: HARRYPOTTER_ NAGINI
Go unit tests