Apache和Nginx是什么?|Nginx和Reactor是什么?|网路IO的本质|阻塞队列|异步非阻塞IO
前言
那么这里博主先安利一些干货满满的专栏了!
首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。
高质量干货博客汇总
https://blog.csdn.net/yu_cblog/category_12379430.html?spm=1001.2014.3001.5482
前期概念准备
首先,想要搞明白Nginx和Apache,我们首先要对网络IO的相关概念做了解,这是非常重要的。什么是阻塞IO,什么是非阻塞IO,什么是异步IO,什么是多路转接,什么是reactor模式,这些大家都要先搞清楚,本期博客的内容,大家才能明白。
因此对于上面这些内容,博主做了详细的解释和讲解,在上一篇博客中,如果对网络IO相关概念还不了解的伙伴们,先看完上一篇,再来学习这一篇~
Apache和Nginx
Apache HTTP服务器的底层原理
Apache HTTP服务器采用了经典的多进程/多线程模型。它的主要组件包括主进程/线程(Master Process/thread)和工作进程线程(Worker Process/thread)。当Apache启动时,主进程首先被创建,并监听指定的端口,等待客户端连接。当有新的连接请求到达时,主进程接受该连接并将其分派给一个可用的工作进程。
通俗来说,就是多线程或者多进程,当然一般是用线程的,因为线程占用cpu资源少。其实就是一个主线程,在统一管理一些新线程。服务器启动,一个主线程被创建,如果底层来链接了,则创建一个新线程,调用accept,则这个新线程专门用于处理这一个特定的链接,直到链接关闭。来一个链接,主线程就创建一个新线程,本质就是用新线程去接任务的道理。当然这种方案是可以优化的,一般会做一个线程池去完成这些事情,先创建好一堆线程,然后来链接了,则一个线程去领任务,如果线程池线程不够了,可以选择创建,或者阻塞等其他线程释放。
那么这种方法问题在哪呢?如果一个链接来了,是一个长链接,我赖着不走,也不给你发消息,那你这领任务线程咋办?就只能被这个占着坑位不干活的链接吊着,既不能释放,也不能工作。如果这样的长链接很多,这是非常吃CPU资源的!
Nginx的底层原理
Nginx采用了事件驱动的、异步的单进程模型。它的底层结构由多个模块组成,包括事件模块、HTTP模块、反向代理模块等。
核心组件是事件模块,它利用操作系统提供的异步I/O机制(如epoll、kqueue)来实现高效的事件处理。Nginx的主进程是一个事件驱动的Reactor,通过事件循环(Event Loop)监听和接受客户端连接。当有新的连接到达时,主进程会将连接分发给一个可用的工作进程。
工作进程(Worker Process)是Nginx实际处理请求的执行者。每个工作进程都是独立的,并且在多个连接间共享相同的事件循环。工作进程通过事件驱动的方式处理请求,包括读取请求、解析请求头、处理请求逻辑、生成响应等。在处理请求的过程中,Nginx使用非阻塞I/O操作,充分利用异步I/O机制来提高并发处理能力。
reactor(用linux下的epoll为例)
其中reactor就是Nginx的核心构件,我直接举一个例子解释,什么是事件循环,什么是监听这些东西。直接举例子,大家就明白了。对于一个HTTP请求而言:
对于一个服务器,肯定有一个监听套接字listensock。当服务器开启之后,肯定会有其他地方来的许多链接,想和我们这个服务器三次握手,因此我们有连接来了,应该去accept对吧?但是现在在epoll多路转接模式下,不能直接让listensock去accept!为什么,因为我不知道什么时候来链接啊,如果链接没来,我调用accept不就阻塞了?因此,我们应该把listensock放到epoll里面去注册!!然后直接返回,不用阻塞!注册好之后,如果链接来了,也就是说listensock套接字(套接字的本质就是文件描述符,这些基本的概念博主也不赘述了)的读事件就绪了!epoll就会通知我!我此时再去accept,此时是一定不会被阻塞了!因为epoll告诉我,listensock的读事件已经就绪了!
那么我们知道accept之后的套接字,也就是普通套接字,可能会给我们发消息的,那么按照之前的方法,直接调用read行吗?肯定是不行的!没消息来你read什么,没消息你read不就阻塞了?epoll里面不能有这么低级的操作。因此,同样,注册到epoll里面去!啥时候来消息了,epoll告诉你,你就不用管了,直接返回。
整个过程将一个请求分成了多个阶段,每个阶段都会在许多模块中注册并进行处理,而且所有的操作都是异步非阻塞的。异步在这里表示服务器执行一个任务后无需等待返回结果,而是在完成后自动接收通知。
整个过程是单进程单线程的,但是高并发!长链接来了我不怕啊,你只是注册在epoll里面,你不来消息,我就不在你身上花时间(调用read),因此这种方式非常的高效!!!!!这种方式使得服务器能够高效处理多个并发请求,并能在等待I/O操作期间执行其他任务,以提高整体性能。
epoll的底层是什么?相比于select和poll的优势在哪?这些可以看博主在github上关于多路转接的一个项目,里面说的非常的清晰了!
reactor只有epoll吗?
Reactor模式是一种设计模式,用于构建事件驱动的应用程序。在Reactor模式中,有一个事件循环(Event Loop)负责监听事件并调度对应的处理程序。具体的底层实现可以采用多种技术和系统调用,其中epoll是Linux系统下常用的事件通知机制之一。
在Linux系统中,epoll提供了高效的I/O事件通知机制,使得服务器能够处理大量的并发连接。因此,很多Reactor模式的实现会选择使用epoll作为底层的事件通知机制,以实现高性能的事件驱动。
然而,Reactor模式的底层实现并不仅限于epoll,它也可以使用其他的事件通知机制,如select、poll等,或者在其他操作系统上使用相应的机制,如kqueue(在FreeBSD和Mac OS X上)或IOCP(在Windows上)。
因此,Reactor模式并不依赖于特定的底层实现,而是关注于事件驱动的设计思想和模式。具体的底层实现取决于操作系统和开发者选择的事件通知机制。
Nginx的一些其他功能
此外,Nginx还提供了强大的模块化架构,用户可以根据需求选择和配置不同的模块。Nginx的模块可以实现诸如负载均衡、缓存、反向代理、SSL/TLS加密等功能。模块可以通过配置文件进行加载和配置,使得Nginx具有很高的灵活性和可扩展性。
一个基于Reactor模型的Http服务器
最近博主就在做一个这样的http服务器,基于Reactor异步IO,底层多路转接的方式实现的,可以达到高效率的要求。
现在这个项目的后端已经基本完善了,现在还在完善一些细节,希望大家多多支持这个项目~~
Reactor-based-HyperWebServerhttps://github.com/Yufccode/Reactor-based-HyperWebServer
总结
无论是Nginx还是Squid等反向代理服务器,它们都采用了事件驱动的网络模式。事件驱动实际上是一项古老的技术,早期使用的是select和poll等机制。随后,基于内核通知的更高级事件机制出现,例如libevent中的epoll,这提高了事件驱动的性能。事件驱动的核心仍然是I/O事件,应用程序能够快速切换在多个I/O句柄之间,实现所谓的异步I/O。事件驱动服务器非常适合处理I/O密集型任务,例如反向代理,它充当客户端和Web服务器之间的数据中转站,仅涉及纯粹的I/O操作,而不涉及复杂的计算。使用事件驱动来构建反向代理是更好的选择,一个工作进程即可运行,无需管理进程和线程带来的开销,同时CPU和内存消耗也较小。
因此,Nginx和Squid等服务器都是采用这种方式实现的。当然,Nginx也可以采用多进程加事件驱动的模式,几个进程运行libevent,而无需像Apache那样需要数百个进程。Nginx在处理静态文件时也表现出色,这是因为静态文件本身也属于磁盘I/O操作,处理方式相同。至于所谓的数万并发连接,这并没有多大意义。随手编写一个网络程序就可以处理数万个并发连接,但如果大多数客户端都被阻塞在某处,那就没有多少价值了。
再来看看像Apache或Resin这样的应用服务器,它们之所以被称为应用服务器,是因为它们需要运行具体的业务应用程序,如科学计算、图形图像处理、数据库读写等。它们很可能是CPU密集型的服务,而事件驱动并不适合此类情况。举个例子,如果某项计算需要2秒的耗时,那么这2秒将完全阻塞进程,事件机制毫无作用。想象一下,如果MySQL改用事件驱动,一个大型的join或sort操作将阻塞所有客户端。在这种情况下,多进程或多线程展现出优势,每个进程可以独立地执行任务,彼此不会阻塞或干扰。当然,现代CPU速度越来越快,单个计算的阻塞时间可能很短,但只要存在阻塞,事件编程就不具备优势。因此,进程和线程等技术不会消失,而是与事件机制相辅相成,并将长期存在。
总而言之,事件驱动适用于I/O密集型服务,而多进程或多线程适用于CPU密集型服务。它们各自具有优势,并不存在取代彼此的趋势。
本段文字参考:
版权声明:本文为CSDN博主「席飞剑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:Apache与Nginx网络模型_nginx和apache什么网络模型_席飞剑的博客-CSDN博客
Apache和Nginx是什么?|Nginx和Reactor是什么?|网路IO的本质|阻塞队列|异步非阻塞IO的更多相关文章
- 在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树
nginx平台初探(100%) — Nginx开发从入门到精通 http://ten 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来 ...
- nginx学习(二)——基础概念之异步非阻塞
上面讲了很多关于nginx的进程模型,接下来,我们来看看nginx是如何处理事件的. 有人可能要问了,nginx采用多worker的方式来处理请求,每个worker里面只有一个主线程,那能够处理的并发 ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- 同步异步阻塞非阻塞Reactor模式和Proactor模式 (目前JAVA的NIO就属于同步非阻塞IO)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- Reactor和Proactor模式的讲解(关于异步,同步,阻塞与非阻塞)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- apache和nginx那点事儿--阻塞和异步
先明白的事儿:当一个程序在执行的时候,一般会创建一个进程,也可以有多个进程.一个进程至少会创建一个线程,多个线程共享一个程序进程的内存.程序的运行最终是靠线程来完成操作的.线程的数量跟CPU核数有关, ...
- 【夯实Nginx基础】Nginx工作原理和优化、漏洞
本文地址 原文地址 本文提纲: 1. Nginx的模块与工作原理 2. Nginx的进程模型 3 . NginxFastCGI运行原理 3.1 什么是 FastCGI ...
- 【Nginx 大系】Nginx服务器面面观
Nginx官方文档中文版 1. 先看看百度百科对Nginx 的解释: nginx_百度百科 2. 下面的博客就是讲 Nginx的安装方法和 具体的配置文件的使用介绍的很详细,可以仔细阅读下 [好]Ng ...
- Nginx教程(一) Nginx入门教程 (转)
1 Nginx入门教程 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行.由俄罗斯的程序设计师IgorSysoev所开 ...
- Nginx 之三:nginx服务器模块、web请求处理机制及事件驱动模型、进程功能和进程间通信
一:Nginx的模块化结构设计: 1.核心模块:指的是nginx服务器运行当中必不可少的模块,这些模块提供了最基本最核心的服务,比如权限控制.进程管理.错误日志.事件驱动.正则表达式解析等,nginx ...
随机推荐
- AcWing 第 13 场周赛 补题记录
比赛链接:Here AcWing 3811. 排列 签到题, 先输出 \(n\) 然后输出 \(1\sim n -1\) 即可 AcWing 3812. 机器人走迷宫 不会什么特别高级的方法 qaq, ...
- AtCoder Beginner Contest 214 (D并查集,E反悔贪心,F公共子序列DP)
题目链接:Here ABC水题, D - Sum of Maximum Weights 上图中最大权 \(9\) 对答案的贡献是这条边两边的连通块的 size 的乘积再乘以 9 受到上面的启发,我们可 ...
- uni-app实现登录功能
https://www.bilibili.com/video/BV1jy4y1B7pw?p=140&spm_id_from=pageDriver uniapp封装request,设置请求头与t ...
- APB Slave Mux
基于APB slave mux我们可以快速地将多个apb slave连接在APB上面.在实际的设计当中都是采用这样的方式连接多个APB slave的 DECODE4BIT - 可以理解为master接 ...
- AHB-SRAMC Design-02
AHB-SRAMC Design SRAMC(另外一种代码风格)解析 SRAM集成,顶层模块尽量不要写交互逻辑 module ahb_slave_if( input hclk, input hrest ...
- java - 标准类的定义
一个标准的类需要拥有下面 4个 组成部分: 1. 所有的成员变量都要使用 private 关键字进行修饰 2. 为每一个成员变量编写 set.get 方法 3. 创建一个无参数的构造方法 4. 创建一 ...
- Android Studio 的 Gradle 面板没有 Task
问题描述:Android Studio Gradle 窗口没有显示 task 列表的问题,如下图所示: 网上找了好久都没有找到原因,最后自己摸索,找了解决方法. 解决方法:依次点击:File -> ...
- [转帖]nginx 剖析 request_time和upstream_response_time的误区、区别
https://cloud.tencent.com/developer/article/1767981 首先,澄清一个误区 upstream_response_time必须在upstream配置时才能 ...
- [转帖]配置cri-docker使kubernetes1.24以docker作为运行时
从kubernetes 1.24开始,dockershim已经从kubelet中移除,但因为历史问题docker却不支持kubernetes主推的CRI(容器运行时接口)标准,所以docker不能再作 ...
- [转帖]renice和nice
https://www.cnblogs.com/qiynet/p/17555881.html 将行程 id 为 987 及 32 的行程与行程拥有者为 daemon 及 root 的优先序号码加 1 ...