【发布时间】:2019-11-09 11:35:42
【问题描述】:
我是 Node js 的新手,我已经在 Node js(使用 socket.io 库和 express)和 Java(来自 Javalin.io 库的 websockets)中使用 Mongodb 构建了一个非常简单的群聊应用程序。他们基本上做同样的事情,所以我希望 Node js 比 Java 快,因为这可能是基于实时和 I/O 的应用程序的最佳示例。
但是,使用 JMeter 测试应用程序(N 个请求在 5 秒内)表明 Node js 应用程序对于较低的 N (50-100) 稍慢,对于较高的 N (400) 变得更慢。
我正在测试的请求是对 api 的 HTTP 请求,返回一个包含 mongodb 中所有消息的 Json 数组:
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 参数db 连接(到 10,20,50,100),但它主要是让事情变慢。
聊天应用程序的节点 js 实现是否可能比 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 怎么样?我的代码可以以任何方式优化吗?
【问题讨论】:
-
这个rest请求的Java实现是什么样的?
-
添加了java实现
标签: node.js mongodb socket.io jmeter performance-testing