如何提高Nodejs的上传并发?

如何提高Nodejs的上传并发?

最近项目中使用了nodejs的multer插件做上传,但是在512K的上传带宽下,并发不理想,10个7M的文件上传用了240+秒。且中间有很多上传请求超时了,最后是重传上去的 请问各位大神是如何解决上传并发问题的?

我用了cluster开了4个线程去跑,也没有感觉优化多少。。感觉都是在用同一个

5 回复

要提高Node.js中的文件上传并发性能,可以采取多种策略,包括但不限于使用多进程、优化I/O操作以及利用更高效的库。以下是一些具体的建议和示例代码:

1. 使用multer-s3上传到S3

将文件直接上传到云存储服务(如Amazon S3)可以显著提高并发性能,因为这些服务通常具有更好的带宽和处理能力。

示例代码:

const AWS = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');

AWS.config.update({
    accessKeyId: 'YOUR_ACCESS_KEY',
    secretAccessKey: 'YOUR_SECRET_KEY',
    region: 'us-west-2'
});

const s3 = new AWS.S3();

const upload = multer({
    storage: multerS3({
        s3: s3,
        bucket: 'your-bucket-name',
        acl: 'public-read',
        metadata: function (req, file, cb) {
            cb(null, { fieldName: file.fieldname });
        },
        key: function (req, file, cb) {
            cb(null, Date.now().toString());
        }
    })
});

app.post('/upload', upload.single('file'), (req, res) => {
    res.send('File uploaded successfully.');
});

2. 使用多进程/线程

虽然Node.js本身是单线程的,但你可以通过cluster模块来创建多个工作进程,每个进程负责处理一部分上传任务。

示例代码:

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

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died`);
    });
} else {
    const express = require('express');
    const app = express();
    const multer = require('multer');
    const upload = multer({ dest: 'uploads/' });

    app.post('/upload', upload.single('file'), (req, res) => {
        res.send('File uploaded successfully.');
    });

    http.createServer(app).listen(3000);
}

3. 使用fastify框架

fastify是一个高性能的Web框架,相比Express,它在处理高并发方面表现更好。

示例代码:

const fastify = require('fastify')({ logger: true });
const multer = require('fastify-multer');

fastify.register(multer.contentParser);

fastify.post('/upload', {
    config: {
        maxFileSize: 10 * 1024 * 1024 // 10MB
    },
    handler: async (request, reply) => {
        const files = request.files;
        // 处理文件上传逻辑
        reply.send({ message: 'File(s) uploaded successfully.' });
    }
});

fastify.listen(3000, err => {
    if (err) throw err;
    console.log(`Server listening on http://localhost:${fastify.server.address().port}`);
});

总结

通过上述方法,你可以显著提高Node.js应用中的文件上传并发性能。选择合适的库、使用云存储服务以及利用多进程或多线程都是有效的手段。希望这些建议对你有所帮助!


丢到云存储去

带宽问题,要用钱解决的

512K的上传带宽 …这个是想想都不可能是程序问题了…

要提高Node.js的上传并发性能,可以采取以下几种方法:

  1. 集群(Cluster)模块:确保你的Node.js应用能够利用多核CPU的优势。尽管你已经尝试使用了cluster模块,但可能需要进一步优化配置或检查其他配置。

  2. 异步处理:确保文件上传处理逻辑是完全异步的,避免阻塞事件循环。Multer默认就是非阻塞的,所以这一步通常不需要额外的操作。

  3. 限制同时上传的任务数:使用如async库中的queue来控制同时处理的上传任务数。

  4. 使用负载均衡器:例如Nginx或HAProxy可以在HTTP层面对请求进行负载均衡。

  5. 优化文件存储:确保文件上传后能够快速存入磁盘或云存储服务。可以考虑将文件直接上传到云存储服务,而不是先通过服务器再存储。

  6. 网络带宽:如果带宽有限,可以考虑使用CDN服务或对文件进行压缩。

下面是一个使用async.queue来控制并发上传任务的例子:

const async = require('async');
const multer = require('multer');

// 设置Multer的存储引擎
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
    }
});

const upload = multer({ storage: storage });

// 创建一个队列对象,最大并发数为3
const q = async.queue(upload.single('file'), 3);

q.push({ file: 'file1' }, function (err, result) {
    if (err) {
        console.log(err);
    } else {
        console.log(result);
    }
});

q.push({ file: 'file2' }, function (err, result) {
    if (err) {
        console.log(err);
    } else {
        console.log(result);
    }
});

在这个例子中,我们创建了一个最大并发数为3的队列,这意味着同时最多只能处理3个文件上传任务。这样可以防止过载,提升整体上传效率。

回到顶部