2.2.1服务器百万并发实现

这篇具有很好参考价值的文章主要介绍了2.2.1服务器百万并发实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Reactor模型的几个重要组件:Event事件、Reactor反应堆、Demultiplex事件分发器、Evanthandler事件处理器

接上节课,上节课中,我们使用了epoll实现了同时监听多个文件描述符,是对IO的管理,也提到了reactor是对事件的管理,那具体来说是怎样的呢?reactor是事件驱动模型,也就是EPOLLIN/EPOLLOUT,同时,我们应该维护一种结构,对于每个fd,都应该有这样一种记录该fd相关的结构。
2.2.1服务器百万并发实现
对于其中的fd小块,存储的都是该fd相关的内容,比如该fd的读写缓存区,对应的回调函数等等:
2.2.1服务器百万并发实现
结构可以用代码这样表示:

typedef int (*ZVCALLBACK)(int fd, int events, void *arg);

typedef struct zv_connect_s {
    int fd;

    ZVCALLBACK cb;

    char rbuffer[BUFFER_LENGTH];
    int rc;
    char wbuffer[BUFFER_LENGTH];
    int wc;

    int count;
} zv_connect_t;

typedef struct zv_connblock_s {
    zv_connect_t *block;
    struct zv_connblock_s *next;
} zv_connblock_t;

typedef struct zv_reactor_s {
    int epfd;
    zv_connblock_t *blockheader;

} zv_reactor_t;

这样,对于listenfd,我们设置它的accept_cb,对于clientfd,设置它的recv_cbsend_cb

具体来说,我们以fd为下标,唯一标识该fd相关的块,对于listenfd,通过listenfd设置相关的accept_cb回调:

int accept_cb(int fd, int events, void *arg)
{
   	...
    int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);
    if (clientfd < 0) {
        printf("accept errno: %d\n", errno);
        return -1;
    }

    zv_reactor_t *reactor = (zv_reactor_t*)arg;
    zv_connect_t *conn = &reactor->blockheader->block[clientfd];

    conn->fd = clientfd;
    conn->cb = recv_cb;
    ...
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = clientfd;
    epoll_ctl(reactor->epfd, EPOLL_CTL_ADD, clientfd, &ev);
}

reactor->blockheader->block[listenfd].fd = listenfd;
reactor->blockheader->block[listenfd].cb = accpet_cb;

接收和发送回调同理。
并且,当我们使用上节课提到的epoll将IO管理起来后,整体代码就会显得非常简洁,因为当有EPOLLIN/EPOLLOUT事件来临时,我们只需要根据fd找到对应的回调函数执行即可:

while (1) {//mainloop,  event driver

        int nready = epoll_wait(reactor.epfd, events, 1024, -1);
        if (nready < 0) continue;
        int i = 0; 
        for (i = 0; i < nready; i++) {
            int connfd = events[i].data.fd;
            zv_connect_t *conn = &reactor.blockheader->block[connfd];
            if (events[i].events & EPOLLIN) {
                conn->cb(connfd, events[i].events, &reactor);
            }
            if (events[i].events & EPOLLOUT) {
                conn->cb(connfd, events[i].events, &reactor);
            }
        }
    }

这便是reactor对事件管理的方式,这样一来,我们可以将网络与业务分离,业务人员只需要在回调函数中读写相应的buffer即可,无需关注网络细节!

再往后,为了提高处理能力,我们可以将clientfd相关的读写操作放到子线程去做,而主线程只负责appect等等,这就涉及到不同的网络编程模型,之后再谈。


1.并发:服务器同时承载的客户端数量
2.qps:每一秒处理的请求数量
3.最大时延:
4.新建(建链):每秒建立的链接数
5.吞吐量

ulimit -a查看每个进程可以打开的文件描述符个数
2.2.1服务器百万并发实现
可以看到这里open files最大是1024,有两种方式可以修改:
1.命令:ulimit -n 1048576(这是临时修改)
2.2.1服务器百万并发实现
2.修改文件/etc/security/limits.conf(注意中间是tab键)
2.2.1服务器百万并发实现

gaoyuelong@ubuntu:~/23040voice/06$ sudo sysctl -p
gaoyuelong@ubuntu:~/23040voice/06$ sudo modprobe nf_conntrack

(目前虚拟机网络没有调试好,导致网络通信有些问题,后续再写百万并发部分,先挖个坑)

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:https://ke.qq.com/course/417774?flowToken=1020253文章来源地址https://www.toymoban.com/news/detail-422084.html

