1、web服务

1.1 web介绍

Web网络服务也叫WWW(World Wide Web 全球信息广播)万维网服务,一般是指能够让用户通过浏览器访问到互联网中文档等资源的服务。

Web 网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的请求后才会响应,最终用于提供服务程序的 Web 服务器会通过 HTTP(超文本传输协议)或HTTPS(安全超文本传输协议)把请求的内容传送给用户。

浏览器访问web网站的过程

1. 在浏览器地址栏中输入网址
2. DNS 服务解析域名,客户端获得服务器 IP 地址
3. 浏览器用 TCP 的三次握手与服务器建立连接
4. 浏览器向服务器发送拼好的请求报文
5. 服务器收到报文后处理请求,同样拼好响应报文再发给浏览器
6. 浏览器解析报文,渲染输出页面

1.2 URI和URL

URI:(Uniform Resource Identifier), 统一资源标识符,是一个用来唯一标识互联网上某一特定资源的字符串。

URL:(Uniform Resource Locator),统一资源定位符。

URN:(Uniform Resource Name),统一资源名称。

WEB 上的可用的每种资源,HTML文档,图片文件,音视频文件,压缩包等,都可以用一个全网唯一的URI 来标识出来,该标识允许用户对任何资源通过特定的协议进行交互操作。

简单来说,URI 是抽象的定义,不管用什么方法表示,只要能定位一个资源,就叫 URI。在早期的设计中,用来定位资源的方式有两种,用地址定位(URL)和 用名称定位(URN),不管用哪种方式定位,只要能保证全网唯一即可,只是使用 URN 的场景较少,导致在 WEB 应用上,几乎所有的URI 都是 URL 形式的。

URL组成如下:

<scheme>://<user>:<password>@<host>:<port>/<path>?<query>#<frag>
​
#########说明##########
scheme:获取资源的协议,例如http,https
user:用户名,某些资源需要权限才能获取
password:密码
host:资源所在服务器的 IP 或域名
port:端口
path:路径,资源在服务器上的相对路径
query:查询,客户端提交的查询参数,键值对形式,key=value,多个查询参数用&分隔
frag:片段,用来锚定资源的一部分
示例:
https://rpmfind.net/linux/rpm2html/search.php?query=http&submit=Search+...&system=&arch=
https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
​
​
#########网址中特殊符号说明:
+表示空格
% 符号是 URL的转义标志。它通过 %XX 的格式,确保所有字符都能安全、无误地在网络上传输,而不会与URL自身的语法结构发生冲突。

1.3 http协议报文

1.3.1 http协议

HTTP 是一种允许浏览器向服务器获取资源的协议,是 WEB 的基础,通常由浏览器发起请求,用来获取不同类型的资源,比如 HTML 文件,CSS 文件,Javascript 文件,图片,视频,压缩包等。

1.3.2 http的请求报文

http请求报文由请求行、请求头部、空行和请求报文主体几个部分组成。

报文格式 报文信息 说明
请求行 请求方法 URL 协议版本 请求行是请求报文的第一行,用来说明客户端想要做什么
请求头 字段名1:值1 字段名2:值2 …… Accept:image/gif,image/jpeg 媒体类型 Accept-Language:zh-cn 语言类型 Accept-Encoding:gzip,deflate 支持压缩 user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 客户端类型 Host:www.ceshi.com 主机名
空行 空白无内容 通知web服务器空行以下不会有请求头部的信息了
请求报文主体 GET方法没有请求报文主体,POST方法才有 请求报文主体中包括了要发送给web服务器的数据信息。请求报文主体不会应用于http的GET命令方法,而是应用于post方法。

http的方法

求方法 协议版本 说明
GET 0.9 获取资源,可以理解为读取或者下载数据
HEAD 1.0 获取资源,和 GET 类似,不返回具体数据,只需要头信息
POST 1.0 向服务端提交数据,数据通常交由后端程序处理
PUT 1.1 向服务端提交数据,数据直接存储在服务器上
PATCH 1.1 对PUT方法的补充,用来对己知资源进行局部更新
DELETE 1.1 请求服务端删除指定资源
CONNECT 1.1 建立一个到服务端的隧道
OPTIONS 1.1 请求服务端返回对指定资源支持使用的请求方法
TRACE 1.1 追踪请求到达服务器中间经过的代理服务器

