当前位置: 首页 > news >正文

websevere服务器从零搭建到上线(三)|IO多路复用小总结和服务器的基础框架

文章目录

  • epoll
    • select和poll的优缺点
    • epoll的原理以及优势
    • epoll
  • 好的网络服务器设计
  • Reactor模型
    • 图解Reactor
  • muduo库的Multiple Reactors模型

epoll

select和poll的优缺点

1、单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于 select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有 这样的定义:#define __FD_SETSIZE 1024

2、内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销

3、select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件

4、select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作, 那么之后每次select调用还是会将这些文件描述符通知进程

相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在

以select模型为例,假设我们的服务器需要支持100万的并发连接,则在__FD_SETSIZE 为1024的情况 下,则我们至少需要开辟1k个进程才能实现100万的并发连接。除了进程间上下文切换的时间消耗外, 从内核/用户空间大量的句柄结构内存拷贝、数组轮询等,是系统难以承受的。因此,基于select模型的 服务器程序,要达到100万级别的并发访问,是一个很难完成的任务。

epoll的原理以及优势

epoll的实现机制与select/poll机制完全不同,它们的缺点在epoll上不复存在。

设想一下如下场景:有100万个客户端同时与一个服务器进程保持着TCP连接。而每一时刻,通常只有 几百上千个TCP连接是活跃的(事实上大部分场景都是这种情况)。如何实现这样的高并发?

  1. 在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到 内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完成后,再将句柄数据复制到用 户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般 只能处理几千的并发连接。
  2. epoll的设计和实现与select完全不同。epoll通过在Linux内核中申请一个简易的文件系统(文件系统一 般用什么数据结构实现?B+树,磁盘IO消耗低,效率很高)。把原先的select/poll调用分成以下3个部分:
  • 调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)
  • 调用epoll_ctl向epoll对象中添加这100万个连接的套接字
  • 调用epoll_wait收集发生的事件的fd资源

如此一来,要实现上面说是的场景,只需要在进程启动时建立一个epoll对象,然后在需要的时候向这 个epoll对象中添加或者删除事件。同时,epoll_wait的效率也非常高,因为调用epoll_wait时,并没有 向操作系统复制这100万个连接的句柄数据,内核也不需要去遍历全部的连接。

//epoll_create在内核上创建的eventpoll结构如下:
struct eventpoll{.... /*红黑树的根节点,这颗树中存储着所有添加到epoll中的需要监控的事件*/ struct rb_root rbr; /*双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件*/ struct list_head rdlist; ....
};

epoll

epoll重点掌握LT模式和ET模式。

关于这一节可以读以下两篇博客:
IO多路转接(复用)之epoll
epoll边沿模式的非阻塞方法

好的网络服务器设计

陈硕老师的原话
在这个多核时代,服务端网络编程如何选择线程模型呢? 赞同libev作者的观点:one loop per thread is usually a good model这样多线程服务端编程的问题就转换为如何设计一个高效且易于使 用的event loop,然后每个线程run一个event loop就行了(当然线程间的同步、互斥少不了,还有其 它的耗时事件需要起另外的线程来做)。

event loop 是 non-blocking 网络编程的核心,在现实生活中,non-blocking 几乎总是和 IOmultiplexing 一起使用,原因有两点:

  • 没有人真的会用轮询 (busy-pooling) 来检查某个 non-blocking IO 操作是否完成,这样太浪费 CPU资源了。
  • IO-multiplex 一般不能和 blocking IO 用在一起,因为 blocking IO 中 read()/write()/accept()/connect() 都有可能阻塞当前线程,这样线程就没办法处理其他 socket 上的 IO 事件了。

所以,当我们提到 non-blocking 的时候,实际上指的是 non-blocking + IO-multiplexing,单用其 中任何一个都没有办法很好的实现功能

更强大的网络服务器Nginx!
采用的是epoll + fork 而不是epoll+pthread!
用多个进程程来监听新链接,不想muduo只有一个线程来监听网络连接

强大的nginx服务器采用了epoll+fork模型作为网络模块的架构设计,实现了简单好用的负载算法,使 各个fork网络进程不会忙的越忙、闲的越闲,并且通过引入一把乐观锁解决了该模型导致的服务器惊群 现象,功能十分强大。

Reactor模型

Reactor模型是一个设计一个高性能网络服务器的常用模型。

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.
反应堆设计模式是一种事件处理模式,用于处理由一个或多个输入并发传递给服务处理程序的服务请求。然后,服务处理程序对传入的请求进行多路复用,并将它们同步地分派给相关的请求处理程序。

