2.2.2 redis,memcached,nginx网络组件

简介: 2.2.2 redis,memcached,nginx网络组件

课程目标:

1.网络模块要处理哪些事情

2.reactor是怎么处理这些事情的

3.reactor怎么封装

4.网络模块与业务逻辑的关系

5.怎么优化reactor?

io函数 函数调用 都有两个作用:io检测 是否就绪  io操作
1. int clientfd = accept(listenfd, &addr, &len); 检测 全连接队列是否有数据
2. int n = read(clientfd, buf, sz);
3. int n = write(clientfd, buf, sz);

对于客户端而言,怎么知道链接建立成功,主要通过connect返回值(三次握手时是否收到服务端的ack)

对于服务端而言,当recv返回0时,说明对端关闭,实际上是在内核缓存区读到了一个EOF,自然读操作结束。

对于写操作,用户能做的只有将数据写到内核缓存区,至于数据怎么到达对端,到达与否,用户无须干预,这是协议栈做的事情。

IO多路复用只能检测多个链接,却不能操作

对于accept检测全连接队列

对于clientfd检测读缓存区,从而判断是否可读等

对于connect检测写事件,写事件触发,说明连接建立成功

int n = epoll_wait(epfd, evs, 512, timeouts);
for (int i = 0; i < n; i++) {
  epoll_event ev = evs[i];
  if (ev & epollin) {
    listenfd 读事件 新连接到达 accept
    clientfd        这条连接发送数据了 read
  } else {
    connectfd 写事件  连接建立成功了
    clientfd         这条连接写缓存区可写了 write
  }
}
1.注册io就绪的事件 注册io多路复用 事件 包含callback  在callback中操作事件io
2.epoll_wait收集事件,处理事件,事件循环

reactor构成:1.事件封装 2.事件的注册、注销 3.事件循环

reactor就是把对IO的操作转换为对事件的处理

reactor使用epoll来检测IO,而具体的IO操作还需要对应的系统调用来做!!!

如果不用epoll的话,对于阻塞IO,每个连接都需要一个线程,对于非阻塞IO,需要我们在应用层使用while检测。

TCP是全双工的,读端关闭后,仍然可以写数据

one eventloop per thread

一个线程最多只有一个epoll对象

reactor为什么搭配非阻塞IO?

1.多线程环境 将一个listenfd放到多个epoll去处理,会出现问题。当连接到来时,多个epoll都会被触发,但只有一个线程的accpet会返回,其他线程如果使用阻塞IO,则会一直阻塞(因为事件被其他线程处理了)。
2.边缘触发下 读事件触发时,read循环把read buffer读空。如果使用的是阻塞IO,当read buffer为空后,会一直阻塞。
3. select bug 当一个数据到达时,select将会报告读事件,但是可能这个数据没有通过校验和检测所以丢弃了,而select已经上报读事件了,如果此时用阻塞的io read去读将会阻塞线程!

是不是IO多路复用一定要搭配非阻塞IO?

不是!

比如MySQL,使用select接收连接,每条连接一个线程,阻塞只会阻塞这条连接的线程

在比如libevent,可以加一个系统调用 看缓存区中有多少数据(相当于一个检测的作用),但是效率比较低

int n = EVBUFFER_MAX_READ_DEFAULT;
if (ioctl(fd, FIONREAD, &n) < 0)
  return -1;
return n;

网络模块与业务逻辑的关系

怎么优化reactor?

redis 单reactor,nginx,memcached都是多reactor,nginx是使用多进程,而memcached是使用多线程

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:https://ke.qq.com/course/417774?flowToken=1020253

相关文章
|
7月前
|
网络协议 算法 Java
基于Reactor模型的高性能网络库之Tcpserver组件-上层调度器
TcpServer 是一个用于管理 TCP 连接的类,包含成员变量如事件循环(EventLoop)、连接池(ConnectionMap)和回调函数等。其主要功能包括监听新连接、设置线程池、启动服务器及处理连接事件。通过 Acceptor 接收新连接,并使用轮询算法将连接分配给子事件循环(subloop)进行读写操作。调用链从 start() 开始,经由线程池启动和 Acceptor 监听,最终由 TcpConnection 管理具体连接的事件处理。
258 2
|
7月前
基于Reactor模型的高性能网络库之Tcpconnection组件
TcpConnection 由 subLoop 管理 connfd,负责处理具体连接。它封装了连接套接字,通过 Channel 监听可读、可写、关闭、错误等
206 1
|
7月前
基于Reactor模型的高性能网络库之Poller(EpollPoller)组件
封装底层 I/O 多路复用机制(如 epoll)的抽象类 Poller,提供统一接口支持多种实现。Poller 是一个抽象基类,定义了 Channel 管理、事件收集等核心功能,并与 EventLoop 绑定。其子类 EPollPoller 实现了基于 epoll 的具体操作,包括事件等待、Channel 更新和删除等。通过工厂方法可创建默认的 Poller 实例,实现多态调用。
372 60
|
7月前
基于Reactor模型的高性能网络库之Channel组件篇
Channel 是事件通道,它绑定某个文件描述符 fd,注册感兴趣的事件(如读/写),并在事件发生时分发给对应的回调函数。
355 60
|
7月前
|
安全 调度
基于Reactor模型的高性能网络库之核心调度器:EventLoop组件
它负责:监听事件(如 I/O 可读写、定时器)、分发事件、执行回调、管理事件源 Channel 等。
391 57
|
7月前
|
缓存 索引
基于Reactor模式的高性能网络库之缓冲区Buffer组件
Buffer 类用于处理 Socket I/O 缓存,负责数据读取、写入及内存管理。通过预分配空间和索引优化,减少内存拷贝与系统调用,提高网络通信效率,适用于 Reactor 模型中的异步非阻塞 IO 处理。
258 3
|
7月前
高性能网络库设计之日志组件
高性能网络库设计之日志组件
219 2
|
6月前
|
运维 监控 安全
计算机网络及其安全组件纲要
本文主要介绍了 “计算机网络及常见组件” 的基本概念,涵盖网卡、IP、MAC、OSI模型、路由器、交换机、防火墙、WAF、IDS、IPS、域名、HTTP、HTTPS、网络拓扑等内容。
340 0
|
8月前
|
安全 Java 程序员
分析Muduo网络库源码中的TcpServer组件工作原理
简言之,TcpServer 在 Muduo 中的角色,就是一位终极交通指挥员,它利用现代计算机网络的魔法,确保数据如同车辆一般,在信息高速公路上自由、安全、高效地流动。
106 0
|
缓存 JavaScript
Vue加载网络组件(远程组件)
【10月更文挑战第23天】在 Vue 中实现加载网络组件(远程组件)可以通过多种方式来完成。