V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kaolalicai
V2EX  ›  Node.js

AI 考拉技术分享会--Node.js 并发模型

  •  
  •   kaolalicai · 2018-08-31 11:28:31 +08:00 · 3141 次点击
    这是一个创建于 2305 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    上回书说到 Node.js 内存模型的相关内容,这次,我们往 node 的另一模型,并发模型进行分享,考拉技术小哥哥 Nick 结合了网红奶茶一点点的例子,给大家带来一场视觉与味觉的盛宴。

    并发模型是什么

    首先,什么是并发?

    并发是指程序可以同时处理多个任务,是一个 web 服务必备的能力。

    自从 Nodejs 出现后,js 开始涉及后端领域,因为其出色的并发模型,被很多企业用来处理高并发请求,例如淘宝已经大量使用 node 处理中间层业务。

    接下来本文就分析一下 js 的并发模型,来理解 node 相对于其他语言的优势以及其最合适的应用场景。

    tips:并发和并行区别 并发与并行区别.png

    异步 IO

    什么是异步 IO ? 异步 IO 具体是如何实现的呢? 异步和同步有什么区别呢? 异步就不阻塞吗? IO 阻塞又是什么概念呢? 带着这些问题,我们慢慢分析。

    IO 模型

    《 UNIX 网络编程:卷一》第六章—— I/O 复用。书中向我们提及了 5 种类 UNIX 下可用的 I/O 模型:

    • 阻塞式 I/O ;
    • 非阻塞式 I/O ;
    • I/O 复用( select,poll,epoll...);
    • 信号驱动式 I/O ( SIGIO );
    • 异步 I/O ( POSIX 的 aio_系列函数);

    IO 模型.png

    总结一下阻塞,非阻塞,同步,异步:

    • 阻塞,非阻塞:进程 /线程要访问的数据是否就绪,进程 /线程是否需要等待;
    • 同步,异步:访问数据的方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要 I/O 操作完成的通知,并不主动读写数据,由操作系统内核完成数据的读写。

    说人话

    上面的解释太复杂我看不懂怎么办?我们把上文说到 IO 代入到生活的场景中,考虑到我们公司很多人喜欢买一点点饮料,就以买饮料为例,将四种常见 IO 模型转换为对应的买饮料流程。下面是一下设定:

    • 把买一杯一点点的流程简化为两步:下单制作和拿一点点回公司
    • 公司员工 === 线程
    • 下单制作 === 发起 IO 请求
    • 拿一点点回公司 === 读取数据

    IO 模型时序图.png

    异步 IO 的特点就是把 IO 处理的事情都交给了操作系统(美团外卖),这样线程就不会被 IO 阻塞,可以继续处理其他请求

    Node 的异步 IO

    Node.js 的异步 IO 由 Libuv 这个库提供实现,Libuv 是 Node.js 关键的一个组成部分,它为上层的 Node.js 提供了统一的 API 调用,使其不用考虑平台差距,隐藏了底层实现。 node.png

    可以看出,它提供了非阻塞的网络 I/O,异步文件系统访问等功能,而且右下角居然还有个线程池,实际上 Libuv 收到的 IO 请求是同个多线程来实现的, 看来 Node 只是在程序层面单线程而已

    事件循环

    任务队列

    先看看 Node.js 结构

    node 结构.png

    根据上图,Node.js 的运行机制如下。

    ( 1 ) V8 引擎解析 JavaScript 脚本;

    ( 2 )解析后的代码,调用 Node API ;

    ( 3 ) libuv 库负责 Node API 的执行。它将不同的任务分配给不同的线程,形成一个 Event Loop (事件循环),以异步的方式将任务的执行结果返回给 V8 引擎( callback 处理结果);

    ( 4 ) V8 引擎再将结果返回给用户。

    异步操作都会被压入任务队列,当任务队列为空的时候,程序退出。

    总结

    Libuv 使用异步 IO + 线程池实现的事件循环处理机制提供的高效的 IO 处理,是 Node 能承担高并发请求的主要原因

    参考文章与书籍

    1. 《深入浅出 Node.js 》

    2. 《 Unix 网络编程》

    3. 《七周七并发模型》

    4. 并发与并行的区别

    5. JavaScript 运行机制详解:再谈 Event Loop

    6. 怎样理解阻塞非阻塞与同步异步的区别? - 大姚的回答 - 知乎

    7. Node.js 探秘:初识单线程的 Node.js

    8. Linux IO 模式及 select、poll、epoll 详解


    Nick 小哥哥将内容整理到自己的博客中,欢迎大家前往学习交流:node-js-并发模型
    著作权归本文作者所有,未经授权,请勿转载,谢谢。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   874 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:16 · PVG 06:16 · LAX 14:16 · JFK 17:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.