【发布时间】:2014-02-10 05:50:19
【问题描述】:
我正在对 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 只在一个内核上运行。所以我更改了节点代码以合并集群模块,现在它正在利用所有四个内核。以下是新结果:
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);
});
};
【问题讨论】:
-
你可以试试
NODE_ENV=productiongroups.google.com/forum/#!topic/express-js/fqtr1Carr0E -
另外,您是否正确汇集连接?这是建议的方式
var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err, connection) { // Use the connection connection.query( 'SELECT something FROM sometable', function(err, rows) { // And done with the connection. connection.release(); // Don't use the connection here, it has been returned to the pool. }); });github.com/felixge/node-mysql -
是的,我正确使用了池。我展示的代码只是你所拥有的代码的捷径(我已经尝试过两种方式)。在此 node-mysql 问题上对此进行了广泛澄清:github.com/felixge/node-mysql/issues/712。
-
设置 NODE_ENV=production 没有区别 - 所有数字都保持不变。
-
我很想看看您是否找到了提高性能的方法。请随时更新。
标签: java spring node.js jakarta-ee node-mysql