epoll实现同时承载100w客户端的数量

概念

先表明,这里是让epoll能够同时承受100w的连接,不针对业务处理。

对于百万并发的业务处理,其前提条件就是要同时承受住100w的连接。

程序源码

  epoll的源码直接给出来

/*支持百万并发的 reactor1.其主要限制在于Linux系统的限制,需要修改一些参数测试: 3个标准1.wrk       --> qps 一秒钟能处理的请求量2.并发连接量 --> 3.iperf     --> 测试带宽(硬件能力)// gcc reactor.c -oreactor -mcmodel=medium -g
*/#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>#define PORT 2480
#define MAX_EVENTS 1024#define MAX_BUFFER_SIZE 1024// 事件结构 -- 封装 读写缓冲区,读写事件处理方法
typedef int (*RCALLBACK)(int fd);typedef struct _CONN_ITEM_{int fd;int rLen;int wLen;char readBuffer[MAX_BUFFER_SIZE];char writeBuffer[MAX_BUFFER_SIZE];// 函数指针 -- 这里我们根据 epoll返回的特性分为读事件和写事件RCALLBACK send_cb;RCALLBACK recv_cb;}CONN_ITEM, LPTIEM;CONN_ITEM connLists[1048576] = {0};
int epfd;// 读事件
int send_cb(int fd){int Len = connLists[fd].wLen;int count = send(fd, connLists[fd].readBuffer, Len, 0);struct epoll_event evnet;evnet.data.fd = fd;evnet.events = EPOLLIN;epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &evnet);}// 写事件
int recv_cb(int fd){char *buffer = connLists[fd].readBuffer;int rLen = connLists[fd].rLen;int count = recv(fd, buffer + rLen, MAX_BUFFER_SIZE - rLen, 0);if(0 == count){epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);close(fd);}else{connLists[fd].rLen += count;// 回写数据memcpy(connLists[fd].writeBuffer, connLists[fd].readBuffer, connLists[fd].rLen);connLists[fd].rLen -= 0;connLists[fd].wLen = connLists[fd].rLen;// 将事件修改为触发写事件struct epoll_event event;event.data.fd = fd;event.events = EPOLLOUT;               epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);}
}// 连接事件 - 属于读事件
int accept_cb(int fd){int ret = 0;struct sockaddr_in clienAddr;socklen_t len = sizeof(clienAddr);int connfd = accept(fd, (struct sockaddr*)&clienAddr, &len);if(connfd){// 将新的 fd加入到epoll中struct epoll_event event;event.data.fd = connfd;event.events = EPOLLIN;connLists[connfd].send_cb = send_cb;connLists[connfd].recv_cb = recv_cb;connLists[connfd].rLen = 0;connLists[connfd].wLen = 0;memset(connLists[connfd].readBuffer, 0, MAX_BUFFER_SIZE);memset(connLists[connfd].writeBuffer, 0, MAX_BUFFER_SIZE);ret = epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &event);if(-1 == ret){perror("epoll_ctl");}}}int main(){int ret = 0;int i = 0;// TCPint sockfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == sockfd){perror("socket");return -1;}// addrstruct sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);serverAddr.sin_port = htons(PORT);ret = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_in));if(-1 == ret){perror("bind");return -1;}// 这个地方的第二个参数,表示未连接的个数能容纳几个,防止syn泛洪listen(sockfd, 10);// 建立 epoll,参数以无意义(内核>=2.6.8) > 0epfd =  epoll_create(10);if(-1 == ret){perror("epoll_create");return -1;}// 将sockfd加入到 epoll中struct epoll_event event;event.data.fd = sockfd;event.events = EPOLLIN;           // 指定监控的事件connLists[sockfd].fd = sockfd;//connLists[sockfd].accept_cb = accept_cb;connLists[sockfd].recv_cb = accept_cb;connLists[sockfd].send_cb = send_cb;ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);if(-1 == ret){perror("epoll_ctl");return -1;}// 不断的监视消息 - 可能会触发多次struct epoll_event events[MAX_EVENTS];while(1){int ready = epoll_wait(epfd, events, MAX_EVENTS, -1);if(-1 == ret){perror("epoll_wait");return -1;}for(i = 0; i < ready; ++i){int fd = events[i].data.fd;if(events[i].events & EPOLLIN){// 读事件ret = connLists[fd].recv_cb(fd);}else if(events[i].events & EPOLLOUT){// 写事件ret = connLists[fd].send_cb(fd);}}}close(epfd);close(sockfd);return 0;
}

测试收发数据:

 测试程序

        逻辑,这里我们没有那么多IP进行测试,只能不断的建立连接,断开连接。在实际的应用过程中也是这样的,在后续的工作中,需要测试并发量的情况下,一下代码程序依旧适用。

        

正片开始

多试几次,发现每次都在一千左右崩溃掉了。

为什么会出现这种情况?

        其实不难理解,我们能够知道一个socket会对于一个fd(伪文件),对于一个进程而言,能够建立的连接数量是有限的,我们可以进行修改。

ulimit -n 1048576(一百万) --> 1024 *1024

修改完测试:

这里的情况是,在Linux中默认允许分配端口大概是2万多,我们改下配置文件。

客户端需要做更改,客户端的端口是随机分配的,到两万左右就嗝屁了。(这个根据内核版本决定)。

增加一行:

fs.file-max = 1048576 一个进程能打开的最哒的文件描述符的大小

server端直接崩了,出现这种情况大概率是内存不足的问题。换句话说,当协议盏暂用内存的比例到达一定比例的时候,进程会被操作系统强制终止。我们需要调整配置...

sudo modprobe ip_conntrack

调整完再测试下:

现在能跑到五十多万,显示连接被拒绝,说明服务端断掉了,我们继续调整配置。

接下来就是不断的调整这些数值...实在跑不上去,有可能是网络问题或者虚拟机内存问题,直接把虚拟机内存再加大。

再调整...mmp今天一定把他弄上去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/263444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物联网主机E6000:工业领域的数据融合与5G未来

一、物联网的崛起 在科技日新月异的今天&#xff0c;物联网已经成为了我们生活中不可或缺的一部分。从智能家居到工业自动化&#xff0c;物联网的应用已经深入到我们生活的各个角落。而在这个大背景下&#xff0c;物联网主机的出现&#xff0c;更是为我们的生活带来了前所未有的…

【数据结构】哈希表算法总结

知识概览&#xff08;哈希表&#xff09; 哈希表可以将一些值域较大的数映射到较小的空间内&#xff0c;通常用x mod 质数的方式进行映射。为什么用质数呢&#xff1f;这样的质数还要离2的整数幂尽量远。这可以从数学上证明&#xff0c;这样冲突最小。取余还是会出现冲突情况。…

Go语言基础知识学习(一)

Go基本数据类型 bool bool型值可以为true或者false,例子&#xff1a; var b bool true数值型 类型表示范围int8有符号8位整型-128 ~ 127int16有符号16位整型-32768 ~ 32767int32有符号32位整型-2147783648 ~ 2147483647int64有符号64位整型uint8无符号8位整型0 ~ 255uint16…

代码随想录二刷 |二叉树 | 二叉树的右视图

代码随想录二刷 &#xff5c;二叉树 &#xff5c; 二叉树的右视图 题目描述解题思路代码实现 题目描述 199.二叉树的右视图 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例…

【Docker】swarm stack部署多service应用

前面我们已经学习过了Docker Compose&#xff0c;它可以用来进行一个完整的应用程序相互依赖的多个容器的编排的&#xff0c;但是缺点是只能在单机模式使用&#xff0c;不能在分布式多机器上使用&#xff1b;前面我们也学习了Docker swarm&#xff0c;它可以将单个服务部署为多…

C //习题10.10 从第9题的“职工工资文件”中删除一个职工的数据,再存回原文件。

C程序设计 &#xff08;第四版&#xff09; 谭浩强 习题10.10 习题10.10 从第9题的“职工工资文件”中删除一个职工的数据&#xff0c;再存回原文件。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法&#xff1a;使用指针&#xff0c;函数…

客服工单系统排行榜:提升客户满意度和效率的关键工具

随着技术的进步和企业规模的扩大&#xff0c;客户服务成为了企业成功的关键。而客服工单系统作为一个重要的组成部分&#xff0c;在优化客户服务过程中起到了至关重要的作用。本篇文章为您提供了一份客服工单系统排行榜&#xff0c;帮助您选择适合您企业需求的系统。 “本文进…

探索开源游戏的乐趣与无限可能 | 开源专题 No.47

CleverRaven/Cataclysm-DDA Stars: 9.0k License: NOASSERTION Cataclysm&#xff1a;Dark Days Ahead 是一个回合制的生存游戏&#xff0c;设定在一个后启示录世界中。尽管有些人将其描述为 “僵尸游戏”&#xff0c;但 Cataclysm 远不止于此。在这个残酷、持久、程序生成的世…

【EI征稿中|SPIE出版】 第四届传感器与信息技术国际学术会议(ICSI 2024)

第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09; 2024 4th International Conference on Sensors and Information Technology&#xff08;ICSI 2024&#xff09; 第四届传感器与信息技术国际学术会议&#xff08;ICSI 2024&#xff09;将于2024年1月5…

我有才打造知识付费小程序

一站式线上线下活动管理 为用户提供“精彩城市生活和人脉资源”。 在线活动提供创业、互联网、科技、投资、金融、教育、亲子、生活、聚会交友、医疗、设计、分享会、脱口秀、音乐演出等多种活动类型, 为职场白领提升技能、拓展人脉、聚会交友的首选平台。 为主办方提供“一…

FL Studio20版本水果软件永久免费激活码

FL Studio21水果编曲软件汉化版是一款专业的音乐制作软件&#xff0c;被广泛地应用于电子音乐、hip-hop、流行乐等多种音乐类型的制作。该软件提供了丰富的音频编曲工具和音乐效果器&#xff0c;让用户可以轻松地创作出高品质的音乐作品。同时&#xff0c;这也是一款非常易于上…

Linux权限理解

文章目录 前言概述Linux下的权限Linux权限管理文件访问者的分类&#xff1a;属性&#xff1a;文件权限值表示方法&#xff1a; 文件类型&#xff1a; 权限的修改chmod对 text.txt 文件的权限进行修改法1&#xff1a;法2&#xff1a; chownchgrpumaskfile指令目录权限粘滞位 前言…