如何在Ubuntu下进行Node.js并发处理

作者:技术拾光

时间:2026-07-06

浏览:208

在Ubuntu系统中,Node.js并发处理可采用异步编程、工作线程、集群模块或第三方库。异步编程适合I/O密集型任务,利用事件循环;工作线程处理CPU密集型计算,避免主线程阻塞;集群模块实现多进程负载均衡,用于高并发HTTP服务;第三方库简化复杂并发逻辑。

文章目录

在Ubuntu上折腾Node.js并发处理,其实有不少路子可走。不少人一上来就盯着多线程、多进程,但Node.js的异步机制本身才是它的灵魂。下面把这几种主流方式捋一遍,顺便聊聊各自适合什么场景。

方法一:异步编程——Node.js的看家本领

Node.js最核心的设计就是异步I/O,能用非阻塞的方式处理大量并发请求。实现手段无非回调、Promise、async/await。现在大部分人都习惯async/await的写法,可读性高,代码也更清爽。

const fs = require('fs').promises;

async function readFiles() {
    try {
        const file1 = await fs.readFile('file1.txt', 'utf-8');
        const file2 = await fs.readFile('file2.txt', 'utf-8');
        console.log(file1, file2);
    } catch (error) {
        console.error(error);
    }
}

readFiles();

这种模式特别适合文件读写、数据库查询、网络请求这类I/O密集型任务。只要操作本身不阻塞事件循环,并发能力就上来了。

方法二:worker_threads——真·多线程来了

当遇到CPU密集型任务(比如大量计算、图像处理、加密解密)时,光靠异步就不够用了。Node.js 10.5+ 引入了worker_threads模块,允许你在独立线程里跑Ja vaScript代码,真正利用多核CPU。

const { Worker } = require('worker_threads');

function runWorker(workerData) {
    return new Promise((resolve, reject) => {
        const worker = new Worker('./worker.js', { workerData });
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', (code) => {
            if (code !== 0) {
                reject(new Error(`Worker stopped with exit code ${code}`));
            }
        });
    });
}

runWorker('Hello from main thread')
    .then(result => console.log(result))
    .catch(error => console.error(error));

在worker.js里这么写:

const { parentPort } = require('worker_threads');

parentPort.on('message', (message) => {
    console.log(`Message from main thread: ${message}`);
    parentPort.postMessage('Hello from worker thread');
});

注意:worker之间不共享内存(要靠消息传递),做并行计算时要权衡数据序列化的开销。

方法三:cluster模块——多进程负载均衡

如果要做HTTP服务,想充分利用多核CPU,cluster模块是最经典的方案。主进程负责调度,子进程共享同一个端口,各自处理请求。

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    console.log(`Master ${process.pid} is running`);
    // Fork workers.
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    cluster.on('exit', (worker, code, signal) => {
        console.log(`worker ${worker.process.pid} died`);
    });
} else {
    // Workers can share any TCP connection
    http.createServer((req, res) => {
        res.writeHead(200);
        res.end('hello world\n');
    }).listen(8000);
    console.log(`Worker ${process.pid} started`);
}

每个子进程都是独立的Node.js实例,互不影响。如果某个worker挂掉,主进程可以重新fork一个,提升了稳定性。

方法四:第三方库——省心省力的选择

社区里还有不少优秀的库,比如async、bluebird、p-limit等。它们封装了并行执行、限流、重试、超时等实用功能。如果你的需求比较复杂,直接用现成的库能省去不少重复造轮子的时间。

说到底,选哪种方式取决于你的任务类型:

  • I/O密集型(文件、网络、数据库):异步编程就够了,没必要上多线程/多进程。
  • CPU密集型(计算、加密):worker_threads或cluster模块才是正解。
  • 高并发HTTP服务:cluster模块是生产环境标配。
  • 追求开发效率:第三方库能帮你快速实现复杂并发逻辑。

没有银弹,理解每种方案的优缺点再下手,才能写出既高效又可控的并发代码。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›