重要组件:Event事件、Reactor反应堆、Demultiplex IO多路复用事件分发器、Evanthandler事件处理器
之后我们主要关注这四个组件的通信即可。

图解Reactor

请添加图片描述

交互流程:

  1. 首先会把事件注册到反应堆上,所谓的注册指的是应用程序对该事件比较感兴趣,我们请求反应堆帮我来监听我所感兴趣的事件,并且在事件发生的时候调用我预置的回调函数Handler
  2. 反应堆可以理解为存储了一个Event事件以及事件处理的集合,我们的事件处理可以添加很多的选项,比如事件响应、事件处理等等。每一个Event都对应一个Handler,所以的反应堆就维护了这样一个集合。然后reactor会调用epoll_ctl来设置相关的方法来处理sockfd,这个过程是借助Demultiplex实现。
  3. 我们这里的Demultiplex用来处理epoll_ctl的相关处理,然后Reactor自己启动反应堆,反应堆的后端就能驱动事件分发器Demultiplex(其实就是开启epoll_wait)的使用,整个服务器呈现出阻塞的状态来等待新用户的链接或者是已连接用户的读写事件,epoll_wait监听到了新事件产生,Demultiplex会把事件给反应堆返回。

为什么Demultiplex会返回给Reactor呢,因为事件Event发生后,我们需要调用对应的事件处理器Handler,这是我们注册在Reactor中的

  1. 最后对于发生事件的Event,我们就通过一个Map表来找到该事件Event对应的那个EventHandler,最后处理该任务。

muduo库的Multiple Reactors模型

在这里插入图片描述

在muduo网络库中,Reactor中已经集成了Demultiplex IO多路复用事件分发器组件(图片来源见水印)

在 muduo 库中,许多 client 在 MainReactor 中得到了连接请求的响应,并与 WebServer 建⽴具体的连接。然后通过⼀个叫 Acceptor 的模块,将具体的连接分配给到⼀些叫做 SubReactor 的 模块,在 SubReactor 中对具体的连接进⾏读、编码、计算、解码和写操作(即对 client 请求的响应)。

所以改图有一点不准确,Reactor其实就是存储了事件以及事件处理器,仅此而已,所以上图应该画成事件份发器。

相关文章:

websevere服务器从零搭建到上线(三)|IO多路复用小总结和服务器的基础框架

文章目录 epollselect和poll的优缺点epoll的原理以及优势epoll 好的网络服务器设计Reactor模型图解Reactor muduo库的Multiple Reactors模型 epoll select和poll的优缺点 1、单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数…...

解决宝塔Nginx和phpMyAdmin配置端口冲突问题

问题描述 在对基于宝塔面板的 Nginx 配置文件进行端口修改时,我注意到 phpMyAdmin 的端口配置似乎也随之发生了变化! 解决方法 官方建议在处理 Nginx 配置时,应避免直接修改默认的配置文件,以确保系统的稳定性和简化后续的维护…...

光伏EPC管理软件都有哪些功能和作用?

光伏EPC管理软件是用于光伏工程项目管理的综合性工具,它涵盖了从项目策划、设计、采购、施工到运维的各个环节。 1、项目总览 管理所有项目计划,包括项目类型、项目容量等。 调整和优化项目计划,以应对不可预见的情况。 2、施工管理 制定…...

BGP学习一:关于对等体建立和状态组改变

