我正在为NodeJS与Java进行快速性能测试。选择的简单用例是查询MySQL数据库中的单个表。初步结果如下:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL | 20 | 34% | 57M | 1295
JBoss EAP 6.2/JPA | 20 | 100% | 525M | 4622
Spring 3.2.6/JDBC/Tomcat 7.0 | 20 | 100% | 860M | 4275
请注意,Node的CPU和内存使用率低于Java,但吞吐量也只有三分之一!然后我意识到Java在我的CPU上使用了所有四个核心,而Node只在一个核心上运行。所以我改变了Node代码以合并集群模块,现在它正在使用所有四个核心。以下是新结果:
Platform | DB Connections | CPU Usage | Memory Usage | Requests/second
==============================|================|===========|===============|================
Node 0.10/MySQL (quad core) | 20 (5 x 4) | 100% | 228M (57 x 4) | 2213
请注意,CPU和内存使用量现已成比例增加,但吞吐量仅增加了70%。我期待增加四倍,超过Java吞吐量。我如何解释这种不足?我该怎么做才能线性增加吞吐量?
以下是使用多核的代码:
if (Cluster.isMaster) {
var numCPUs = require("os").cpus().length;
for (var i = 0; i < numCPUs; i++) {
Cluster.fork();
}
Cluster.on("exit", function(worker, code, signal) {
Cluster.fork();
});
}
else {
// Create an express app
var app = Express();
app.use(Express.json());
app.use(enableCORS);
app.use(Express.urlencoded());
// Add routes
// GET /orders
app.get('/orders', OrderResource.findAll);
// Create an http server and give it the
// express app to handle http requests
var server = Http.createServer(app);
server.listen(8080, function() {
console.log('Listening on port 8080');
});
}
我使用node-mysql驱动程序来查询数据库。连接池设置为每个核心5个连接,但这没有区别。如果我将此数字设置为1或20,我的吞吐量大致相同!
var pool = Mysql.createPool({
host: 'localhost',
user: 'bfoms_javaee',
password: 'bfoms_javaee',
database: 'bfoms_javaee',
connectionLimit: 5
});
exports.findAll = function(req, res) {
pool.query('SELECT * FROM orders WHERE symbol="GOOG"', function(err, rows, fields) {
if (err) throw err;
res.send(rows);
});
};
答案 0 :(得分:2)
从我看到的情况来看,你不仅要比较平台,还要比较框架。您可能希望删除框架效果并实现普通的HTTP服务器。例如,Express应用程序中的所有这些中间件都会增加延迟。另外,您是否确保Java库不会缓存频繁请求的数据,从而显着提高性能?
要考虑的其他事项是Node中的内置http
模块(因此,构建在其上的任何库,包括node-mysql
)通过Agent类维护内部连接池(不是与MySQL连接池混淆),以便它可以利用HTTP keep-alives。当您向同一服务器运行许多请求而不是打开TCP连接,发出HTTP请求,获取响应,关闭TCP连接以及重复时,这有助于提高性能。因此,可以重用TCP连接。
默认情况下,HTTP代理只会打开5个同时连接到单个主机的连接,例如MySQL服务器。您可以按照以下方式轻松更改此内容:
var http = require('http');
http.globalAgent.maxSockets = 20;
考虑到这些变化,请看看您可以获得哪些改进。
其他想法是通过在连接打开和关闭时检查MySQL登录来验证MySQL连接池是否正确使用。如果它们经常打开,您可能需要增加node-mysql中的空闲超时值。
答案 1 :(得分:1)
尝试设置环境变量export NODE_CLUSTER_SCHED_POLICY="rr"
。根据{{3}}。