1.3.3 http的响应报文

http响应报文由起始行、响应头部、空行和响应报文主体这几个部分组成

报文格式 报文信息 说明
起始行 协议及版本号 数字状态码 状态信息 用来说明服务器响应客户端请求的状况,例如:HTTP/1.1 200 OK
响应头部 字段名1:值1 字段名2:值2 常见的头部信息: Content-Length: 81 说明响应主体的长度 Content-Type: text/html; charset=UTF-8 说明文档的MIME类型
空行 空白无内容 通知客户端空行以下无头部信息了
响应报文主体 <html> <head> <title> test </title> </head> <body> this is test </body> </html> 响应报文主体中装载了要返回给客户端的数据,这些数据可以是文本,也可以是二进制的(如图片,视频)。

MIME类型:(Multipurpose Internet Mail Extension,多用途因特网邮件扩展)最初是为了解决在不同的电子邮件系统之间搬移报文时存在的问题。后来http也支持了这个功能,用它来描述数据并标记不同的数据内容类型。 当web服务器响应http请求时,会为每一个http对象数据加一个MIME类型。当web浏览器获取到服务器返回的对象时,会去查看相关的MIME类型,并进行相应的处理。MIME类型存在于HTTP响应报文的响应头部信息里,它是一种文本标记,表示一种主要的对象类型和一个特定的子类型。常见的MIME类型:

MIME类型 文件类型
text/html html、htm、shtml文本类型
text/css css文本类型
text/xml xml文本类型
image/gif gif图像类型
image/jpeg jpeg、jpg图像类型
application/javascript js文本类型
text/plain txt文本类型
application/json json文本类型
video/mp4 mp4视频类型
video/quicktime mov视频类型
video/x-flv flv视频类型
video/x-ms-wmv wmv视频类型
video/x-msvideo avi视频类

http的响应状态码:状态码是一个十进制的数字,以代码的形式表示服务端对请求的处理结果,客户端可以根据此值转换处理状态,比如继续发送请求,切换协议,重定向跳转等,在 RFC 文档中规定的状态码是三位数,所以可用值为 000 到 999,但实际上,RFC 把状态码分成了五类,用数字的第一位表示分类,而且仅仅只明确定义了41个状态码。状态码分类如下:

状态码分 类 取值范围 说明
1** 100 -199 提示信息,表示服务器收到请求,目前是协议处理的中间状态,需要客户端继续执行操作
2** 200 -299 成功,报文已经收到并被正确处理
3** 300 -399 重定向,资源位置发生变动,需要客户端重新发送请求
4** 400 -499 客户端错误,请求报文有误,服务器无法处理
5** 500 -599 服务器错误,服务器在处理请求时内部发生了错误

常用状态码:

状 态 码 状态短语 说明
200 OK 请求成功,一般用于GET与POST请求
301 MovedPermanently 永久重定向,客户端请求的资源被移动到新的URL,返回信息中包含新的URL,客户端自动请求
302 Found 临时重定向,其它与301相同
304 Not Modified 自上次访问以来,该资源没有发生更改,客户端直接使用本地缓存
400 Bad Request 客户端请求的语法错误,服务器无法理解,此状态码是一个通用错误码,并不能准确描述错误
401 Unauthorized 请求要求用户的身份认证
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求,原因有多样,通常是没有权限
404 Not Found 服务器上没有找到客户端需要访问的资源
500 Internal Server Error 服务器内部错误,无法完成请求
502 Bad Gateway 服务端网关错误
503 Service Unavailable 服务器当前很忙,暂时无法响应请求(网络服务正忙,请稍后重试)
504 Gateway Time-out 服务端网关超时

1.4 前端页面技术

前端页面技术:HTML + CSS + JAVASCRIPT

HTML:(Hyper Text Markup Language),超文本标记语言。

