一、HTTP协议和Nginx
1.套接字Socket
套接字Socket是进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换,SocketAPI出现于1983年BSD4.2实现在建立通信连接的每一端,进程间的传输要有两个标志:IP地址和端口号,合称为套接字地址 socket address
1.客户机套接字地址定义了一个唯一的客户进程
2.服务器套接字地址定义了一个唯一的服务器进程
套接字的系统调用:
socket() | 创建一个套接字 |
bind() | 绑定IP和端口 |
listen() | 监听 |
accept() | 接收请求 |
connect() | 请求连接建立 |
write() | 发送 |
read() | 接收 |
close() | 关闭连接 |
2.URI
URI(Uniform Resource Identifier ):统一资源标识,分为URL和URN
1.URL
URL是统一资源定位符,用于描述某服务器某特定资源位置
2.URN
URN是统一资源命名
3.URL和URN的区别
URN如同一个人的名称,而URL代表一个人的住址。URN定义某事物的身份,而URL提供查找该事物的方法,URN仅用于命名而不指定地址
4.URL的组成
scheme | 方案,访问服务器以获取资源时要使用哪种协议 |
user | 用户,某些方案访问资源时需要的用户名 |
password | 密码,用户对应的密码,中间用:分隔 |
Host | 主机,资源宿主服务器的主机名或IP地址 |
port | 端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号 |
path | 路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔 |
params | 参数,指定输入的参数,参数为名/值对,多个参数,用;分隔 |
query | 查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔 |
frag | 片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔 |
3.请求访问的完整过程
当用户发起http请求 需要请求index.html网页文件
客户端请求和服务器端建立连接,建立连接后,客户端发送请求报文
服务端网卡收到请求报文,将该报文复制到内核空间(操作系统),内核空间分析报文后交给对应的程序
nginx分析该报文,对比报文和自己的配置文件,按照配置文件完成请求,分析完成后,发现客户需要index.html文件
由于程序的权限问题,没有资格直接调用磁盘上的文件,程序会再将这个请求,再次转发给内核
内核得到请求后,去磁盘中寻找目标文件,找到文件后,复制给程序
程序构建响应报文,构建好后交给内核空间内核空间得到响应报文后,再交给网卡,发给客户
二、I/O模型处理高并发的时候用
1.I/O模型
同步/异步(消息反馈机制):关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知
同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态
同步阻塞:nginx需要自己去问内核是否完成了我交代的任务,而且在接待了一个请求后只有等这个请求结束后才能继续下一个请求
同步非阻塞:指IO操作被调用后立刻告诉内核是否完成了我交代的任务,无需等待IO操作彻底完成,在最终的结果返回前,调用者不会被挂起,可以去做别的事情
2.多路复用I/O型
多路复用I/O模型是一种基于事件驱动的 I/O 处理模式,它利用操作系统提供的多路复用机制(如select、poll、epoll等)来同时监听多个 I/O 事件,当某个事件就绪时,通知应用程序进行处理,通过多路复用I/O模型,可以在一个线程中同时处理多个客户端连接的 I/O 操作,而不需要为每个连接创建一个线程或进程,避免了资源开销和上下文切换的成本。
常见的多路复用I/O模型有:
1.select:适用于连接数不太多的情况,轮询监听多个文件描述符上的 I/O 事件。
2.poll:与select类似,但没有连接数的限制,并且不会修改传入的描述符集合。
3.epoll:适用于连接数非常多的情况,通过事件驱动机制来处理 I/O 事件,可以在大并发情况下具有较高的性能优势。
3.异步I/O模型
异步 I/O 模型是一种非阻塞的 I/O 处理模式,通过回调函数或事件通知的方式来处理已完成的 I/O 操作,能够提高系统的并发性和处理效率
4.事件模型select poll epoll
1.Nginx服务使用异步非阻塞模式:请求不需要排队,会反馈任务的完成结果
2.Apache服务使用同步阻塞模式:请求需要排队,且不会主动返回结果
模型 | 描述 | 优点 | 缺点 |
select | 最古老的模型 | 可以同时监视多个文件描述符 | 效率较低,不适用于大规模并发连接 |
poll | 类似于select | 效率相对更高,可以处理大量并发连接 | 随着文件描述符数量的增加,性能下降较明显 |
epoll | Linux特有模型 | 在高并发场景下性能表现更好,使用边缘触发方式,只在状态变化时通知 | 在非Linux系统上不可用,涉及到一些操作系统特定的细节和配置 |
模型区别 | select | poll | epoll |
操作方式 | 遍历 | 遍历 | 回调 |
底层实现 | 数组 | 链表 | hash表 |
IO效率 | 每次调用都进行线性遍历,时间复杂度为0(n) | 每次调用都进行线性遍历,时间复杂度为0(n) | 事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪的fd放到rdlllist里,时间复杂度O(1) |
IO效率 | 1024(x86)2048(x64) | 无上限 | 无上限 |
fd拷贝 | 每次调用select都需要把fd集合从用户拷贝到内核态 | 每次调用poll,都需要把fd集合从用户态拷贝到内核态 | 调用epoll ctl时拷贝进内核并保存,之后每次epoll wait不拷贝 |