Я новичок в Node js и создал очень простое приложение для группового чата с Mongodb как для узла js (с использованием библиотеки socket.io и express), так и для Java (веб-сокеты из библиотеки Javalin.io). По сути, они выполняют одни и те же действия, поэтому я ожидаю, что Node js будет быстрее, чем Java, так как это, вероятно, лучший пример приложения на основе реального времени и ввода / вывода.
Однако тестированиеприложения с JMeter (N запросов за 5 секунд) показывают, что приложение Node js немного медленнее для меньшего N (50-100), и становится намного медленнее для большего N (400).
Тестируемый мной запрос - это HTTP-запрос к API, возвращающему массив Json, содержащий все сообщения в mongodb:
app.all('/chats', function (req, res) {
res.setHeader("Content-Type", "application/json");
res.statusCode = 200;
thechatsCollection.find({}).toArray ( (err, chats) => {
var jsonArr = [];
for (var i = 0; i < chats.length; i++) {
jsonArr.push({
sender: chats[i].sender,
message: chats[i].message,
createdAt: chats[i].createdAt
});
}
res.json(jsonArr);
});
});
Я инициализирую thechatsCollection один раз, когда запускается сервер иЯ знаю, что он должен открывать динамический пул соединений (начиная с 5), который точно такой же в реализации Java.
MongoClient.connect("mongodb://127.0.0.1:27017/chat", { useNewUrlParser: true, /*poolSize: 100*/ }, (err, client) => {
if(err) throw err;
client.db('chat').collection('thechats', (err, collection) => {
thechatsCollection = collection;
console.log("connected to the db");
});
});
Кроме того, я заметил, что повторный запуск теста приводит кболее низкое среднее время отклика, которое, как я думал, было связано с увеличением пула соединений с дБ, поэтому я пытался установить параметр poolSize при открытии соединения дб (до 10,20,50,100), но это в основном замедляло работу.
Возможно, реализация узла чата в приложении чата медленнее, чем в Java? Что может быть причиной этого? Я неправильно пишу асинхронную часть?
Реализация Java запроса на отдых:
app.get("/chats", ctx -> {
JSONArray messageArray = getMessageArray();
ctx.contentType("application/json");
ctx.result(messageArray.toString());
});
// Builds a JSON array containing all the messages in the db
private static JSONArray getMessageArray() {
JSONArray messageArray = new JSONArray();
for (Document doc : thechatsCollection.find()) {
JSONObject message = new JSONObject();
message.put("message", doc.get("message"));
message.put("sender", doc.get("sender"));
message.put("createdAt", doc.get("createdAt"));
messageArray.put(message);
}
return messageArray;
}
Я попытался выполнить профилирование со встроенным --prof
, вызвав ab -c 20 -n 250 "http://localhost:5000/chats"
, что должно выполнить 250запрашивает 20 одновременно и обрабатывает файл с --prof-process
, и вот что я получаю:
[Summary]:
ticks total nonlib name
606 2.2% 78.3% JavaScript
0 0.0% 0.0% C++
298 1.1% 38.5% GC
26331 97.1% Shared libraries
168 0.6% Unaccounted
[Shared libraries]:
ticks total nonlib name
23282 85.9% C:/Windows/SYSTEM32/ntdll.dll
3026 11.2% C:/Program Files/nodejs/node.exe
...
[JavaScript]:
ticks total nonlib name
122 0.5% 15.8% LazyCompile: *deserializeObject C:/Users/apon9/OneDrive/Node js/chatApplication_nodejs/node_modules/bson/lib/bson/parser/deserializer.js:41:33
82 0.3% 10.6% Builtin: KeyedStoreIC_Megamorphic
35 0.1% 4.5% Builtin: InterpreterEntryTrampoline
...
C:/Program Files/Nodejs/Node.exe
мне кажется разумным, но я понятия не имею, предполагается ли C:/Windows/SYSTEM32/ntdll.dll
быть там с 86%, может быть, связано с ядром?
Как насчет deserializeObject
? Можно ли оптимизировать мой код?