HTML 是由 Tim Berners-Lee 和同事 Daniel W. Connolly 于1990年创立的一种标记语言,它是标准通用化标记语言SGML的应用。用HTML 编写的超文本文档称为HTML文档,它能独立于各种操作系统平台(如UNIX, Windows等),使用 HTML 将所需要表达的信息按某种规则写成 HTML 文件,通过浏览器解析,就是我们所见到的网页。

CSS:(Cascading Style Sheets),层叠样式表。

CSS 定义了如何显示(装扮) HTML 元素,比如:字体大小和颜色属性等。样式通常保存在外部的 .css文件中,用于存放一些HTML文件的公共属性,从而通过仅编辑一个简单的 CSS 文档,可以同时改变站点中所有页面的布局和外观。

JS:(Javascript)

JavaScript 是一种属于网络的高级脚本语言,已经被广泛用于 Web 应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。

1.5 静态资源和动态资源

客户端通过 URL定位服务端的资源,WEB SERVER 服务将该资源返回给客户端,资源可以分为静态资源和动态资源两类,在 Web 服务中,静态资源和动态资源是根据其内容和生成方式来定义的,它们在处理和提供方式上有一些显著的区别:

静态资源

静态资源是指在服务器上事先存在,不需要在请求时进行动态生成的文件,这些文件包括HTML、CSS、JavaScript、图像(如 JPEG、PNG)等。

静态资源是直接从服务器上的文件系统提供的,没有经过服务器端的处理或计算,它们的内容在创建时已经确定,不会根据每个请求而变化。

静态资源适用于那些内容较为固定,不经常变化的情况,它们可以被直接缓存,以提高访问速度,并减轻服务器的负载。

动态资源

定义:动态资源是在服务器上根据用户请求动态生成的内容。这通常涉及到使用服务器端脚本(如PHP、Python、Node.js)进行处理,并根据用户请求的参数生成不同的内容。

动态资源的内容在请求时动态生成,可能涉及到数据库查询、计算或其他与用户请求相关的操作,每次请求可能产生不同的结果。

动态资源适用于需要根据用户输入或其他动态条件生成内容的情况。它们通常涉及更多的计算和服务器端的处理,可能会引起更高的服务器负载。

静态资源适用于内容较为固定、不经常变化的场景,因此更容易被缓存。而动态资源适用于需要根据用户请求生成不同内容的情况。

在实际的 Web 应用中,通常会同时使用静态资源和动态资源,以充分利用它们各自的优势,例如,静态资源可以用于提供页面的基本框架、样式和脚本,而动态资源可以用于提供个性化的、与用户交互的内容。

#动静态资源示例
<!DOCTYPE html>
<html>
<head>
    <title>日期显示示例</title>
</head>
<body>
    <!-- 服务器时间(PHP生成) -->
    <p>服务器时间: <?php echo date('Y-m-d H:i:s'); ?></p>
    <script type="text/javascript">
        // 客户端时间(JavaScript生成)
        alert("hello world");
        var currentDate = new Date();
        var year = currentDate.getFullYear();
        var month = (currentDate.getMonth() + 1).toString().padStart(2, '0');
        var day = currentDate.getDate().toString().padStart(2, '0');
        var hours = currentDate.getHours().toString().padStart(2, '0');
        var minutes = currentDate.getMinutes().toString().padStart(2, '0');
        var seconds = currentDate.getSeconds().toString().padStart(2, '0');
        
        var formattedDateTime = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
        console.log(formattedDateTime);
        
        // 在页面上显示客户端时间
        document.write("客户端时间: " + formattedDateTime);
    </script>
</body>
</html>

1.6 cookie和session

HTTP 是一种无状态协议,这意味着每个HTTP请求都是相互独立的,服务器在处理请求时不会保留先前请求的任何状态信息,每个请求都是独立的、不相关的操作。

这无状态的特性有助于简化协议的设计和实现,同时也使得它更具可伸缩性,每个请求都包含所有必要的信息,而服务器无需维护每个客户端的状态,从而降低了服务器的负担。

如果客户端需要在多次请求之间保持状态,通常会使用一些机制,如Cookie或Session。Cookies 和 Sessions 都是用于在Web应用程序中管理用户状态的机制,它们的作用主要涉及用户身份验证、跟踪会话信息以及存储用户偏好等。

Cookie

