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

news2024/10/7 18:22:10

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu 20.04编译Chrome浏览器

本文记录chrome浏览器编译过程,帮助大家避坑qaq 官网文档:https://chromium.googlesource.com/chromium/src//main/docs/linux/build_instructions.md 一.系统要求 一台64位的英特尔机器,至少需要8GB的RAM。强烈推荐超过16GB。至少需要100…

问题排查-进程分析工具-001strace-安装方式--用法用量

参考来源: centos7 安装strace 《极客时间-网络排查案例课》 strace工具介绍 跟网络排查中有 tcpdump 这样强大的工具类似,进程的排查也有相关的强大工具,比如strace。通过 strace,我们可以把排查工作从进程级别,继续…

【EI会议征稿】第八届先进能源科学与自动化国际研讨会(AESA 2024)

第八届先进能源科学与自动化国际研讨会(AESA 2024) 2024 8th International Workshop on Advances in Energy Science and Automation 继AESA 2017-2023相继成功举办之后,来自国内外多所高校、科研院所及企业代表在先进能源科学与自动化的科研合作和交流…

【虹科干货】Lambda数据架构和Kappa数据架构——构建现代数据架构

如何更好地构建我们的数据处理架构,如何对IT系统中的遗留问题进行现代化改造并将其转变为现代数据架构?该怎么为你的需求匹配最适合的架构设计呢,本文将分析两种最流行的基于速度的数据架构,为你提供一些思路。 文章速览&#xf…

2023最新版JavaSE教程——第5天:数组

目录 一、数组的概述1.1 为什么需要数组1.2 数组的概念1.3 数组的分类 二、一维数组的使用2.1 一维数组的声明2.2 一维数组的初始化2.2.1 静态初始化2.2.2 动态初始化 2.3 一维数组的使用2.3.1 数组的长度2.3.2 数组元素的引用 2.4 一维数组的遍历2.5 数组元素的默认值 三、一维…

【开源】基于Vue和SpringBoot的生活废品回收系统

项目编号: S 003 ,文末获取源码。 \color{red}{项目编号:S003,文末获取源码。} 项目编号:S003,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&…

SAP 50策略测试简介

上篇博文写了40策略的测试,40策略就是典型的按库存生产,考虑库存,考虑销售订单。 本文将测试50策略,按单生产用的最多的策略。相信很多公司按单生产应该都会用到50的策略 1、首先还是先创建物料AB3 同时将BOM中的原材料的独立集中的字段设置为1 2、创建BOM—CS01 3、同杨…

01_ddim_inversion_CN

DDIM反转 设置 # !pip install -q transformers diffusers accelerateimport torch import requests import torch.nn as nn import torch.nn.functional as F from PIL import Image from io import BytesIO from tqdm.auto import tqdm from matplotlib import pyplot as p…

离散Hopfield神经网络分类——高校科研能力评价

大家好,我是带我去滑雪! 高校科研能力评价的重要性在于它对高等教育和科研体系的有效运作、发展和提高质量具有深远的影响。良好的科研能力评价可以帮助高校识别其在不同领域的强项和薄弱点,从而制定战略,改进教学和科研&#xff…

C语言求解:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位(约瑟夫问题)

完整代码&#xff1a; /* 有n个人围成一圈&#xff0c;顺序排号。从第一个人开始报数&#xff08;从1到3报数&#xff09;&#xff0c;凡报到3的人 退出圈子&#xff0c;问最后留下的是原来第几号的那位*/ #include<stdio.h>//约瑟夫问题 //递推关系f(n)(f(n-1)2)\mod n…

白嫖阿里云服务器,速看!数量不多

白嫖阿里云服务器攻略来了&#xff0c;在阿里云免费试用中心可以申请免费服务器&#xff0c;但是阿里云百科不建议选择免费的&#xff0c;只有3个月使用时长&#xff0c;选择99元服务器不是更香&#xff0c;2核2G配置3M固定带宽&#xff0c;一年99元&#xff0c;重点是新老用户…

使用screw一键生成数据库文档

今天分享一个好用的工具&#xff0c;screw&#xff0c;他是一款国产开源软件支持将数据库库表结构一键生成html、word、markdown文档&#xff0c;非常的好用&#xff0c;项目详情页&#xff1a;https://gitee.com/leshalv/screw 背景 我们项目的开发模式是甲方、乙方这种&…

k8s、数据存储

数据存储的概念 容器磁盘上的文件的生命周期是短暂的&#xff0c;这就使得在容器中运行重要应用时会出现一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubelet 会重启它&#xff0c;但是容器中的文件将丢失——容器以干净的状态&#xff08;镜像最初的状态&#xff09;…

ChatGPT风潮再起!最新国内产品一网打尽,畅游指南曝光!

一、国内类chatgpt产品 在人工智能领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;是一个重要的方向&#xff0c;涉及到语音识别、文本生成、机器翻译、问答系统等多个应用场景。近年来&#xff0c;随着深度学习技术的发展&#xff0c;NLP也取得了突破性的进展&#…

PTE-DI 练习 + 模板

目录 重点&#xff1a;平时练习的模板&#xff0c;一定要滚瓜烂熟 25秒准备时间 要想拿还不错的分数&#xff0c;fluency 一定要足够地高 Preparation 1.Look at the title and other words inthe image 2.Look for simple information(highest/lowest) Speak 1.Speak …

断点续传-http中Header参数Range(分段请求基础)

文章目录 Range请求头信息介绍RangeIf-Range 响应头Content-RangeAccept-Ranges 需要用到几个http头 rangeif-rangecontent-rangeaccept-range 断点续传的优缺点 好处&#xff1a;防止大文件下载过程出现网络异常&#xff0c;而前功尽弃。缺点&#xff1a;要发起多次请求&…

Bean的循环依赖问题

2023.11.10 通俗来讲&#xff0c;循环依赖指的是一个实例或多个实例存在相互依赖的关系&#xff08;类之间循环嵌套引用&#xff09;。比如&#xff1a;丈夫类Husband&#xff0c;妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。 正常调用这两对象不会出现问题&am…

【华为数通HCIP | 网络工程师】821-BGP 组播高频题与解析(1)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

echarts 圆环图 高亮事件 切换 中心文字

createEcharts() {let chartDom this.$refs.echartsthis.Echarts echarts.init(chartDom)let option {title: {text: 128, //主标题文本subtext: 总数, //副标题文本left: center,top: 32%,textStyle: {fontFamily: Montserrat-MediumItalic,fontSize: 30,color: #fff,align…

百度搜索深度学习模型业务及优化实践

作者 | Xin 导读 百度搜索架构部模型架构组&#xff0c;致力于将最新的人工智能技术以更低的成本被百度数亿用户体验到。这个过程中会面临非常多的系统、工程层面的问题&#xff0c;甚至在深度学习模型领域&#xff0c;我们看到越来越多的工作并不拘泥于工程本身。 本文主要分享…