NodeJs - 单线程模型和高并发处理原理

NodeJs - 单线程模型和高并发处理原理

  • 前言
  • 一. NodeJs 线程模型
    • 1.1 NodeJs 模型分析
    • 1.2 NodeJs处理事件请求的流程
    • 1.3 NodeJs 和传统 Server 的对比
  • 二. Cluster 模块利用多核CPU处理
  • 三. 总结

前言

我们都知道JavaScript是单线程的处理。但是我们在Node开发、Egg开发下,我们的程序又能够处理高并发的请求。明明是单线程却能高并发处理,这是什么原理呢?我们本篇文章来探究一下。

一. NodeJs 线程模型

先分块解答一下 ”单线程“、 ”高并发“ 的含义:

  • 单线程:Node遵循的是单线程单进程的模式。单线程则指的是Js的引擎只有一个实例,它在NodeJs主线程中执行。但是它可以通过事件驱动的方式来处理异步IO操作。
  • 那如何处理高并发的?Node 拥有一个主线程,但是它只负责任务的往返调度,并不会真正执行用户请求等IO操作。而所有的IO操作则交给内部的work线程池去实现。

1.1 NodeJs 模型分析

我们看一下下面一张图:
在这里插入图片描述
首先我们从上图中,将Node模型分成4个功能模块:

  • Application:应用层。即JS的交互层,例如NodeJs中的模块:http、fs等。
  • V8引擎层:解析JS语法,和下层API进行交互。
  • NodeAPI层:为上层模块系统提供系统调用、底层则和操作系统进行交互。
  • LIBUV层:一种跨平台的底层封装。实现事件循环、文件操作等功能,是Node里面实现异步的核心模块。

再来讲一下和上图有关的几个基本概念:

  • 事件循环:事件循环是一种编程构造,用于等待和分派程序中的事件或消息。主线程从 事件队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
  • 事件队列(任务队列):当用户的网络请求或者其它的异步操作到来时,node都会把它放到Event Queue之中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕。
  • 事件驱动:实质是通过主循环加事件触发方式运行程序。

Node.js 不是一门语言也不是框架,它只是基于 Google V8 引擎的 JS 运行时环境,是对 JS 功能的拓展。提供了网络、文件、dns 解析、进程线程等功能。

1.2 NodeJs处理事件请求的流程

结合上文的几个相关概念,流程如下:

  1. Node 主线程接收到了用户的网络请求,会把它丢到Event Queue(事件队列)中,并不会立即执行它。主线程不会阻塞。
  2. Node主线程代码执行完毕,通过Event Loop(事件循环),每次循环都取出队列中的第一个事件,把它丢给LIBUV库的线程池中的线程让它执行,我们这里就叫libuv线程。备注:这个过程中,一旦有新的事件加入到队列中,都会通知主线程去按顺序取出来处理。
  3. libuv线程池的维护则是由底层的LIBUV来完成维护。默认打开4个,最多拥有128个线程。
  4. 当事件执行完毕,就会通知主线程,主线程执行回调拿到结果,libuv线程则归还给线程池,等待下一次调度。

因此对于Node而言,主线程执行JS,这个过程是单线程的。但是可以同时处理大量的IO事件(底层的libuv线程池来完成),非常适合IO密集型的任务处理。相反,若主线程JS进行了CPU密集型,那性能就会非常差,导致长时间的阻塞。

1.3 NodeJs 和传统 Server 的对比

对比项NodeJs传统Server
高并发处理NodeJs只有一个主线程(单线程),但是可以通过底层的LIBUV库中维护的libuv线程池处理高并发请求每个请求都会生成一个线程
内存消耗由于1000个请求是丢到队列当中(并不是立马执行的),排队等待最多128个libuv线程去处理。内存消耗小得多,时间换空间。假设1个进程需要1M内存,为了能同时处理1000个请求,就可能需要1G左右的内存
上下文切换由于单线程,不需要切换例如Java,线程之间需要进行上下文的切换

这么看下来,NodeJs 更像是 ”非阻塞“ 而不是并发。

  1. 再多的请求都是丢到队列,主线程不会受到阻塞。
  2. 主线程通过回调机制来拿到结果,只负责不断的往返调度,从而实现异步非阻塞IO

但是,在我们知道 JavaScript 代码是运行在单线程上后,即一个 Node.js 进程只能运行在一个 CPU 上,那是不是就无法利用到多核运算的好处了?

并不是,NodeJs 官方提供了一种解决方案:cluster 模块。

二. Cluster 模块利用多核CPU处理