Cookie 是一小段存储在用户计算机上的数据,由服务器通过 HTTP 协议发送给用户的浏览器,然后浏览器将其保存。每次用户访问同一站点时,浏览器都会将相应的 Cookie 发送回服务器,从而实现在客户端和服务器之间存储和传递信息的功能。Cookies 通常包含一些键值对,用于存储少量文本数据,例如用户的身份认证信息、首选语言、个性化设置等。

Session

Session 是服务器端的一种机制,用于在用户和服务器之间存储信息。与 Cookie 不同,Session 数据并不直接存储在用户计算机上,而是存储在服务器上。通常,服务器会为每个用户创建一个唯一的会话标识符(Session ID),该标识符通过 Cookie 或者 URL 参数的形式发送给用户。在服务器端,与每个会话相关的数据都会被存储,这样在用户的不同请求之间可以保持状态。 Sessions 通常用于存储用户的登录状态、购物车内容、权限信息等。

Cookie 和 Session 的经典使用场景:

image-20250903225641287

1. 客户端使用用户名和密码登录网站。
2. 服务端在验证客户端登录凭证后,生成当前用户唯一的 session 数据保存在服务端,并将该session id 下发给客户端。
3. 客户端接收到会话ID后保存在本地的Cookie 中,下次刷新页面,会将该会话ID发送到服务端,服务端验证SESSION 信息,从而显示该客户端的登录状态。

session 共享和 session 复制:

session 是以文件的形式保存在服务器中的,在只有一台 WEB 服务器的情况下,这种方式没有任何问题,但是如果在负载均衡场景下,session 文件只存在于后端某一台服务器上,如果客户端请求被负载到其它服务器上,那么,该客户端的状态就无法维持。

session 共享是指 session 不再只存在某一台服务器上,而是放在某个共享存储中,后端服务器共用所有的 session 信息,session 共享可以用 NFS,MYSQL,REDIS 等方式实现。

session 复制是指当后端某台主机上对 cookie 数据产生了写操作(包括新增,修改,删除等),然后将修改后的数据同步到该集群中其它 WEB 服务器上,保证所有 WEB 服务器上都有全量且状态统一的session 数据,那么,无论将客户端请求调度到任何一台 WEB 服务器上,该服务器上都有 session 数据。

1.7 网站流量指标

网站流量指标是常用来对网站效果进行评价,主要指标包括独立访问者数量、重复访问者数量、页面浏览数、每个访问者的页面浏览数和某些具体文件或页面的统计指标。

UV:(unique visitors),独立访客量,独立访客的计算通常基于Cookie技术。当用户首次访问网站时,服务器会在用户的浏览器上设置一个独特的Cookie,以标识该用户。在随后的访问中,服务器会检查这个Cookie,以确定用户是否为独立访客。需要注意的是,由于用户可能会清除Cookie或使用隐私模式浏览,因此独立访客的数量可能会受到一定影响。

PV:(page views),页面浏览数量,网站点击量,访客每打开一个页面或刷新一次页面都计算一次。

IP:独立IP数量,一天内来自相同IP地址的客户端的访问只计算一次,是衡量网站流量的重要指标。

2、IO模型

2.1 什么是I/O

IO 的全称是 Input‑Output(输入 / 输出),所有应用程序与外部硬件设备之间发生的数据读取、写入、传输等数据交互行为,统称为 IO

常见的外部设备包含固态硬盘、机械硬盘、网卡、键盘、显示器、麦克风等;读取磁盘文件、接收浏览器网络请求、屏幕打印文字等都属于 I/O 行为。

真正要实现对磁盘的读取或者写入是应用程序去完成的,但是应用程序是不能直接进行一些读写操作的,应用程序的读写操作需要交给操作系统内核的系统调用函数。也就是说应用程序要读写数据,只能通过调用操作系统开放出来的API来操作。

应用程序发起的一次I/O操作包含两个阶段:

  • IO调用:应用程序进程向操作系统内核发起调用,向操作系统内核提交读写任务。

  • IO执行:操作系统内核完成I/O操作。

操作系统内核完成IO操作还包括两个过程:

  • 准备数据阶段:内核等待IO设备准备好数据。

  • 拷贝数据阶段:将数据从内核缓冲区拷贝到用户进程缓冲区,然后应用程序就能够读取和处理数据了。

