大前端

前端学习之家-大前端

高并发IO底层原理

目录

一、基础知识

1.用户态和内核态

2.系统调用流程图

二、四种主要IO模型

1.同步阻塞IO(Blocking IO)

2.同步非阻塞(Non-BlockingIO, NIO)

3.IO多路复用

4.异步IO

三、支持百万级并发连接的Linux系统配置


一、基础知识

应用程序的IO操作实际上不是物理设备级别的读写,而是缓存的复制。

应用程序的IO = socket IO + 文件IO,在内核缓存区和进程缓冲区进行数据交换。

数据在内核缓冲区和读写设备(网卡、磁盘)之间的交换是由操作系统内核完成的。

1.用户态和内核态

操作系统虚拟内存 = 内核空间+用户空间

用户态进程通过系统调用,让内核态进程完成调用系统资源之类的操作。

2.系统调用流程图

二、四种主要IO模型

阻塞:用户程序(发起IO请求的进程或线程)的执行状态,java 默认创建的socket是阻塞IO。

同步:用户空间主动发起IO请求。

异步:系统内核主动发起IO请求。

1.同步阻塞IO(Blocking IO)

用户空间主动发起,需要等待内核IO操作彻底完成才能返回用户空间的IO操作。在IO操作过程中,发起IO请求的用户进程或线程处于阻塞状态。

2.同步非阻塞(Non-BlockingIO, NIO)

用户空间的程序不需要等待内核IO操作彻底完成,发起IO请求后获得内核返回的状态值,就可以立即返回用户空间去执行后续指令。在IO操作过程中,发起IO请求的用户进程或线程处于非阻塞状态。

注:在Java中,把socket设置为NONBLOCK模式就是非阻塞IO。和Java的NIO不同,Java的NIO组件是基于操作系统的IO多路复用实现的。

3.IO多路复用

支持IO多路复用基于操作系统的IO操作的系统调用和select/epoll就绪查询系统调用。单个应用程序或者线程可以轮询成百上千个socket连接的就绪状态,当某个socket网络连接有IO就绪状态时就可以根据socket连接发起的read系统调用,用户线程进入阻塞状态,内核开始将数据从内核缓冲区复制到用户缓冲区,复制完成后,内核返回结果,用户线程解除阻塞读到数据,继续执行。

4.异步IO

用户线程通过系统调用向内核注册某个IO操作,内核在整个IO操作(包括数据准备、数据复制)完成后通知用户程序,用户执行后续的业务操作。在内核处理数据的过程中(包括将数据从网卡读到内核缓冲区,将内核缓冲区数据复制到用户缓冲区),用户程序都不需要阻塞。

异步IO需要操作系统内核提供支持,windows通过IOCP实现了真正的异步IO,Linux2.6也支持异步IO,但是JDK目前还不完善,Java的高并发网络应用程序大多采用的IO多路复用模型实现的,Netty框架就是。

三、支持百万级并发连接的Linux系统配置

root用户下执行“ulimit -n 1000000”命令,表示可以打开百万个文件句柄,默认时1024。只在当前用户环境下有效,断开用户会话或者用户退出linux,则变回默认值1024。

永久修改可编辑/etc/rc.local开机启动文件,添加一行“ulimit -SHn 1000000”。

要彻底解除Linux系统的最大文件打开数量的限制,可编辑/etc/security/limits.conf,加入“soft nofile 1000000 \n hard nofile 1000000", 一般在ElasticSearch和Netty安装的环境中都要这样修改。

发表评论:

Copyright Your WebSite.Some Rights Reserved.