AI 考拉技术分享会--Node.js 并发模型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kaolalicai

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

  •  
  •   kaolalicai 2018 年 8 月 31 日 3615 次点击
    这是一个创建于 2793 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    上回书说到 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     Solana     1581 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 58ms UTC 16:39 PVG 00:39 LAX 09:39 JFK 12:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86