编辑(2):现在使用db-mysql和generic-pool模块。错误率显著降低,但吞吐量仍约为100 req/sec。
编辑(1):有人建议使用ORDER BY RAND()会导致MySQL变慢,因此我从查询中删除了该子句。Node.js现在约为100 req/sec,但服务器仍报告“CONNECTION error:Too many connections”。
Node.js还是Lighttpd与PHP?
您可能看到了许多node.js的“Hello World”基准测试……但是,“Hello World”测试,即使每个请求延迟2秒钟,也远远不能接近实际生产使用。我也使用node.js执行了这些“Hello World”测试的变体,并且看到了大约800 req/sec的吞吐量和0.01%的错误率。然而,我决定进行一些更加现实的测试。
也许我的测试不完整,很可能node.js或我的测试代码真的有很大问题,因此如果您是node.js专家,请帮助我编写一些更好的测试。我的结果如下所述。我使用Apache JMeter进行测试。
测试用例和系统规格
测试非常简单。对用户数量进行随机排序的mysql查询。检索并显示第一个用户的用户名。 mysql数据库连接是通过unix套接字进行的。操作系统为FreeBSD 8+。 8GB的RAM。 Intel Xeon四核2.x GHz处理器。在我遇到node.js之前,我对Lighttpd配置进行了一些调整。
Apache JMeter设置
线程数(用户):5000我认为这是并发连接数
渐进周期(秒):1
循环计数:10这是每个用户的请求次数
Apache JMeter最终结果
标签 | #样本| 平均值 | 最小值 | 最大值 | 标准偏差 | 错误% | 吞吐量 | KB/sec | 平均字节
HTTP请求Lighttpd | 49918 | 2060ms | 29ms | 84790ms | 5524 | 19.47% | 583.3/sec | 211.79 | 371.8
HTTP请求Node.js | 13767 | 106569ms | 295ms | 292311ms | 91764 | 78.86% | 44.6/sec | 79.16 | 1816
结果结论
Node.js太糟糕了,我不得不提前停止测试。 [已修复完全测试]
Node.js在服务器上报告“CONNECTION error:Too many connections”。[已修复]
大多数情况下,Lighttpd的吞吐量约为1200 req/sec。
然而,node.js 的吞吐量约为29个请求/秒。[已修复,现在为100个请求/秒]
这是我在 node.js 中使用 MySQL 连接池的代码
var cluster = require('cluster'), http = require('http'), mysql = require('db-mysql'), generic_pool = require('generic-pool');
var pool = generic_pool.Pool({
name: 'mysql',
max: 10,
create: function(callback) {
new mysql.Database({
socket: "/tmp/mysql.sock",
user: 'root',
password: 'password',
database: 'v3edb2011'
}).connect(function(err, server) {
callback(err, this);
});
},
destroy: function(db) {
db.disconnect();
}
});
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
pool.acquire(function(err, db) {
if (err) {
return response.end("CONNECTION error: " + err);
}
db.query('SELECT * FROM tb_users').execute(function(err, rows, columns) {
pool.release(db);
if (err) {
return response.end("QUERY ERROR: " + err);
}
response.write(rows.length + ' ROWS found using node.js<br />');
response.end(rows[0]["username"]);
});
});
});
cluster(server)
.set('workers', 5)
.listen(8080);
这是我用于 PHP(Lighttpd + FastCGI)的代码
<?php
$conn = new mysqli('localhost', 'root', 'password', 'v3edb2011');
if($conn) {
$result = $conn->query('SELECT * FROM tb_users ORDER BY RAND()');
if($result) {
echo ($result->num_rows).' ROWS found using Lighttpd + PHP (FastCGI)<br />';
$row = $result->fetch_assoc();
echo $row['username'];
} else {
echo 'Error : DB Query';
}
} else {
echo 'Error : DB Connection';
}
?>
ORDER BY RAND()
会变慢,如果你的数据库导致了一些延迟,这将不是一个公平的测试。 - fire