目录 一.BGP基本概念 (1).BGP即是协议也是分类 1.早期EGP 2.BGP满足不同需求 3.BGP区域间传输的优势 (1)安全性——只传递路由信息 (2)跨网段建立邻居 4.BGP总结 5.BGP的应用 (1&#…...

ETL工具kettle(PDI)入门教程,Transform,Mysql->Mysql,Csv->Excel

什么是kettle,kettle的下载,安装和配置:ETL免费工具kettle(PDI),安装和配置-CSDN博客 mysql安装配置:Linux Centos8 Mysql8.3.0安装_linux安装mysql8.3-CSDN博客 1 mysql -> mysql 1.1 mysql CREATE TABLE user_…...

常见地图坐标系间的转换算法JavaScript实现

文章目录 🍉 不同的地图厂商使用不同的坐标系来表示地理位置。以下简述:🍉 前置常量和方法:🍉 BD-09转GCJ-02(百度转谷歌、高德)🍉 GCJ-02转BD-09(谷歌、高德转百度)🍉 WGS84转GCJ-02(WGS84转谷歌、高德)🍉 GCJ-02转WGS84(谷歌、高德转WGS84)🍉 BD-09转wgs84坐…...

基于python的大麦网自动抢票工具的设计与实现

基于python的大麦网自动抢票工具的设计与实现 Design and Implementation of Da Mai Net Ticket Grabbing tool based on Python 完整下载链接:基于python的大麦网自动抢票工具的设计与实现 文章目录 基于python的大麦网自动抢票工具的设计与实现摘要第一章 引言1.1 研究背景…...

2024年5月树莓集团快讯

树莓集团近期快讯 1 园区专场招聘会进校园 国际数字影像产业园联合四川城市职业学院的专场招聘会成功召开,共计提供400余个工作岗位。 2 园区硬件优化再升级 园区硬件优化再升级,智能门禁系统及人脸识别系统下周投入使用。 3 基地短剧合作交流 天府…...

网站localhost和127.0.0.1可以访问,本地ip不可访问解决方案

部署了一个网站, 使用localhost和127.0.0.1加端口号可以访问, 但是使用本机的ip地址加端口号却不行. 原因可能有多种. 可能的原因: 1 首先要确认是否localhost对应的端口是通的(直接网址访问), 以及你无法访问的那个本机ip是否正确(使用ping测试); 2 检查本机的防火…...

Docker Dockerfile如何编写?

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 1.指令说明 FROM,构建镜像基于哪个镜像 MAINTAINER,镜像维护者姓名或邮箱地址 RUN,构建镜像时运行的指令 CMD,运行容器时执…...

Python数独游戏

数独(Sudoku)是一种逻辑性的数字填充游戏,玩家需要在一个分为九宫的81格网格上填入数字,同时满足每一行、每一列以及每个宫(3x3的子网格)的数字都不重复。 在Python中实现一个数独游戏可以涉及到多个方面&…...

24 | MySQL是怎么保证主备一致的?

MySQL 主备的基本原理 内部流程 备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接。一个事务日志同步的完整过程是这样的: 在备库 B 上通过 change master 命令,设置主库 A 的 IP、端口、用户名、密码,以及要从哪个位置开始…...

2.数据类型与变量(java篇)

目录 数据类型与变量 数据类型 变量 整型变量 长整型变量 短整型变量 字节型变量 浮点型变量 双精度浮点型 单精度浮点型 字符型变量 布尔型变量(boolean) 类型转换 自动类型转换(隐式) 强制类型转换(显式) 类型提升 字符串类型 数据类…...

QT设计模式:桥接模式

基本概念 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使得它们可以独立地变化,而不会相互影响。 需要实现的结构如下: 抽象部分(Abstraction):定义了抽象类的接口&#x…...

简单粗暴的翻译英文pdf

背景:看书的时候经常遇到英文pdf,没有合适的翻译软件可以快速翻译全书。这里提供一个解决方案。 Step 1 打开英文pdfCTRLA全选文字CTRLC复制打开记事本CTRLV复制保存为data.txt Step 2 写一个C脚本 // ToolPdf2Html.cpp : 此文件包含 "main&quo…...

UDP和TCP协议比较,TOE技术

如今在某些方面TCP超越UDP的主要原因如下 在硬件层面的TOE(TCP Offload Engine)功能,将越来越多的TCP功能卸载到网卡上。它极大地提升了TCP的性能,使其在高吞吐量场景下的表现更为出色。近年TCP的拥塞控制算法实现了显著进步。这些新算法显著提高了TCP在…...

第十三节 huggingface的trainner解读与Demo

文章目录 前言一、trainer和TrainingArguments训练与预测完整Demo1、数据构建2、TrainingArguments构建3、Trainer初始化4、模型训练5、模型推理6、完整demo代码7、完整运行结果二、辅助函数1、yield返回内容2、迭代器中断恢复迭代demo3、yield from结构4、torch.Generator()的…...

GO: json 处理

需要引入"encoding/json"包 json解析到map jsonStr : "{\"a\":\"test\",\"b\":\"testb\"}" var dat map[string]string err : json.Unmarshal([]byte(jsonStr), &dat) if err nil {fmt.Println(dat) }结果…...

HarmonyOS开发案例:【生活健康app之实现打卡功能】(2)

实现打卡功能 首页会展示当前用户已经开启的任务列表,每条任务会显示对应的任务名称以及任务目标、当前任务完成情况。用户只可对当天任务进行打卡操作,用户可以根据需要对任务列表中相应的任务进行点击打卡。如果任务列表中的每个任务都在当天完成则为…...

Mockito框架,帮助创建模拟对象进行测试的利器

在现代软件开发中,单元测试作为确保代码质量和可靠性的重要环节,已逐渐成为开发流程中不可或缺的一部分。为了让单元测试更加灵活、独立,开发者们通常使用 Mocking(模拟)框架来替代真实对象,从而更好地模拟…...

GNSS/SINS组合导航实战:静基座精对准中的卡尔曼滤波参数调优技巧

GNSS/SINS组合导航实战:静基座精对准中的卡尔曼滤波参数调优技巧 在嵌入式导航系统开发中,静基座精对准是确保初始姿态精度的关键环节。许多工程师在调试卡尔曼滤波器时,常陷入参数试错的困境——Q矩阵该设多大?R矩阵如何匹配传感…...

OpenClaw深度沟通渠道-全景深度解构

OpenClaw深度沟通渠道-全景深度解构OpenClaw的渠道(Channels)是其“交互层”的核心,是用户意图与AI执行力的唯一交汇点。选择渠道,就是选择将AI能力注入您数字生活的哪个场景。以下分析将超越简单列表,深入每个渠道的技…...

Llama Factory应用场景:快速打造行业专属的智能客服模型

Llama Factory应用场景:快速打造行业专属的智能客服模型 1. 引言:当智能客服遇见“模型工厂” 想象一下这个场景:一家电商公司,每天要处理成千上万的客户咨询。从“这个衣服有货吗”到“我的订单为什么还没发货”,客…...

【CTF | pwn篇】从栈溢出到ROP:ctfshow pwn实战技巧精讲

1. 栈溢出基础:从零开始理解漏洞利用 栈溢出是PWN领域最经典的漏洞类型之一,也是CTF比赛中出现频率最高的题型。我们先从一个最简单的例子开始,看看如何利用栈溢出漏洞控制程序执行流程。 1.1 栈的结构与函数调用 当程序调用函数时&#xff0…...

STM32G474低功耗模式怎么选?一张图看懂睡眠、停止、待机模式区别与实战选型

STM32G474低功耗模式实战选型指南:从睡眠到待机的全场景决策框架 当你面对一块需要连续工作数月的电池供电设备时,每个微安培的电流都变得至关重要。STM32G474系列作为意法半导体针对高性能低功耗场景推出的微控制器,提供了从轻度睡眠到深度休…...

数字游民工作流:OpenClaw+nanobot全球远程办公方案

数字游民工作流:OpenClawnanobot全球远程办公方案 1. 为什么需要自动化全球办公方案 作为一名长期在东南亚各国旅居的数字游民,我深刻体会到跨时区工作的痛苦。凌晨三点被欧洲同事的Slack消息吵醒,错过亚太区的晨会,或是忘记在不…...

PCL2社区版:打造个性化Minecraft启动器的终极指南

PCL2社区版:打造个性化Minecraft启动器的终极指南 【免费下载链接】PCL-CE PCL2 社区版,可体验上游暂未合并的功能 项目地址: https://gitcode.com/gh_mirrors/pc/PCL-CE 想要完全掌控你的Minecraft游戏体验吗?PCL2社区版(…...

HunyuanVideo-Foley 效果对比:不同算法模型生成音效的质量评估

HunyuanVideo-Foley 效果对比:不同算法模型生成音效的质量评估 1. 音效生成技术概览 音效生成技术正在经历一场革命性的变革。从早期的采样拼接到如今的AI生成,算法模型已经能够根据简单的文字描述创造出丰富多样的声音效果。这项技术在影视制作、游戏…...

Phi-3-mini-128k-instruct在软件测试中的应用:自动化生成测试用例与脚本

Phi-3-mini-128k-instruct在软件测试中的应用:自动化生成测试用例与脚本 1. 引言 如果你是一名软件测试工程师,或者正在准备软件测试面试,下面这个问题你一定不陌生:“如何保证测试用例的覆盖率,尤其是在需求频繁变更…...

文脉定序系统压力测试与性能监控方案

文脉定序系统压力测试与性能监控方案 最近不少朋友在部署完文脉定序系统后,都会来问我同一个问题:“服务上线了,心里还是没底,怎么知道它能扛住多少用户同时访问?平时运行稳不稳定?” 这确实是个很实际的问…...