Ich mache einen schnellen Leistungstest für NodeJS vs. Java. Der ausgewählte einfache Anwendungsfall ist das Abfragen einer einzelnen Tabelle in der MySQL-Datenbank. Die ersten Ergebnisse waren wie folgt:Wie skaliere ich NodeJS linear auf mehreren Kernen?
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
Beachten Sie, dass Knoten der CPU- und Speichernutzung sind viel niedriger als Java, aber der Durchsatz ist auch etwa ein Drittel! Dann stellte ich fest, dass Java alle vier Kerne auf meiner CPU verwendete, während Node auf nur einem Kern lief. Also änderte ich den Node-Code, um das Cluster-Modul zu integrieren, und jetzt nutzte er alle vier Kerne. Hier sind die neuen Ergebnisse:
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
Beachten Sie, dass die CPU- und Speicherauslastung haben nun proportional gestiegen, aber der Durchsatz nur um 70% gestiegen ist. Ich habe eine vierfache Steigerung erwartet und den Java-Durchsatz überschritten. Wie kann ich die Abweichung erklären? Was kann ich tun, um den Durchsatz linear zu erhöhen?
Hier ist der Code für die Nutzung mehrerer Kerne:
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');
});
}
Ich bin der Knoten-mysql-Treiber für die Abfrage der Datenbank. Der Verbindungspool ist auf 5 Verbindungen pro Kern festgelegt, dies macht jedoch keinen Unterschied. Wenn ich diese Zahl auf 1 oder 20 setze, bekomme ich ungefähr den gleichen Durchsatz!
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);
});
};
Sie könnten versuchen 'NODE_ENV = production' https://groups.google.com/forum/#!topic/express-js/fqtr1Carr0E – KeepCalmAndCarryOn
Sind Sie auch Pooling-Verbindungen richtig? Dies ist der vorgeschlagene Weg 'var mysql = require ('mysql'); var pool = mysql.createPool (...); pool.getConnection (Funktion (Fehler, Verbindung)) { // Verwenden Sie die Verbindung Verbindung.Abfrage ('SELECT etwas aus Somethable', Funktion (Fehler, Zeilen)) { // Und mit der Verbindung getan. connection.release(); // Verwenden Sie nicht die Verbindung hier, es wurde an die zurückgegeben Pool }); }); 'https://github.com/felixge/node-mysql – KeepCalmAndCarryOn
Ja, ich benutze den Pool richtig. Der Code, den ich zeige, ist nur eine Abkürzung von dem, was Sie haben (ich habe es in beide Richtungen versucht). Dies wurde ausführlich in diesem Knoten-mysql Problem erläutert: https://github.com/felixge/node-mysql/issues/712. – Naresh