官网当中提供了一段简介:

  • 单个 Node.js 实例在单线程环境下运行。为了更好地利用多核环境,用户有时希望启动一批 Node.js 进程用于加载。
  • 集群化模块使得你很方便地创建子进程,以便于在服务端口之间共享。说白了就是多个子进程共享一个端口。

Cluster简单的说就是:

  1. 可以在服务器上同时启动多个进程。
  2. 这些进程同时监听同一个端口。跑的也是同一份源代码。
  3. 有一个专门负责启动其他进程的Master进程(包工头),它只负责启动其他进程。
  4. 而被启动的线程则叫做 Worker 进程,是真正干活的工人。接收请求,提供对外服务。而启动的Worker进程数量一般由服务器的CPU核数来决定。

即前面的小章节,都是建立在单个Worker的基础上来完成的。每个Worker都有属于他自己的一套事件队列以及底层的LIBUV库线程池。

现在有两个问题:

  1. Cluster 是如何做到多个进程共享同一个端口的?
  2. Master 是如何将接收到的请求传递给worker然后去执行的?

源码的详解可以参考:源码解析

原理如下:

  1. 主线程负责监听指定的端口,并接收来自客户端的请求。
  2. 主线程接收到请求后,将请求通过轮询负载均衡的方式丢给可用的Worker进程来处理。
  3. 主进程和 Worker 进程之间通过 IPC(进程间通信)来传递连接和其他信息。主进程将接收到的连接分配给 Worker 进程,并将连接的套接字(socket)传递给对应的 Worker 进程。Worker 进程接收到连接后,可以像单个 Node.js 应用程序一样处理连接。执行完业务逻辑处理之后,返回。
  4. 通过这种方式,多个 Worker 进程可以共享同一个端口,并且能够处理并发的连接请求。

三. 总结

总结下NodeJs的单线程模型和高并发处理原理,假设我们有一台4核CPU的机器。

  • NodeJs会创建出一个Master进程,它负责创建Worker进程,数量一般会和服务器的核数一致,也就是4个Worker进程。
  • 外部的用户请求到服务器,会由Master进程进行轮询负载均衡丢给Worker进程来处理。
  • 同时Master会通过IPC通信,传递相关的信息给Worker进程,让他们能够正确地处理用户请求。

这里是nodejs对多核服务的一个利用机制。每个CPU同一时间可以处理一个用户请求。

那再说一下单个Worker进程的处理:

  1. Worker 进程开始处理当前用户请求。这个请求过程中遇到的任何一个IO请求(事件),统一丢给Event Queue事件队列中,而非立即执行。
  2. 主线程(JS单线程)处理完毕之后(即你的代码已经跑完了,但是期间涉及到的异步任务还没执行完毕),会进行事件循环,不断地访问事件队列中的队列,依次取出,将它丢给LIBUV库中维护的线程池。
  3. 最终的异步任务则由底层的线程池来完成,完成好后通知给主线程,主线程通过回调机制拿到结果。
  4. 从而实现了主线程的非阻塞异步IO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/130024.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(动手学习深度学习)第7章 残差网络---ResNet

目录 ResNet总结 ResNet代码实现ResNet的梯度计算 ResNet 总结 残差块使得很深的网络更加容易训练 甚至可以训练一千层的网络 残差网络对随后的深层神经网络设计产生了深远影响,无论是卷积类网络还是全连接类网络。 ResNet代码实现 导入相关库 import torch fro…

【优选算法系列】【专题二滑动窗口】第二节.1004. 最大连续1的个数 III和1658. 将 x 减到 0 的最小操作数

文章目录 前言一、最大连续1的个数 III 1.1 题目描述 1.2 题目解析 1.2.1 算法原理 1.2.2 代码编写二、将 x 减到 0 的最小操作数 2.1 题目描述 2.2 题目解析 2.2.1 算法原理 2.2.2 代码编写总结 前言 一、最大连…

Centos配置邮件发送

在CentOS Linux上配置邮件发送 在这个指南中,我们将讨论如何配置CentOS Linux系统以通过外部邮件服务器发送电子邮件,使用自己的邮件账户进行发送。 第一步:开启SMTP授权码 首先,我们以QQ邮箱为例,需要开启SMTP授权…

state 和 props 有什么区别?

一、state 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是 state,一般在 constructor 中初始化 当需要修改里面的值的状态需要通过调用 setState 来改变,从而达到更新组件内部数据的作用,并且重新调用组件 r…

滚珠螺杆的精度和使用场景之间的关系?

滚珠螺杆的精度和使用场景之间有着密切的关系,不同精度的滚珠螺杆被应用于不同的机械设备和制造工艺中,以满足不同的精度要求和生产效率。 在机床加工行业中,高精度的滚珠螺杆被广泛应用于数控机床、加工中心和磨床等高精度加工设备中。这些设…

