我正在做一個NodeJS與Java的快速性能測試。所選的簡單用例是查詢MySQL數據庫中的單個表。初始結果如下:如何在多個內核上線性擴展NodeJS?
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
請注意,節點的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');
});
}
我使用的節點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 = production' https://groups.google.com/forum/#!topic/express-js/fqtr1Carr0E – KeepCalmAndCarryOn
另外,你是否正確地連接了連接?這是建議的方式'var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err,connection){ //使用連接 連接。查詢('SELECT some FROM sometable',函數(err,rows){//並且完成了連接 connection.release(); //不要在這裏使用連接,它已經返回到pool。 }); });'https://github.com/felixge/node-mysql – KeepCalmAndCarryOn
是的,我正確地使用了池。我所展示的代碼只是你所擁有的一個捷徑(我已經試過了這兩種方式)。在這個node-mysql問題上進行了廣泛的闡述:https://github.com/felixge/node-mysql/issues/712。 – Naresh