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

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

  •  
  •   humbass · 73 天前 · 2606 次点击
    这是一个创建于 73 天前的主题,其中的信息可能已经有所发展或是发生改变。

    经常被问到 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')
    
    17 条回复    2024-09-24 10:51:39 +08:00
    hiqxy
        1
    hiqxy  
       73 天前
    一个进程只能单核把
    ntedshen
        2
    ntedshen  
       73 天前
    现跑一个不就完了。。。
    ab -n1000000 -c100 -t20 --lantency "http://127.0.0.1:3000/"
    一个
    skallz
        3
    skallz  
       73 天前
    @hiqxy 那线程池是干啥用的。。。多线程就已经能利用多核了
    Zhuzhuchenyan
        4
    Zhuzhuchenyan  
       73 天前   ❤️ 1
    取决于你的多核语境是以下哪一个

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

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

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

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

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

    你要想利用多核,可以把服务无状态化,然后跑核心数量个服务,用 Nginx 之类的负载均衡,这样还能容灾和灰度发布什么的。
    dode
        17
    dode  
       67 天前
    python3 -m http.server 单线程,单连接并且是同步 IO ,非常慢
    http-server -p 8000 支持多连接,速度还不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1936 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 00:30 · PVG 08:30 · LAX 16:30 · JFK 19:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.