Nodejs写入webdis非常慢,请问是为什么呢?

Nodejs写入webdis非常慢,请问是为什么呢?

代码

var http = require("http");
//http://192.168.1.3:7379/HGET/123:cellphonenumber/
function start(handle) {
    function onRequest(request, response) {
        var options = {
            host:'192.168.1.6',
            port:7379,
            path:'/SADD/' + 'niaAOVU2lg' + ':config/' + '2013-03-09'+Math.random(),
            method:'get'
        };
        var req = http.get(options, function (res) {
            //    console.log("Got response: " + res.statusCode);
            res.on('error',function (e) {
                //     console.log("Got error: " + e.message);
            }).on('data', function (chunk) {
                    //         console.log('BODY: ' + chunk);
                });
        });
        req.on('error', function(e) {
            //  console.log("Got error: " + e.message)
        })
        response.writeHead(200,{'Content-Type':'text/html'});
        response.end()
    }
    var server = http.createServer(onRequest).listen(8888);
}
    exports.start = start;

启动服务器后,利用

setsid webbench -c 1000 -t 60 '192.168.1.2:8888/'进行压测

之后发现 负载服务器.2的cpu几乎跑满,成功150000多个,失败300+

但是192.168.1.6 webdis端,cpu几乎没有负载,访问 http://192.168.1.6:7379/SCARD/niaAOVU2lg:config 可以发现,记录数不断增长,但是非常慢(大约一秒增长300个左右) 请问一下这是怎么回事啊,是我的代码写的有问题么?


3 回复

根据你提供的信息,你的Node.js应用在写入Webdis时速度非常慢。这可能是由于几个原因造成的,包括网络延迟、HTTP请求的开销以及可能的性能瓶颈。以下是一些可能的原因和优化建议。

问题分析

  1. 网络延迟

    • 你的Node.js应用需要频繁地发起HTTP请求到Webdis服务器。如果网络延迟较高,这可能会显著降低整体性能。
  2. HTTP请求的开销

    • 使用http.get发起每个请求都会产生一定的开销,包括DNS解析、建立TCP连接等。如果每次请求都是独立的,那么这些开销会累加,导致整体性能下降。
  3. 性能瓶颈

    • 你的Node.js应用可能已经达到了处理能力的上限,特别是在高并发情况下。尽管Webdis服务器本身没有明显负载,但Node.js服务器的CPU使用率很高,表明可能存在性能瓶颈。

解决方案

示例代码:优化后的Node.js应用

const http = require('http');
const request = require('request'); // 使用request库简化HTTP请求

const handle = {}; // 假设这是你的处理逻辑

function start() {
    const server = http.createServer((req, res) => {
        const options = {
            url: `http://192.168.1.6:7379/SADD/${'niaAOVU2lg'}:config/${'2013-03-09'}${Math.random()}`,
            method: 'GET'
        };

        request(options, (error, response, body) => {
            if (error) {
                console.error(error);
            } else {
                console.log(`Request succeeded with status code ${response.statusCode}`);
            }
            res.writeHead(200, {'Content-Type': 'text/html'});
            res.end();
        });
    });

    server.listen(8888, () => {
        console.log('Server is listening on port 8888');
    });
}

exports.start = start;

关键优化点:

  1. 使用request

    • request是一个更简洁的HTTP客户端库,可以减少代码量并提高性能。你可以通过npm install request安装它。
  2. 批量处理

    • 如果可能的话,尝试批量处理请求,而不是逐个发送。例如,可以将多个SADD操作合并成一个批量请求。
  3. 连接池

    • 考虑使用连接池来复用HTTP连接,减少每次请求的连接开销。
  4. 异步处理

    • 确保所有异步操作(如数据库查询或网络请求)都正确处理回调,避免阻塞事件循环。

通过以上优化,你应该能够提高Node.js应用写入Webdis的速度。如果问题仍然存在,建议进一步检查网络配置和服务器资源使用情况。


补充,开了个8核的机器

function start(handle) {
    var http = require("http");
    var cluster = require('cluster');
    var http = require('http');
    var numCPUs = require('os').cpus().length;
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; i++) {
            cluster.fork();
        }
        cluster.on('death', function (worker) {
            console.log('worker ' + worker.pid + ' died');
            cluster.fork();
        });
    } else {
        function onRequest(request, response) {
            var options = {
                host:'192.168.1.6',
                port:7379,
                path:'/SADD/' + 'niaAOVU2lg' + ':config/' + '2013-03-09' + Math.random(),
                method:'get'
            };
            var req = http.get(options, function (res) {
                //    console.log("Got response: " + res.statusCode);
                res.on('error',function (e) {
                    //     console.log("Got error: " + e.message);
                }).on('data', function (chunk) {
                        //         console.log('BODY: ' + chunk);
                    });
            });
            req.on('error', function (e) {
                //  console.log("Got error: " + e.message)
            })
            response.writeHead(200, {'Content-Type':'text/html'});
            response.end()
        }
    var server = http.createServer(onRequest).listen(8888);
}

}

exports.start = start;

写入速度提高到3600个每秒了,而压测webdis的极限写入速度是17000个每秒,请问我的代码还有什么问题?

根据你的描述,写入操作非常慢,可能的原因包括:

  1. HTTP请求的阻塞:当前代码使用的是Node.js内置的http模块来发起HTTP请求,这种方式是同步的,会阻塞事件循环。当并发请求增多时,CPU使用率会上升。

  2. 并发处理不足:你的测试工具使用了1000个并发连接,但你的代码没有很好地处理高并发情况。每次请求都需要等待响应才能继续处理下一个请求,导致资源被大量占用。

  3. 网络延迟:如果网络延迟较高,每个请求都需要花费较长时间,也会导致整体性能下降。

你可以尝试使用非阻塞的方式来处理HTTP请求,比如使用axiosnode-fetch库,并配合async/await来实现异步处理。

示例代码

const axios = require('axios');
const http = require('http');

function start(handle) {
    async function onRequest(request, response) {
        const url = `http://192.168.1.6:7379/SADD/${'niaAOVU2lg'}:config/${'2013-03-09'}${Math.random()}`;
        
        try {
            await axios.get(url);
            response.writeHead(200, {'Content-Type': 'text/html'});
            response.end('Success');
        } catch (error) {
            response.writeHead(500, {'Content-Type': 'text/html'});
            response.end('Error');
        }
    }

    const server = http.createServer(onRequest).listen(8888, () => {
        console.log('Server running on port 8888');
    });
}

exports.start = start;

改进点

  • 使用axios替代原生http模块,支持更好的错误处理和更简洁的代码。
  • 将请求处理改为异步方式,不会阻塞事件循环,可以更好地处理高并发请求。

这样应该能显著提高你的应用在高并发情况下的性能。

回到顶部