12. 测试搭建百万并发项目

news2024/11/28 16:28:50

本文利用四台虚拟机,实现了百万并发的项目,并解决其中遇到的一些问题

一、百万并发项目

准备4个虚拟机,其中一个4G内存,2核CPU;另外三个2G内存,1核CPU。
在这里插入图片描述
在服务器中运行11节的代码,客户端中运行mul_port_client_epoll.c代码。

二、问题与解决

1、Connection refused ——出现服务器不允许链接的错误

这是因为在Linux系统中,每个进程都有一些打开的文件(open files),而文件系统默认每个进程默认最多可以打开fd(File Descriptor)=1024个文件描述符。可以通过命令ulimit -a进程查看
在这里插入图片描述
通过命令sudo vim /etc/security/limits.conf,可修改open files最大个数。在limits.conf文件末尾添加如下命令,指定了所有用户在系统中可以同时打开的最大文件数量为 1048576。

*       hard    nofile  1048576
*       soft    nofile  1048576

在这里插入图片描述
修改后输入命令sudo reboot,进行重启。

2、connect: Cannot assign requested address ;error: Cannot assign requested address

在计算机网络中,Socket(套接字)是应用程序与网络之间的接口。它提供了一种通信机制,使得运行在不同主机上的应用程序可以互相发送和接收数据。
一个 Socket 由 IP 地址、协议类型和端口号三部分组成。其中,IP 地址指定了目标主机的地址;协议类型指定了要使用的传输层协议,如 TCP 或 UDP;而端口号则表示应用程序所使用的特定服务或进程。
当一个 Socket 发送数据时,它将数据包添加到网络层协议中,并通过 IP 地址找到目标主机。一旦到达目标主机后,在传输层上根据端口号找到对应的应用程序,并将数据包交给该程序处理。类似地,在接收数据时,Socket 需要指定本地 IP 和端口号以便正确地处理来自其他主机发来的数据。
出现“无法分配请求的地址”的错误,是因为在目标主机IP、远程端口号、本机IP以及协议确定时,出现本机端口号被耗尽的情况。这种情况通常会发生在客户端同时请求大量数据或者建立大量连接时,但服务器没有足够的资源来处理这些请求。
解决办法是:一个服务器监听多个端口,修改代码放在后面,监听100个端口(原来是一个)。

3、connect: Connection timed out error ;error: Connection timed out error

fd的个数与fd的最大值有以下区别:

  • fd的个数指当前进程已经打开并正在使用的文件描述符数量。
  • fd的最大值指当前进程可以同时打开并使用的最大文件描述符数量。

可以通过命令cat \proc\sys\fs\file-max查看fd的个数(本例结果为1048576)
通过命令cat /proc/sys/net/netfilter/nf_conntrack_max查看fd的最大数(本例结果为65536)
因此需要修改客户端fd的最大数,通过命令sudo vim /etc/sysctl.conf,添加以下命令

fs.file-max=1048576
net.nf_conntrack_max=1048576

输入命令sudo sysctl -p应用新的配置

4、Cannot open /proc/meminfo: Too many open files in system

与问题3一样,修改服务器的file-max

5、sysctl: cannot stat /proc/sys/net/nf_conntrack_max: No such file or directory

输入命令sudo modprobe ip_conntrack

6、内存回收

复制会话,输入命令htop
在这里插入图片描述
业务中CPU和内存消耗最好不要超过80%。因此需要优化TCP协议栈,通过命令sudo vim /etc/sysctl.conf,添加以下命令

net.ipv4.tcp_mem = 252144 524288 786432
net.ipv4.tcp_wmem = 1024 1024 2048
net.ipv4.tcp_rmem = 1024 1024 2048

输入命令sudo sysctl -p应用新的配置。

这是Linux系统中的TCP参数设置,具体含义如下:

  • net.ipv4.tcp_mem: 这个参数定义了 TCP 协议栈所使用的内存总量。它由三个数字组成,分别表示:最小值、默认值和最大值(单位为页面大小)。在这个例子中,其值为 252144 524288 786432。
  • net.ipv4.tcp_wmem: 这个参数定义了发送缓冲区的大小。它由三个数字组成,分别表示:最小值、默认值和最大值(单位为字节)。在这个例子中,其值为 1024 1024 2048。
  • net.ipv4.tcp_rmem: 这个参数定义了接收缓冲区的大小。它由三个数字组成,分别表示:最小值、默认值和最大值(单位为字节)。在这个例子中,其值为 1024 1024 2048。
    说明:

以上这些参数都是 TCP/IP 协议栈所使用的参数。其中 tcp_mem 参数控制着协议栈所使用的内存总量;tcp_wmem 和 tcp_rmem 参数则控制着发送缓冲区和接收缓冲区的大小。

三、代码


#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>


#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/epoll.h>


#define BUFFER_LENGTH       1024
#define EPOLL_SIZE          1024

#define MAX_PORT            100


int islistenfd(int fd,int *fds){
    int i=0;
    for (i=0;i<MAX_PORT;i++){
        if(fd==*(fds+i)) return fd;
    }
    return 0;
}



