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个左右) 请问一下这是怎么回事啊,是我的代码写的有问题么?
根据你提供的信息,你的Node.js应用在写入Webdis时速度非常慢。这可能是由于几个原因造成的,包括网络延迟、HTTP请求的开销以及可能的性能瓶颈。以下是一些可能的原因和优化建议。
问题分析
-
网络延迟:
- 你的Node.js应用需要频繁地发起HTTP请求到Webdis服务器。如果网络延迟较高,这可能会显著降低整体性能。
-
HTTP请求的开销:
- 使用
http.get
发起每个请求都会产生一定的开销,包括DNS解析、建立TCP连接等。如果每次请求都是独立的,那么这些开销会累加,导致整体性能下降。
- 使用
-
性能瓶颈:
- 你的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;
关键优化点:
-
使用
request
库:request
是一个更简洁的HTTP客户端库,可以减少代码量并提高性能。你可以通过npm install request
安装它。
-
批量处理:
- 如果可能的话,尝试批量处理请求,而不是逐个发送。例如,可以将多个
SADD
操作合并成一个批量请求。
- 如果可能的话,尝试批量处理请求,而不是逐个发送。例如,可以将多个
-
连接池:
- 考虑使用连接池来复用HTTP连接,减少每次请求的连接开销。
-
异步处理:
- 确保所有异步操作(如数据库查询或网络请求)都正确处理回调,避免阻塞事件循环。
通过以上优化,你应该能够提高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个每秒,请问我的代码还有什么问题?
根据你的描述,写入操作非常慢,可能的原因包括:
-
HTTP请求的阻塞:当前代码使用的是Node.js内置的
http
模块来发起HTTP请求,这种方式是同步的,会阻塞事件循环。当并发请求增多时,CPU使用率会上升。 -
并发处理不足:你的测试工具使用了1000个并发连接,但你的代码没有很好地处理高并发情况。每次请求都需要等待响应才能继续处理下一个请求,导致资源被大量占用。
-
网络延迟:如果网络延迟较高,每个请求都需要花费较长时间,也会导致整体性能下降。
你可以尝试使用非阻塞的方式来处理HTTP请求,比如使用axios
或node-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
模块,支持更好的错误处理和更简洁的代码。 - 将请求处理改为异步方式,不会阻塞事件循环,可以更好地处理高并发请求。
这样应该能显著提高你的应用在高并发情况下的性能。