WebGL-Vue3-TS-Threejs:基础练习 / Javascript 3D library / demo

一、理解Three.js Three.js是一个用于WebGL渲染的JavaScript库。它提供了一组工具和类,用于创建和渲染3D图形和动画。简单理解(并不十分准确),Three.js之于WebGL,好比,jQuery.js之于JavaScript。 OpenGL …

ROS Motion Planning运动规划库安装方法及进阶使用方法详细介绍

今天偶然发现了一个优质的运动规划库:ai-winter/ros_motion_planning,比较适合从事ROS移动机器人运动规划研究领域的小伙伴学习和使用,相比于莱斯大学Kavraki实验室提供的开源的著名运动规划库OMPL、或着我之前介绍过的zhm-real开源的zhm-rea…

2011年09月01日 Go生态洞察:Go语言词法扫描与App Engine演示

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

蓝桥杯每日一题2023.11.10

“蓝桥杯”练习系统 (lanqiao.cn) 题目描述 题目分析 对于此题:我们看到题目要求尽可能大,会联想到二分,注意切出的一定为正方形,其能切出的个数为(h[i] / x) * (w[i] / x),将所有的个数与要求的个数进行对比&#x…

sql学习笔记(三)

目录 1.四舍五入 2.向上取整 3.向下取整 4.Hive 分区 5.case when条件语句 6.日期函数 7.字符串函数 8.窗口函数 1️⃣排序函数 1.四舍五入 round select round(3.14) —>3 2.向上取整 ceiling select ceiling(12.15) —>13 3.向下取整 floor select floor(12…

RFID携手制造业升级,为锂电池生产带来前所未有的可靠性

应用背景 随着科技的发展和全球化的推进,产品的生产过程越来越复杂,且对品质的要求也越来越高。在锂电池生产领域,由于其高能量密度、长寿命和环保特性,已被广泛应用于电动汽车、储能系统等领域。然而,锂电池的安全性和…

Android T窗口动画显示和退出流程(更新中)

序 如何创建一个窗口动画?我们通过先从APP创建一个窗口,以这个窗口的创建过程的窗口动画为例 这个demo就是点击BUTTON显示窗口,点击CLOSE WINDOW关闭窗口,下面简述关键代码 //定义WindowManager和LayoutParams private Window…

redis数据倾斜如何解决

Redis数据倾斜主要是由于数据访问热点导致的,通常在执行事务操作或范围查询时发生。这会导致大量数据集中在某个实例上,使得集群负载不均衡。以下是一些解决Redis数据倾斜的方法: 避免在同一个键值对上保存过多的数据。可以将大的键值对拆分…

Java 算法篇-深入理解递归(递归实现:青蛙爬楼梯)

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 递归的说明 2.0 用递归来实现相关问题 2.1 递归 - 阶乘 2.2 递归 - 反向打印字符串 2.3 递归 - 二分查找 2.4 递归 - 冒泡排序 2.5 递归 - 冒泡排序2.0 2.6 递归 - 插…

启动Docker服务后显示Docker Engine stopped

1、重新启动Docker服务:打开Windows服务管理器(可以在开始菜单中搜索),找到"Docker Desktop Service"或类似命名的服务,右键单击并选择"重启"。稍等片刻,看看是否重新启动成功 2、尝试…

如何快速落地LLM应用?通过Langchain接入千帆SDK

百度智能云千帆大模型平台再次史诗级升级!在原有API基础上,百度智能云正式上线Python SDK(下文均简称千帆 SDK)版本并全面开源,企业和开发者可免费下载使用!千帆SDK全面覆盖从数据集管理,模型训…

如何利用软文推广提升消费者“购买力”?

企业软文推广的目的大部分是为了将自己的产品卖出去,想要成功卖出去还得将重心放在消费者身上,今天媒介盒子就来分享,如何利用软文推广提升消费者的“购买力”。 一、 研究产品属性 产品是连接企业和消费者的桥梁,要想将产品卖出…

黄执中老师人际说服课思考总结(个人笔记整理 ②)

前言: 沟通和说服的区别:为什么沟通不能解决问题,处于劣势的一方(承受问题的那方)才想去沟通(对方没有沟通动力)。说服是温柔而有力的学科 - 劣势一方的武器。 说服是一门影响人的学问&#xff…

SQL Server 2022 安装步骤——SQL Server设置身份验证教程

目录 前言: 安装详细步骤: 第一步: 第二步: 第三步: 第四步: SQL Server 连接的方式: Window验证: SQL Server验证: 两者之间区别: 总结: SQL Server身份验证登录配置教程:​ 第一步: 第二步: 第三步: 番外篇: 前言: 本文讲解,如何安装SQL Server安…