WEB服务
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 的经典使用场景:

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可访问的内存空间分为二部分,一部分是用户空间,一部分是内核空间。内核空间是操作系统内核访问的区域,是受保护的内存空间,而用户空间是用户应用程序访问的内存区域。

一个完整的IO过程包括以下几个步骤:
-
应用程序进程向操作系统发起IO调用。
-
操作系统内核中的相应硬件驱动下发指令给磁盘或者网卡,将硬件中的数据加载到内核缓冲区。
-
操作系统内核将内核缓冲区的数据拷贝到用户进程缓冲区。
-
至此应用程序可以正常读取、处理缓冲区中的数据。
2.2 web请求处理过程
web服务端处理客户端浏览器请求的I/O过程如下:

-
客户端发送请求,服务器网卡接收请求。
-
服务器将请求数据从网卡缓冲区拷贝到内核缓冲区,这一步由硬件通过DMA(直接内存访问)直接完成。
-
操作系统将请求数据从内核缓冲区拷贝到用户空间的WEB服务器缓冲空间。
-
web服务根据用户请求,向内核发起系统调用,申请获取相应资源(例如:客户端获取图片,图片存储在硬盘)。
-
内核发现web服务器进程请求的是一个存放在本地硬盘上的资源,使用DMA将数据拷贝至内核缓冲区。
-
操作系统将内核缓冲区的数据复制到用户空间的web服务器内存空间。
-
用户空间WEB服务进程构建响应数据。
-
操作系统将响应数据从WEB服务器缓冲区拷贝到内核缓冲区。
-
DMA将内核缓冲区的响应数据发送给网卡。
-
网卡返回响应数据给客户端。
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操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

同步/异步:调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知,关注的是消息通信机制。
同步: synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成。
异步: asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态。

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

阻塞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请求时 ,如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求。

非阻塞IO的流程如下:
-
应用进程向操作系统内核,发起recvfrom读取数据。
-
操作系统内核数据没有准备好,立即返回EWOULDBLOCK错误码。
-
应用程序进程轮询调用,继续向操作系统内核发起recvfrom读取数据。
-
操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间。
-
完成调用,返回成功提示。
轮询机制存在两个问题:
如果有大量文件描述符都要等,那么就得一个一个的 read。这会带来大量的 Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。
轮询的时间不好把握,这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。
3.3 多路复用IO
多路复用IO之select
应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据。

但是呢,select有几个缺点:
-
监听的IO最大连接数有限,在Linux系统上一般为1024。
-
select函数通过不断轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
因为存在连接数限制,所以后来又提出了poll。与select相比,poll解决了连接数限制问题。但是呢,select和poll一样,还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,效率也会线性下降。因此经典的多路复用模型epoll诞生。
多路复用IO之epoll
为了解决select/poll存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现,流程图如下:

epoll先通过epoll_ctl()来注册一个fd(文件描述符),一旦某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这里去掉了遍历文件描述符的操作,而是采用监听事件回调的机制。这就是epoll的亮点。
3.4 信号驱动IO
信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。

信号驱动IO模型,在应用进程发出信号后,是立即返回的,不会阻塞进程。它已经有异步操作的感觉了。但是你细看上面的流程图,发现数据复制到应用缓冲的时候,应用进程还是阻塞的。回过头来看下,不管是BIO,还是NIO,还是信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的。
缺点:信号 IO 在大量 IO 操作时可能会因为信号队列溢出导致没法通知。
3.5 异步IO
前面讲的BIO,NIO和信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的,因此都不算是真正的异步。AIO(Asynchronous I/O)实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。

要实现真正的异步 IO,操作系统需要做大量的工作,目前 Windows 下通过 IOCP 实现了真正的异步 IO,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时以 IO 复用模型模式 + 多线程任务的架构基本可以满足需求。
3.6 IO模型对比
上述五种 IO 模型中,越往后,阻塞越少,理论上效率也更好。

3、常用的web服务器
Web服务器是提供Web信息服务的软件,它通过HTTP或HTTPS协议与客户端通信,接受客户端请求,处理请求,然后返回响应数据,Web 服务器的主要工作是通过存储、处理和交付网页给用户来显示网站内容,一个成熟的WEB服务器软件不仅仅只是处理客户端请求,还要有良好的安全性和稳定性,以满足用户不断变化和增长的需求。
各个web服务器市场占有率:
Netcraft公司于1994年底在英国成立,多年来一直致力于互联网市场以及在线安全方面的咨询服务,其中在国际上最具影响力的当属其针对网站服务器,域名解析/主机提供商,以及SSL市场所做的客观严谨的分析研究。
以下是一些主流的Web服务器以及它们的特点,这些Web服务器都有各自特点和优势,在使用的时候,要取决于项目需求,性能要求及开发人员偏好等。
Apache

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

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

网址:
Apache‑Tomcat 为开源的 Java Web 容器,兼具 Web 服务功能,主要负责运行 Servlet 与 JSP 程序;相较于 Nginx 这类事件驱动型网页服务器,它处理静态资源以及应对海量并发连接的性能较差。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)