到了这里,关于2.2.1服务器百万并发实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)Channel 模块的实现

    在这篇文章中虽然实现了能够和多客户端建立连接,并且同时和多个客户端进行通信。 基于多反应堆的高并发服务器【C/C++/Reactor】(上)-CSDN博客 https://blog.csdn.net/weixin_41987016/article/details/135141316?spm=1001.2014.3001.5501 但是有一个 问题(O_O)? : 这个程序它是单线程的。如果我们想

    2024年02月03日
    浏览(38)
  • 用反应器模式和epoll构建百万并发服务器

    此处的百万并发指的是可以建立至少100w个客户端连接,不考虑业务处理。 反应器模式下的epoll相比起普通的epoll不同在于:普通的epoll在获取到就绪状态的event结构体之后,先判断是什么类型的fd,再进行操作。而reactor先判断是什么类型的事件,再进行操作。本文从头用react

    2024年02月02日
    浏览(56)
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)完整代码

    Buffer.h Buffer.c Channel.h Channel.c ChannelMap.h ChannelMap.c Dispatcher.h EpollDispatcher.c  PollDispatcher.c SelectDispatcher.c EventLoop.h EventLoop.c HttpRequest.h HttpRequest.c   HttpResponse.h HttpResponse.c TcpConnection.h TcpConnection.c TcpServer.h TcpServer.c ThreadPool.h ThreadPool.c WorkerThread.h WorkerThread.c

    2024年01月20日
    浏览(45)
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(下)重构Channel类

    一、C语言 Channel.h Channel.c 二、C++ Channel.h Channel.cpp  

    2024年01月21日
    浏览(46)
  • 【网络进阶】服务器模型Reactor与Proactor

    在高并发编程和网络连接的消息处理中,通常可分为两个阶段:等待消息就绪和消息处理。当使用默认的阻塞套接字时(例如每个线程专门处理一个连接),这两个阶段往往是合并的。因此,处理套接字的线程需要等待消息就绪,这在高并发场景下导致线程频繁地休眠和唤醒

    2024年02月01日
    浏览(32)
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)EventLoop初始化和启动

    (一)详述 EventLoop  这个 Dispatcher 是一个事件分发模型,通过这个模型,就能够检测对应的文件描述符的事件的时候,可以使用 epoll/poll/select ,前面说过三选一。另外不管是哪一个底层的检测模型,它们都需要使用一个数据块,这个数据块就叫做 DispatcherData 。除此之外,还有另外一

    2024年01月23日
    浏览(52)
  • 使用select实现TCP并发服务器模型

    本期主要分享的是对于select的使用,使用select实现TCP并发服务器模型,由于之前所用到的技术知识只能够支撑我们进行单个访问,但是有了select之后呢,我们就能够实现多用户进行访问;这也是非常符合客观需求的; 这次呢我们重点来使用一下select; 用到的头文件如下: 我

    2024年02月08日
    浏览(34)
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpRequest模块 解析http请求协议

    一、HTTP响应报文格式 二、根据解析出的原始数据,对客户端的请求做出处理  processHttpRequest  1.解码字符串   解决浏览器无法访问带特殊字符的文件得到问题 2.判断文件扩展名,返回对应的 Content-Type(Mime-Type) 3.发送文件  sendFile 4.发送目录 三、解析http请求协议  parseHttpR

    2024年02月02日
    浏览(41)
  • 基于多反应堆的高并发服务器【C/C++/Reactor】(中)在TcpConnection 中接收并解析Http请求消息

    一、在TcpConnection 中多添加和http协议相关的request和response 二、给客户端回复数据(方法一) 1.在 Buffer.h 文件中添加 bufferSendData 函数:  2.在 TcpConnection.c 文件中添加 processWrite 函数: 3.修改 tcpConnectionInit 函数中调用的 channelInit函数 的写回调函数为 processWrite函数 三、给客户端

    2024年01月23日
    浏览(39)
  • 基于epoll实现Reactor服务器

    在我们调用epoll_create的时候会创建出epoll模型,这个模型也是利用文件描述类似文件系统的方式控制该结构。 在我们调用epoll_create的时候,就会在内核管理中创建一个epoll模型,并且建管理模块地址给file结构体,file结构体也是连接在管理所有file结构体的数据结构中 所以epo

    2024年02月20日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包