linux操作系统为了保证系统的稳定性和安全性,将内存空间分为两部分:

以32位操作系统为例,它为每一个进程都分配了4G(2的32次方)的内存空间。这4G可访问的内存空间分为二部分,一部分是用户空间,一部分是内核空间。内核空间是操作系统内核访问的区域,是受保护的内存空间,而用户空间是用户应用程序访问的内存区域。

image-20250905161105472

一个完整的IO过程包括以下几个步骤:

  • 应用程序进程向操作系统发起IO调用。

  • 操作系统内核中的相应硬件驱动下发指令给磁盘或者网卡,将硬件中的数据加载到内核缓冲区。

  • 操作系统内核将内核缓冲区的数据拷贝到用户进程缓冲区。

  • 至此应用程序可以正常读取、处理缓冲区中的数据。

2.2 web请求处理过程

web服务端处理客户端浏览器请求的I/O过程如下:

image-20250905204019571

  1. 客户端发送请求,服务器网卡接收请求。

  2. 服务器将请求数据从网卡缓冲区拷贝到内核缓冲区,这一步由硬件通过DMA(直接内存访问)直接完成。

  3. 操作系统将请求数据从内核缓冲区拷贝到用户空间的WEB服务器缓冲空间。

  4. web服务根据用户请求,向内核发起系统调用,申请获取相应资源(例如:客户端获取图片,图片存储在硬盘)。

  5. 内核发现web服务器进程请求的是一个存放在本地硬盘上的资源,使用DMA将数据拷贝至内核缓冲区。

  6. 操作系统将内核缓冲区的数据复制到用户空间的web服务器内存空间。

  7. 用户空间WEB服务进程构建响应数据。

  8. 操作系统将响应数据从WEB服务器缓冲区拷贝到内核缓冲区。

  9. DMA将内核缓冲区的响应数据发送给网卡。

  10. 网卡返回响应数据给客户端。

DMA:(Direct Memory Access),直接内存访问,是一些计算机总线架构提供的功能,它能使数据从附加设备(如磁盘驱动器)直接发送到计算机主板的内存上 。

通过上面完整的 Web 请求‑响应流程能够看出:普通 IO 模式下,硬盘读取出来的静态文件数据,必须拷贝至 Web 进程的用户空间缓冲区中转,后续还需要再次拷贝回内核缓冲区。整个过程产生多次 CPU 内存拷贝、多次用户态‑内核态上下文切换;CPU 被迫耗费算力搬运大块内存数据,会拖垮服务器并发吞吐能力。为了解决该 IO 性能瓶颈,出现了零拷贝 (Zero‑Copy) 技术。

零拷贝(Zero‑Copy)本质含义:减少甚至消除 CPU 在「内核缓冲区 ↔ 用户缓冲区」之间的数据复制

Nginx 依托 sendfile 系统调用实现零拷贝,数据自硬盘载入内核缓存之后便不再拷贝至进程用户空间,直接由内核空间交付网卡。

2.3 I/O模型相关概念

阻塞/非阻塞:调用者在等待结果返回之前所处的状态。

阻塞: blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。

非阻塞: nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

image-20250905211853680

同步/异步:调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知,关注的是消息通信机制。

同步: synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成。

异步: asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态。

image-20250905211733641

2.4、五种IO模型

2.4.1 阻塞IO模型

阻塞IO模型,简称BIO,Blocking IO。

假设应用程序的进程发起IO调用,但是如果内核的数据还没准备好的话,那应用程序进程就一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示,此次IO操作,称之为阻塞IO。

image-20250905212620373

阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞。 用户线程通过系统调用 read 发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成 read 操作,用户线程需要等待 read 将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源。 缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大。

2.4.2 非阻塞型IO模型

非阻塞IO模型,简称NIO,Non-Blocking IO。

当用户线程发起IO请求时 ,如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求。

image-20250905213256616

