IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 高并发IO底层原理 -> 正文阅读

[系统运维]高并发IO底层原理

IO读写基本原理

为了避免用户进程直接操作内涵,保证内核安全,操作系统将内存(虚拟内存)划分为两部分:

  • 内核空间(Kenel-Snace)
  • 用户空间(User-Space)

在Linux系统中,内核模块运行在内核空间,对应的进程处于内核态:用户程序运行在用户空间,对应的进程处于:用户态。操作系统的核心是内核程序,它独立于普通的应用程序,有权限访问受保护的内核空间和硬件设备,而普通的应用程序并没有这样的权限。内核态进程可以执行任意命令,调用系统的一切资源,而用户态进程只能执行简单的运算不能直接调用系统资源,用户态进程执行系统调用必须通过系统调用(System Call)向内核发出指令,完成调用系统资源之类的操作。

操作系统层面的read系统调用并不是直接从物理设备把数据读取到应用的内存中,write系统调用也不是直接把数据写入物理设备。上层应用无论是调用操作系统的read还是调用操作系统的write,都会涉及缓冲区。具体来说,上层应用通过操作系统的read系统调用把数据从内核缓冲区复制到应用程序的进程缓冲区,通过操作系统的 write系统调用把数据从应用程序的进程缓冲区复制到操作系统的内核缓冲区

应用程序的IO操作实际上不是物理设备级别的读写,而是缓存的复制。read和write两大系统调用都不负责数据在内核缓冲区和物理设备(如磁盘、网卡等)之间的交换。这个底层的读写交换操作是由操作系统内核(Kernel)来完成的。所以,在应用程序中,无论是对socket的IO操作还是对文件的IO操作,都属于上层应用的开发,它们在输入(Input)和输出(Output)维度上的执行流程是类似的,都是在内核缓冲区和进程缓冲区之间进行数据交换。

在这里插入图片描述

  • 客户端发送请求:Java客户端程序通过write系统调用将数据复制到内核缓冲区,Linux内核缓冲区的请求数据通过客户端机器的网卡发送出去。在服务端,这份请求数据会从接收网卡中读取到服务端机器的内核缓冲区。
  • 服务端获取请求:Java服务端程序通过read系统调用从Linux内核缓冲区读取数据,再进入 Java进程缓冲区。
  • 服务端业务处理:Java服务器在自己的用户空间中完成客户端的请求所对应的业务处理
  • 服务端返回数据: Java服务器完成处理后,构建好的响应数据格从用户缓冲区写入内核缓冲区,这里用到的是 write系统调用,操作系统会负责将内核缓冲区的数据发送出去。
  • 发送给客户端:服务端Linux将内核缓冲区的数据写入网卡,网卡通过底层的通讯协议将数据发送给目标客户端。

四种IO模型

同步阻塞IO

在这里插入图片描述

  • 从Java进行IO读后发起read系统调用开始,用户线程就进入阻塞状态。
  • 当系统内核收到read系统调用后就开始准备数据。一开始,数据可能还没到达内核缓冲区(例如,还没有收到一个完整的 socket数据包),这时内核就要等待。
  • 内核一直等到完整的数据到达,就会将数据从内核缓冲区复制到用户缓冲区(用户空间的内存),然后内核返回结果(例如返回复制到用户缓冲区中的字节数)。
  • 直到内核返回后用户线程才会解除阻塞的状态,重新运行起来。

同步非阻塞IO(Non-Blocking IO, NIO)

Java编程的NIO(NEW IO)类库组件所归属的不是基础IO模型中的NIO,而是IO多路复用

在这里插入图片描述

  • 在内核数据没有准备好的阶段,用户线程发起IO请求时立即返回。所以,为了读取最终的数据,用户进程(或者线程)需要不断地发起IO系统调用。
  • 内核数据到达后,用户进程(或者线程)发起系统调用,用户进程(或者线程)阻塞。内核开始复制数据,它会将数据从内核缓冲区复制到用户缓冲区,然后内核返回结果(例如返回复制到的用户缓冲区的字节数)。
  • 用户进程(或者线程)读到数据后,才会解除阻塞状态,重新运行起来,用户空间需要经过多次尝试才能确保最终真正读到数据

IO多路复用

在这里插入图片描述

  • 选择器注册。首先,将需要read操作的目标文件描述符(socket连接)提前注册到Linux的select/epoll 选择器中,在Java 中所对应的选择器类是 Selector类。然后,开启整个IO多路复用模型的轮询流程。
  • 就绪状态的轮询。通过选择器的查询方法,查询所有提前注册过的目标文件描述符( socket连接)的IO就绪状态。通过查询的系统调用,内核会返回一个就绪的socket列表。当任何一个注册过的socket 中的数据准备好或者就绪了就说明内核缓冲区有数据了,内核将该socket加入就绪的列表中,并且返回就绪事件。
  • 用户线程获得了就绪状态的列表后,根据其中的socket连接发起read系统调用,用户线程阻塞。内核开始复制数据,将数据从内核缓冲区复制到用户缓冲区。
  • 复制完成后,内核返回结果,用户线程才会解除阻寒的状态,用户线程读取到了数据继续执行。

异步IO

在这里插入图片描述

  • 当用户线程发起了read系统调用后,立刻就可以去做其他的事,用户线程不阻塞。
  • 内核开始IO的第一个阶段:准备数据。准备好数据,内核就会将数据从内核缓冲区复制到用户缓冲区。
  • 内核会给用户线程发送一个信号(Signal),或者回调用户线程注册的回调方法,告诉用户线程read系统调用已经完成,数据已经读入用户缓冲区。
  • 用户线程读取用户缓冲区的数据,完成后续的业务操作。
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 19:16:18  更:2022-06-08 19:19:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 2:06:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码