V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
humbass
V2EX  ›  Node.js

问一个关于 nodejs CPU 核心利用的问题

  •  
  •   humbass · 4 天前 · 1733 次点击

    经常被问到 nodejs 写的程序 cpu 利用率的问题

    例如建立一个 TCP Server ,做一些数据处理,简单 demo 大约像下面这样。

    问题:假设服务器是 4 核

    • 在没有使用 pm2 等第三方模块情况下直接启动,最多用到了几个核?
    • 是否要显式的使用 cluster 模块,才真正用到多核 ?
    const net = require('net')
    
    const server = net.createServer()
    
    server.on('connection', (socket) => {
      socket.on('data', (data) => {
        // 这里做一些任务处理
      })
    })
    
    server.listen(3000, '0.0.0.0')
    
    16 条回复    2024-09-19 15:16:27 +08:00
    hiqxy
        1
    hiqxy  
       4 天前
    一个进程只能单核把
    ntedshen
        2
    ntedshen  
       4 天前
    现跑一个不就完了。。。
    ab -n1000000 -c100 -t20 --lantency "http://127.0.0.1:3000/"
    一个
    skallz
        3
    skallz  
       4 天前
    @hiqxy 那线程池是干啥用的。。。多线程就已经能利用多核了
    Zhuzhuchenyan
        4
    Zhuzhuchenyan  
       4 天前
    取决于你的多核语境是以下哪一个

    1.任务处理是否用到了多核

    server.on('connection', (socket) => {
    socket.on('data', (data) => {
    //① 这里做一些任务处理
    })
    })

    对于①处代码,除非显示调用其他相关的库,否则就是单纯的单线程执行

    2. 整个程序是否用到了多核

    node.js 内部依赖 libuv 来做网络链接相关的事情,libuv 内部维护一个线程池来处理文件、网络调用。线程池上的线程基本上可以认为会在多核上均匀调度。
    Trim21
        5
    Trim21  
       4 天前
    @skallz #3 这是在 nodejs 语境下的说法,况且 op 也没用 Workers 开其他线程...
    leconio
        6
    leconio  
       4 天前 via iPhone
    前面套个 nginx 负载均衡,开 4 个进程和端口。docker compose 很容易配置。
    shuimugan
        7
    shuimugan  
       4 天前   ❤️ 1
    不用多进程,不用 Worker threads ,就只能吃满一个核,你直接写个 while(true)看 cpu 占用就知道了,很多脚本语言都是这样设计,包括 php 、python (有 GIL 的版本)、ruby 。
    yuuk520
        8
    yuuk520  
       4 天前
    借用楼主的帖子发问:发送网络请求时记录请求时间会因为服务器压力,导致时间记录不准吗?
    NotLongNil
        9
    NotLongNil  
       4 天前
    @Zhuzhuchenyan 正解👍
    codehz
        10
    codehz  
       3 天前
    @shuimugan 没 gil 也只是 native 层扩展的角度有区别,python 本身并没有支持扩展到不同线程,即使现在去掉了 gil ,也只是解放了多线程 native 代码操作 python 对象的锁,python 本身还是只能用一个线程
    即使用多解释器方案,那玩意也无法共享对象
    FishBear
        11
    FishBear  
       3 天前
    在建立连接 io 这些操作的时候 会用到其他的核心,但是我建议你开多个进程,然后前置 haproxy 负载均衡,这样能充分的利用多个核心
    dejavuwind
        12
    dejavuwind  
       3 天前
    单个线程的情况下 在同一个时刻只会运行在一个 CPU 核心上,理论上在一段时间内是有可能会被调度到不同的 CPU 核心的,但是同一时刻只会在一个核心上运行。
    dejavuwind
        13
    dejavuwind  
       3 天前
    @dejavuwind 想象一下一个核心在跑别的程序已经占用很高的情况,这个时候 CPU 如何决定让哪个核心来运行新的任务线程呢,这个涉及到 CPU 的调度算法了,所以 CPU 空闲的时候 的确会出现好像一段时间上这个线程只会跑在一个核心的现象 所以说个人觉得只用到了几个核这种问题其实不太严谨
    fengYH8080
        14
    fengYH8080  
       3 天前
    @dejavuwind #13 这种问题插入 CPU 调度就没必要了,一个线程细粒化到微指令时确实会在不同的核中执行,就如你说的同一时刻只能在一个核中运行,在考虑只是资源利用的情况下,确实就是只利用到了一个核的资源,至于是哪个核其实并不重要。题主这个问法自动帮他归纳为核的利用上,而不是使用上,不用揪他那几个字的意思
    fengYH8080
        15
    fengYH8080  
       3 天前
    @skallz 进程只有一个主线程,就只能利用到单核的资源,而 node 的线程池是用作异步 io 的,可以理解为只是等待 io 的处理结果,缓解 cpu 与存储介质的速度鸿沟,这部分线程池对 CPU 的利用率极其低。可以在代码中搞个同步的操作,例如无限循环,你就会发现只有一个核被利用上,且进程被卡住,如果是网络服务就无法接受其他的请求
    libook
        16
    libook  
       3 天前
    Node.js 默认不使用多进程、多线程 API 的话就是一个单线程的主进程,然后 IO 会由特定的接口管理的单独的进程跑。

    你要想利用多核,可以把服务无状态化,然后跑核心数量个服务,用 Nginx 之类的负载均衡,这样还能容灾和灰度发布什么的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2629 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:17 · PVG 08:17 · LAX 17:17 · JFK 20:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.