node高并发原理机制

概念

  1. 事件循环:
    事件循环是一种编程构造,用于等待和分派程序中的事件或消息, 主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
  2. 事件队列:
    当用户的网络请求或者其它的异步操作到来时,node都会把它放到Event Queue之中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕。
  3. 任务队列:
    任务队列"是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
  4. 事件驱动:
    实质是通过主循环加事件触发方式运行程序
  5. node
    Node.js 不是一门语言也不是框架,它只是基于 Google V8 引擎的 JavaScript 运行时环境,是对 js 功能的拓展。提供了网络、文件、dns 解析、进程线程等功能。
  6. libuv
    libuv是专门为Node.js开发的一个封装库,提供跨平台的异步I/O能力。

注:
1. 一个事件循环有一个或多个任务队列。一个任务队列是一组的任务
2. Libuv 主要是,利用系统提供的事件驱动模块解决网络异步 IO,利用线程池解决文件IO。另外还实现了定时器,对进程、线程等使用进行了封装。

node架构图

在这里插入图片描述

  1. Node Standard Library 标准库,如Http, event模块。
  2. Node Bindings 是沟通JS 和 C++的桥梁,封装V8和Libuv的细节,向上层提供基础API服务。由 C/C++ 实现。
  3. V8 是Google开发的JavaScript引擎,提供JavaScript运行环境,可以说它就是 Node.js 的发动机。
  4. Libuv 是专门为Node.js开发的一个封装库,提供跨平台的异步I/O能力.

单线程、异步

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。node单线程指的是node在执行程序代码时,主线程是单线程。

异步体现在,主线程之外,还维护了一个"事件队列"(Event queue)。当用户的网络请求或者其它的异步操作到来时,node都会把它放到Event Queue之中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕.
注:

  1. JavaScript 是单线程的,Node 本身其实是多线程的,只是 I/O 线程使用的 CPU 比较少;还有个重要的观点是,除了用户的代码无法并行执行外,所有的 I/O (磁盘 I/O 和网络 I/O) 则是可以并行起来的。
  2. libuv 线程池默认打开 4 个,最多打开 128个 线程。

事件循环

Node 开始执行脚本时,会先进行事件循环的初始化,但是这时事件循环还没有开始,会先完成下面的事情。
● 同步任务
● 发出异步请求
● 规划定时器生效的时间
● 执行process.nextTick()等
然后就调用libuv事件循环阶段,事件循环会无限次地执行,一轮又一轮。只有异步任务的回调函数队列清空了,才会停止执行。

Node中的事件循环有6个阶段
event loop 的每个阶段都有一个任务队列
当 event loop 到达某个阶段时,将执行该阶段的任务队列,直到队列清空或执行的回调达到系统上限后,才会转入下一个阶段
当所有阶段被顺序执行一次后,称 event loop 完成了一个 tick
在这里插入图片描述
注:
node中的事件循环与浏览器有区别~

事件驱动+事件循环实现高并发

具体执行顺序:
1、每个Node.js进程只有一个主线程在执行程序代码,形成一个执行栈(execution context stack)
2、主线程之外,还维护了一个"事件队列"(Event queue)。当用户的网络请求或者其它的异步操作到来时,node都会把它放到Event Queue之中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕。
3、主线程代码执行完毕完成后,然后通过Event Loop,也就是事件循环机制,开始到Event Queue的开头取出第一个事件,从线程池中分配一个线程去执行这个事件,接下来继续取出第二个事件,再从线程池中分配一个线程去执行,然后第三个,第四个。主线程不断的检查事件队列中是否有未执行的事件,直到事件队列中所有事件都执行完了,此后每当有新的事件加入到事件队列中,都会通知主线程按顺序取出交EventLoop处理。当有事件执行完毕后,会通知主线程,主线程执行回调,线程归还给线程池。

总线程不断重复第三步
在这里插入图片描述
注意
我们所看到的node.js单线程只是一个js主线程与ui渲染共享一个线程,本质上的异步操作还是由线程池完成的,node将所有的阻塞操作都交给了内部的线程池去实现,本身只负责不断的往返调度,并没有进行真正的I/O操作,从而实现异步非阻塞I/O,这便是node单线程和事件驱动的精髓之处了

总结:

  1. libuv 线程池默认打开 4 个,最多打开 128个 线程。(例如:以前 web 服务器同一时间比如说最多只能接收 100 个请求,多的就无法接收了。nodejs 所谓的高并发是指可以同时接收 1000、10000 个请求,只不过以排队的方式在等待。)
  2. 主线程执行js,是单线程的,js代码在做大量计算就是cpu密集了。主线程不空闲出来也没法处理 io 的事,所以就会阻塞了。
  3. 回调只能保证某个请求按照顺序执行,不能保证多个请求访问一个资源的先后顺序,多个请求访问一个资源是要加锁的,用事务加锁就行。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js 是一个基于事件驱动的 JavaScript 运行环境。它的事件驱动机制基于观察者模式和回调函数。 事件驱动的原理是,Node.js 在执行过程中会不断地监听各种事件,当某个事件发生时,Node.js 会触发相应的回调函数来处理事件。这种机制使得 Node.js 能够高效地处理大量并发请求。 具体来说,Node.js 的事件驱动原理包括以下几个关键组件: 1. 事件循环(Event Loop):Node.js 在单线程中运行,它的事件循环负责监听和分发事件。事件循环会不断地从事件队列中取出事件,并将事件分发给对应的回调函数进行处理。 2. 事件队列(Event Queue):事件队列是用来存储待处理的事件的队列。当某个事件触发时,相关的回调函数会被添加到事件队列中等待执行。 3. 观察者(Observer):观察者是用来监听特定类型事件的对象。在 Node.js 中,观察者可以是内部的模块、外部的库或用户自定义的对象。当某个观察者监听到特定类型的事件时,它会将对应的回调函数添加到事件队列中。 4. 回调函数(Callback):回调函数是在特定事件发生时被执行的函数。它是异步编程的核心机制,在 Node.js 中广泛使用。当某个事件触发时,事件循环会从事件队列中取出对应的回调函数,并执行它。 总的来说,Node.js 的事件驱动机制基于事件循环、事件队列、观察者和回调函数的组合。通过这种机制Node.js 能够高效地处理并发请求,提供高性能的网络服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值