你遇到过哪些业务场景,可以通过 Nodejs 实现,却是 CPU 密集型场景,并且可能需要实时返回的?

你遇到过哪些业务场景,可以通过 Nodejs 实现,却是 CPU 密集型场景,并且可能需要实时返回的?
/t/702273

看到上面这个问题想到。

例如:图片复杂的裁剪合并,node.js 虽有相关的库,但是实现的功能不多。一般我们会把任务放进队列,后端用 python 实现相应的功能,并且也不要求实时性。

大家也举例说说遇到过的业务场景,平常所说的“node.js 不适合 CPU 密集型的应用场景”,到底是哪些场景?

更多的有可能 node.js 的生态并不是很完善。


18 回复

node 天生异步,大部分公司的业务都是 io 操作,基本很少有需要长时间占用 cpu 的业务。大家的业务基本上就是写写数据库

反倒是很多 python 写出来的后端不用协程多进程,在接口里做同步 io 数据库操作,一个请求阻塞全局 gil,并发测试响应时间上天


node js 搭配 python 用,也是鬼才^_^

加密,

但是这种情况下 python 更慢,蛇日的 python 好慢呀

用 node canvas 画图返回,python 的 pillow 太慢了。

minecraft 服务端?

另外不要为了 node 而 node

有原生 IO 复用不用,非得写同步逻辑,实属倔强的公司

图片处理,sharp 库了解一下,用的 libvips

Python 跑 CPU 密集型的可以用进程池,node 应该也有类似的吧

node 有 work_thread 库.cpu 密集已经不是短板了

很多是 node 做不好或者就直接不做不了的 CPU 密集的任务,比如:
直播视频流动态编码类型多马率、多编码的转码,要求实时,且 IO 不是瓶颈。
实时模型推理,实时排序等,主要是计算,尤其是涉及 CV 和 NLP,还有图计算的。
游戏服务器,比如帧同步模块,无锁队列(游戏的队列,比如组队、进服务器等)模块,必须在给定时间内算完,且数据一般都在同一个进程里,只有少部分数据会异步落盘。
以及数据的复杂处理等,这个看业务了,比如对大量的 data point 用特定的算法做 sampling 。

一般遇到 CPU 密集型场景优先考虑用 C 实现,而且不会要求实时。要求实时要么堆硬件要么并发稳定,不然来个高并发波动 CPU 资源超限直接就任务超时了。
之前做过三个计算任务场景,一个是 CAD 文件解析绘图,一个是视频转码,还有个自然语言处理,前两个是用消息队列提交到任务中心排队的,最后一个控制并发量多买机器。
架构上设计好了,用不用 node.js 其实不重要,任务处理用 nodejs,java,python,C++随便什么写都可以,经常混合的。刚开始规模不大的话性能差个一两倍直接堆硬件就完了,后期有规模了才会优化。

请问一下贵公司使用的是哪个垃圾 python 的数据库驱动,做数据库操作居然不会释放 gil 锁

比如 webpack build,就是一个典型的计算密集型

node.js 的强项是前后端可以用同一技术栈. 弱项是后端生态不完善, 第三方库质量参差不齐. CPU 密集型不合适我理解主要是指一些极端场景效率不高(但是我极度怀疑这些极端场景会用 node.js 来实现). 实时返回不代表要同步处理或者要在 node.js 层面处理, node.js 很多逻辑天生都是异步的, 放到 worker 中处理即可.

比如大循环 1 加到 10 亿,大递归递归版本的斐波那契

在IT领域,确实存在一些业务场景,它们既适合通过Node.js实现,又涉及CPU密集型任务,且可能需要实时返回结果。以下是一个典型场景及相应的解决方案概述:

场景:图像处理服务。用户上传图片后,服务需要对图片进行个性化处理(如滤镜、裁剪、调整大小等),并实时返回处理后的图片。

解决方案

  1. Node.js作为服务端:利用Node.js构建服务端应用,接收用户上传的图片并触发处理流程。
  2. 子进程处理CPU密集型任务:由于图像处理是CPU密集型任务,可以在Node.js中通过child_process模块创建子进程,将图像处理任务交给子进程执行。
  3. 实时返回结果:子进程完成图像处理后,通过进程间通信将结果返回给主进程,主进程再将处理后的图片实时返回给用户。

示例代码

const { fork } = require('child_process');
const path = require('path');

// 创建子进程执行图像处理任务
const imageProcessor = fork(path.join(__dirname, 'imageProcessor.js'));

// 接收用户上传的图片并触发处理
app.post('/upload', (req, res) => {
  const imageBuffer = ...; // 获取用户上传的图片数据
  imageProcessor.send({ type: 'process', data: imageBuffer });

  imageProcessor.on('message', (message) => {
    if (message.type === 'result') {
      res.send(message.data); // 实时返回处理后的图片数据
    }
  });
});

注意,imageProcessor.js是子进程执行的脚本,负责实际的图像处理逻辑。

回到顶部