【长文梳理Webserver核心】框架篇

ops/2024/10/10 15:03:26/

感谢前人的总结,让一个小白快速成长,那我也贡献一份自己的力量~

  • 大框架梳理
  • 从main函数开始学习

在这里插入图片描述

大框架梳理

先摆图:
在这里插入图片描述
目光先放到最上面的两个小框架,半同步/半反应堆线程池和异步日志系统,日志系统晓得伐?非常重要但不属于项目业务实现的核心,所以咱先主要看这个半同步/反应堆线程池,它在其中维护了一个请求队列,这个队列非常非常重要,主要用来处理请求(废话。。。

在这个线程池中的主线程通过epoll来监听socket,看有没有新请求,并将请求队列中的任务分配给线程池中的工作线程,OK到下一个绿框框了,工作线程可以处理的任务有三类:

  • 日志输出
  • 定时器处理非活动连接
  • 处理HTTP请求

以上就是文字描述的核心业务,如果更加清晰简单描述的话就是下面这样:
在这里插入图片描述
MainReactor将与Client建立的连接发给Acceptor,Acceptor再将连接分配给一些SubReactor的模块,在SubReactor中对具体的连接进行读、编码、计算、解码和写操作(即对client请求的响应)。

上面这句话是我抄的,有没有和我一样看这句话也会冒出很多问题的朋友?
比如,什么是SubReactor,为什么图片上只画了两个,建立什么样的具体连接…

我直接说了,冒出这种问题是因为前置知识不足
这里用的是主从Reactor多线程,图其实画的…我不知道为什么会一传十十传百,我查资料之后感觉有写问题,如果不对还请评论指出在这里插入图片描述下面以我查完资料的思路讲解一下:

我认为正确的图,来源看水印:
在这里插入图片描述
Reactor多线程方案说明:

  • 主Reactor通过Selector监听连接事件,收到通知后。通过Acceptor处理连接事件
  • 当Acceptor处理连接事件之后,MainReactor将事件分配给SubReactor
  • SubReactor将这个事件加入到队列中,并且创建Handler去处理
  • Handler对事件分发到Worker线程池并且进行处理
  • 主Reactor可以对应多个子Reactor

该方案的优点是:

  • 父线程与子线程的数据交互简单职责明确,父线程只负责接收新连接,子线程完成后续的业务处理
  • 父线程与子线程的数据交互简单,Reactor主线程只需要把新连接传给子线程,子线程无需返回数据

现在再看框架就明白多了
框架就了解到这里吧,接下来梳理一下细节

从main函数开始学习

作者在main函数中进行了参数配置,设置日志的相关参数(存储路径、日志等级…),然后实例化了一个主循环对象,初始化了Webserver单例对象,最后启动了Webserver并开启了主循环。

EventLoop mainLoop;
Server myHTTPServer(&mainLoop, threadNum, port);
myHTTPServer.start();
mainLoop.loop();

其中最重要的函数是myHTTPServer.start();mainLoop.loop();,先着重分析他俩

先看第一个函数myHTTPServer.start();
在这里插入图片描述
主要工作:

  • 启动线程池
  • 设置了acceptChannel_的handler,分别为读回调和连接回调
  • 将acceptChannel_加入Poller

可以看出来是做了一些连接操作,但什么是Poller?什么是acceptChannel_?
现在很多还不好解释,我先解释一下acceptChannel_的读回调函数,读回调函数就是有新连接时执行的函数
在这里插入图片描述
他的主要工作是:

  • 通过accept(3)来建立TCP连接
  • 从线程池中获取一个eventLoop事件循环
  • 将建立的新连接放入eventLoop事件循环

再看下mainLoop.loop();
在这里插入图片描述
做了以下工作:

  • 从poller中取出所有活动事件
  • 调用活动事件的回调函数
  • 执行额外的函数
  • 执行超时的回调函数

http://www.ppmy.cn/ops/123545.html

相关文章

redis+mysql数据一致性+缓存穿透解决方案

在分布式事务中我们知道有cap定理,即 我们保证高可用的情况下,必然要牺牲一些一致性,在保证强一致性的情况下,必然会牺牲一些可用性。而我们redismysql数据一致性的使用策略就是在我们保证可用性的情况下尽量保证数据的一致性。想…

【高等代数笔记】线性空间(二十四下半部分-二十六)

3.23 子空间的运算 【推论1】 dim ⁡ ( V 1 V 2 ) dim ⁡ V 1 dim ⁡ V 2 ⇔ V 1 ∩ V 2 0 \dim(\textbf{V}_1\textbf{V}_2 )\dim\textbf{V}_1\dim\textbf{V}_2\Leftrightarrow\textbf{V}_1\cap\textbf{V}_2\textbf{0} dim(V1​V2​)dimV1​dimV2​⇔V1​∩V2​0 3.24 子…

Spring源码-AOP具体源码

1.类ProxyFactory 核心方法:getProxy 1.DefaultAopProxyFactory#createAopProxy 判断使用JDK还是CGLIB动态代理的代码如下: Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 如果ProxyFactory的isOp…

【VUE】虚拟DOM真的比真实DOM性能好吗

首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。它能保证性能下限,在真实DOM操作的时候进行针对性的优化时,还是更快的。 虚拟DOM(Virtual DOM)相比真实DOM(Real DOM&…

golang包管理

package 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的。本文介绍了Go语言中如何定义包、如何导出包的内容及如何导入其他包。 包与依赖管理 本章学习目标 掌握包的定义和使用掌握init初始化函数的使用掌握…

前端 + Nginx + 后端架构的无感升级方案

一、前端无感升级 构建新的前端包 使用 Webpack、Vite 等工具进行打包,生成带有版本号或哈希值的静态文件名。确保 index.html 引用最新的静态资源文件(例如 app.js?versionabc123)。 上传静态资源到服务器 将打包后的前端静态资源上传到 Ng…

昇思MindSpore进阶教程--数据处理性能优化(中)

大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 shuffle性能优化 shuffle操作主要是对有…

Web3与传统互联网的比较:机遇与挑战

随着科技的不断进步,Web3作为新一代互联网的概念逐渐浮出水面,改变了我们对网络的认知。相较于传统互联网,Web3在许多方面展现出不同的特征与潜力。本文将对Web3与传统互联网进行比较,探讨其带来的机遇与挑战。 一、核心概念的差异…