int main(int argc,char *argv[]){
    if (argc < 2) {
        printf("Param Error \n");
        return -1;
    }

    int port=atoi(argv[1]);//开始的端口
    int sockfds[MAX_PORT]={0};  //lisiten fd
     int epfd=epoll_create(1); 

    int i=0;
    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  ---->  8890 ----> ....
        addr.sin_addr.s_addr=INADDR_ANY;

        if (bind(sockfd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in))<0){
            perror("bind");
            return -2;
        }

        if(listen(sockfd,5)<0){
            perror("listen");
            return -3;
        }
        printf("tcp server listen on port : %d\n", port + i);

        struct epoll_event ev;  
        ev.events=EPOLLIN;  
        ev.data.fd = sockfd;
        epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);  

        sockfds[i]=sockfd;
    }
     
    struct epoll_event events[EPOLL_SIZE] = {0};    //创建一个结构体数组 events 用于存储 epoll_wait() 返回的事件列表。
    
    
    while (1){
        int nready=epoll_wait(epfd,events,EPOLL_SIZE,5); //
        if (nready == -1) continue; //表示5秒内,没有事件,继续监听

        int i=0;
        for (i=0;i<nready;i++){
            int sockfd=islistenfd(events[i].data.fd ,sockfds);
            if(sockfd){
                struct sockaddr_in client_addr;
                memset(&client_addr,0,sizeof(struct sockaddr_in));
                socklen_t client_len =sizeof(client_addr);

                int clientfd=accept(sockfd,(struct sockaddr *)&client_addr,&client_len);

                fcntl(clientfd,F_SETFL,O_NONBLOCK);

                int reuse=1;
                setsockopt(clientfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));

                struct epoll_event ev;
                ev.events=EPOLLIN | EPOLLET;  //EPOLLET 则表示将 I/O 事件设置为边缘触发模式。
                ev.data.fd=clientfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&ev);
            }
            else{
                //当某个客户端套接字上出现可读事件时(即该文件描述符在 events 中对应的元素有 EPOLLIN 标志),则调用 recv() 函数从该套接字中读取数据
                int clientfd=events[i].data.fd;
                
                char buffer[BUFFER_LENGTH]={0};
                int len=recv(clientfd,buffer,BUFFER_LENGTH,0);

                if (len < 0){//出现了异常情况或者非阻塞状态下没有更多数据可读
                    //关闭该套接字并将其从 epoll 实例中删除
                    close(clientfd);

                    struct epoll_event ev;
                    ev.events=EPOLLIN;  
                    ev.data.fd=clientfd;
                    epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev); //从 epoll 实例中删除 clientfd 对应的文件描述符,并且停止监听该套接字上的事件。
                }
                else if(len == 0) {//对方已经断开连接
                    //关闭该套接字并将其从 epoll 实例中删除
                    close(clientfd);

                    struct epoll_event ev;
                    ev.events=EPOLLIN;  
                    ev.data.fd=clientfd;
                    epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);
                }
                else{
                    printf("Recv: %s, %d byte(s), clientfd: %d\n", buffer, len, clientfd);
                }

            }
        }
    }



    return 0;
}



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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享一个500页面给大家

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>500页面</title><style>body,html {padding: 0;margin: 0;font-family: Quicksand, sans-s…

学生端程序(极域电子教室)破解方法

今天信息课上&#xff0c;由于老师的电脑控制&#xff08;极域电子教室&#xff09;导致某些同学无法摸鱼&#xff0c;于是他们就想让我破解&#xff0c;这道不难&#xff0c;我也就使用了三四周就破解出来了&#xff0c;今天就来和大家分享一下极域电子教室的破解方法 目录 …

(四)调整PID控制器参数的指南

一、控制系统设计快速入门和环境 首先确定一下控制任务。快速、精准地控制&#xff0c;必要的稳定性&#xff0c;时域&#xff08;上升时间、超调等&#xff09;&#xff0c;频域&#xff08;带宽、阻尼比&#xff09;然后明白控制系统特点。类积分器&#xff1f;开环稳定性、高…

深度学习实战项目(三)-行人检测重识别yolov5+reid(跑通+界面设计)

行人检测重识别yolov5reid&#xff08;跑通界面设计&#xff09; 参考源代码: github 权重文件&#xff1a; 根据github上面的网盘进行权重下载&#xff1a; 检测&#xff1a;将 ReID_resnet50_ibn_a.pth放在person_search/weights文件下&#xff0c;yolov5s.pt放person_sear…

pytest之fixture

fixture 0、文档1、局部前置处理2、全局前置处理3、全局前置处理 0、文档 pytest-fixture fixture 1、局部前置处理 pytest.fixture() 装饰器用于声明函数是一个fixture&#xff0c;该fixture的名字默认为函数名&#xff0c;也可以自己指定名称&#xff08;name取别名&#…

CBAM: Convolutional Block Attention Module论文总结和代码实现

论文&#xff1a;https://arxiv.org/pdf/1807.06521.pdf 中文版&#xff1a;CBAM: Convolutional Block Attention Module中文翻译 源码&#xff1a;https://github.com/Jongchan/attention-module 目录 一、论文的出发点 二、论文的主要工作 三、CBAM模块的具体实现 四…

【C++系列P5】‘类与对象‘-三部曲——[对象特殊成员](3/3)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01; 【 类与对象-三部曲】的大纲主要内容如下&#xff1a; 如标题所示&#xff0c;本章是【 类与对象-三部曲】三章中的第三章节——对象&成员章节&#xff0c;主要内容如下&#xff1a; 目录…

1723_PolySpace Bug Finder命令行执行探索

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

小兔鲜--项目总结3

目录 结算模块-地址切换交互实现 地址切换交互需求分析 打开弹框交互实现 地址激活交互实现 订单模块-生成订单功能实现 支付模块-实现支付功能 支付业务流程 支付模块-支付结果展示 支付模块-封装倒计时函数 理解需求 实现思路分析 会员中心-个人中心信息渲染 分页…

【JavaSE】Java基础语法(二十六):Collection集合

文章目录 1. 数组和集合的区别2. 集合类体系结构3. Collection 集合概述和使用【应用】4. Collection集合的遍历【应用】5. 增强for循环【应用】 1. 数组和集合的区别 相同点 都是容器,可以存储多个数据不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型…

【C++系列P4】‘类与对象‘-三部曲——[类](2/3)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01; 【 类与对象-三部曲】的大纲主要内容如下&#xff1a; 如标题所示&#xff0c;本章是【 类与对象-三部曲】三章中的第二章节——类章节&#xff0c;主要内容如下&#xff1a; 目录 一.类 1.…

CodeForces..学习读书吧.[简单].[条件判断].[找最小值]

题目描述&#xff1a; 题目解读&#xff1a; 给定一组数&#xff0c;分别是 “时间 内容”&#xff0c;内容分为00&#xff0c;01&#xff0c;10&#xff0c;11四种&#xff0c;求能够得到11的最小时间。 解题思路&#xff1a; 看似00&#xff0c;01&#xff0c;10&#xff0…

完整卸载office以及重装office 2021

完整卸载office以及重装 一.背景 之前很早安装的word最近发现打开&#xff0c;编辑等操作都很卡&#xff0c;而且占用的CPU很多&#xff0c;20%左右&#xff0c;而在网上搜索了一些结果无法解决问题后&#xff0c;决定卸载重装 二. 卸载的建议方法 直接参考官方链接从PC卸载…

华为OD机试之租车骑绿岛(Java源码)

租车骑绿岛 题目描述 部门组织绿岛骑行团建活动。租用公共双人自行车&#xff0c;每辆自行车最多坐两人&#xff0c;最大载重M。 给出部门每个人的体重&#xff0c;请问最多需要租用多少双人自行车。 输入描述 第一行两个数字m、n&#xff0c;分别代表自行车限重&#xff0c;部…

k8s 对外服务之 ingress|ingress的对外暴露方式|ingress http,https代理|ingress nginx的认证,nginx重写

k8s 对外服务之 ingress|ingress的对外暴露方式|ingress http&#xff0c;https代理|ingress nginx的认证&#xff0c;nginx重写 一 Ingress 简介二 Ingress 组成三 ingress 暴露服务的方式四 部署 nginx-ingress-controller4.1 修改 ClusterRole 资源配置4.2 DaemonSetHostNet…

STM32HAL库RS485-ModBus协议控制伺服电机

STM32HAL库RS485-ModBus协议控制伺服电机 一个月前&#xff0c;接手了一个学长的毕设小车&#xff0c;小车采用rs485通信的modbus协议驱动轮毂电机&#xff0c;与往常我学习的pwm控制电机方法大相径庭&#xff0c;在这里以这篇博客记录下该学习过程。 小车主要架构 电机型号 …

Python期末复习题库(上)——“Python”

小雅兰期末加油冲冲冲&#xff01;&#xff01;&#xff01; 1. (单选题) Python源程序的扩展名为&#xff08; A &#xff09; A. py B. c C. class D. ph 2. (单选题) 下列&#xff08; A &#xff09;符合可用于注释Python代码。 A. # B. */ C. // D. $ 3. (单选题)下列…

SMARTPHONE PLATFORM st解决方案

智能手机是最常用的计算设备。 它们展示了强大的硬件功能和复杂的操作系统&#xff0c;支持高级功能和人工智能应用、互联网和云访问、图像和视频采集、游戏以及语音通话和短信等核心电话功能。 要执行如此多样的应用&#xff0c;智能手机必须包含许多设备&#xff0c;包括大量…

一、电路分析的变量

点我回到主目录 ------------------------------------------------------------------------------------------------------------------------- 目录 1.电流 2.电压 3.功率 4.关联参考方向 5.电路吸收或发出功率的判断 1.电流 •电流 单位A&#xff08;安培…

vue基于Python的图书商城销售系统qo85w

系统以浏览器/服务器模式即B/S模板式为基础。本系统使用MySQL数据库,利用Python开发的操作系统&#xff1b;主要的功能有个人中心、用户管理、图书资讯管理、图书类型管理、图书信息管理、爬虫管理、留言板管理、系统管理、订单管理等组成。 本文首先介绍了现代化图书销售系统管…