kaolalicai
V2EX  ›  Node.js

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

  •  
  •   kaolalicai · Aug 31, 2018 · 3648 views
    This topic created in 2814 days ago, the information mentioned may be changed or developed.

    前言

    上回书说到 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-并发模型
    著作权归本文作者所有,未经授权,请勿转载,谢谢。

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1393 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 415ms · UTC 17:14 · PVG 01:14 · LAX 10:14 · JFK 13:14
    ♥ Do have faith in what you're doing.