非阻塞IO的流程如下:

  • 应用进程向操作系统内核,发起recvfrom读取数据。

  • 操作系统内核数据没有准备好,立即返回EWOULDBLOCK错误码。

  • 应用程序进程轮询调用,继续向操作系统内核发起recvfrom读取数据。

  • 操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间。

  • 完成调用,返回成功提示。

轮询机制存在两个问题:

如果有大量文件描述符都要等,那么就得一个一个的 read。这会带来大量的 Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。

轮询的时间不好把握,这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

3.3 多路复用IO

多路复用IO之select

应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据。

image-20250905214121809

但是呢,select有几个缺点:

  • 监听的IO最大连接数有限,在Linux系统上一般为1024。

  • select函数通过不断轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

因为存在连接数限制,所以后来又提出了poll。与select相比,poll解决了连接数限制问题。但是呢,select和poll一样,还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,效率也会线性下降。因此经典的多路复用模型epoll诞生。

多路复用IO之epoll

为了解决select/poll存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现,流程图如下:

image-20250905214900850

epoll先通过epoll_ctl()来注册一个fd(文件描述符),一旦某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这里去掉了遍历文件描述符的操作,而是采用监听事件回调的机制。这就是epoll的亮点。

3.4 信号驱动IO

信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。

image-20250905215314866

信号驱动IO模型,在应用进程发出信号后,是立即返回的,不会阻塞进程。它已经有异步操作的感觉了。但是你细看上面的流程图,发现数据复制到应用缓冲的时候,应用进程还是阻塞的。回过头来看下,不管是BIO,还是NIO,还是信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的。

缺点:信号 IO 在大量 IO 操作时可能会因为信号队列溢出导致没法通知。

3.5 异步IO

前面讲的BIO,NIO和信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的,因此都不算是真正的异步。AIO(Asynchronous I/O)实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。

image-20250905220216152

要实现真正的异步 IO,操作系统需要做大量的工作,目前 Windows 下通过 IOCP 实现了真正的异步 IO,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时以 IO 复用模型模式 + 多线程任务的架构基本可以满足需求。

3.6 IO模型对比

上述五种 IO 模型中,越往后,阻塞越少,理论上效率也更好。

image-20250905223838345

3、常用的web服务器

Web服务器是提供Web信息服务的软件,它通过HTTP或HTTPS协议与客户端通信,接受客户端请求,处理请求,然后返回响应数据,Web 服务器的主要工作是通过存储、处理和交付网页给用户来显示网站内容,一个成熟的WEB服务器软件不仅仅只是处理客户端请求,还要有良好的安全性和稳定性,以满足用户不断变化和增长的需求。

各个web服务器市场占有率:

Netcraft公司于1994年底在英国成立,多年来一直致力于互联网市场以及在线安全方面的咨询服务,其中在国际上最具影响力的当属其针对网站服务器,域名解析/主机提供商,以及SSL市场所做的客观严谨的分析研究。

Resources | Netcraft

以下是一些主流的Web服务器以及它们的特点,这些Web服务器都有各自特点和优势,在使用的时候,要取决于项目需求,性能要求及开发人员偏好等。

Apache

image-20250908162218758

网站:https://httpd.apache.org/

Apache 是目前市场占有率较高的老牌WEB服务器,它免费开源,功能强大,支持多种操作系统,可在多平台上运行,包括Unix、Linux、Windows等,同时具有强大的模块化体系结构,提供了丰富的模块,也支持许多第三方模块,允许用户自定义服务器功能,另外也支持虚拟主机配置。

Nginx

image-20250908161715774

网站:nginx

Nginx是一个高性能的Web服务器,广泛应用于高并发、大流量的互联网应用场景中,Nginx还可以作为反向代理服务器、负载均衡服务器,其优异的静态处理能力,使其在处理静态文件时具有很高的效率,由于选择了高效的网络IO模型,使其在高并发大流量的工作场景下,对于资源(CPU,内存等)的要求非常低,且运行非常稳定。

Tomcat

image-20250908162049254

网址:

https://tomcat.apache.org/

Apache‑Tomcat 为开源的 Java Web 容器,兼具 Web 服务功能,主要负责运行 Servlet 与 JSP 程序;相较于 Nginx 这类事件驱动型网页服务器,它处理静态资源以及应对海量并发连接的性能较差。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