gpt4 book ai didi

node.js - NodeJS 和 TCP 性能

转载 作者:可可西里 更新时间:2023-11-01 02:33:39 25 4
gpt4 key购买 nike

我正在测试两个 NodeJS 实例之间通过 TCP 的通信,使用 net module .

由于 TCP 不依赖消息 (socket.write()),我将每条消息包装在一个字符串中,如 msg "{ json: 'encoded' }"; 以便单独处理它们(否则,我会收到包含随机数量的串联消息的数据包)。

我在具有桥接网络和基于 Core i3 的主机的 CentOS 6.5 VirtualBox VM 上运行两个 NodeJS 实例(服务器和客户端)。测试在于客户端向服务器发出请求并等待响应:

  1. 客户端连接到服务器。
  2. 客户端输出当前时间戳(Date.now())。
  3. 客户端发出 n 个请求。
  4. 服务器回复 n 个请求。
  5. 客户端在每次响应时递增一个计数器。
  6. 完成后,客户端输出当前时间戳。

代码很简单:

服务器

var net = require('net');

var server = net.createServer(function(socket) {

socket.setNoDelay(true);

socket.on('data', function(packet) {

// Split packet in messages.
var messages = packet.toString('utf-8').match(/msg "[^"]+";/gm);

for (var i in messages) {

// Get message content (msg "{ content: 'json' }";). Actually useless for the test.
//var message = messages[i].match(/"(.*)"/)[1];

// Emit response:
socket.write('msg "PONG";');

}

});

});

server.listen(9999);

客户端

var net = require('net');

var WSClient = new net.Socket();

WSClient.setNoDelay(true);

WSClient.connect(9999, 'localhost', function() {

var req = 0;
var res = 0;

console.log('Start:', Date.now());

WSClient.on('data', function(packet) {

var messages = packet.toString("utf-8").match(/msg "[^"]+";/gm);

for (var i in messages) {

// Get message content (msg "{ content: 'json' }";). Actually useless for the test.
//var message = messages[i].match(/"(.*)"/)[1];

res++;
if (res === 1000) console.log('End:', Date.now());

}

});

// Emit requests:
for (req = 0; req <= 1000; req++) WSClient.write('msg "PING";');

});

我的结果是:

  • 1 个请求:9 - 24 毫秒
  • 1000 个请求:478 - 512 毫秒
  • 10000 个请求:5021 - 5246 毫秒

我对本地主机的 ping (ICMP) 在 0.6 到 0.1 秒之间。我没有密集的网络流量或 CPU 使用率(运行 SSH、FTP、Apache、Memcached 和 Redis)。

对于 NodeJS 和 TCP 这是否正常,或者它只是我的 CentOS VM 或我的低性能主机?我应该迁移到另一个平台,例如 Java 还是 native C/C++ 服务器?

我认为本地主机上的每个请求延迟 15 毫秒(平均)对于我的项目来说是 Not Acceptable 。

最佳答案

将消息包装在一些文本中并搜索 Regex 匹配项是不够的。

net.Servernet.Socket 接口(interface)将原始 TCP 流作为基础数据源。只要底层 TCP 流有可用数据,就会触发 data 事件。

问题是,您无法控制 TCP 堆栈。它触发 data 事件的时间与您的代码逻辑无关。因此,您无法保证驱动您的监听器的 data 事件恰好有一条、少于一条、多于一条或任意数量和一些剩余的消息被发送。事实上,您几乎可以保证底层 TCP 堆栈会将您的数据分解成 block 。并且监听器仅在 block 可用时触发。您当前的代码在 data 事件之间没有共享状态。

您只提到延迟,但我希望如果您检查一下,您还会发现(两端)收到的消息数不是您期望的。那是因为任何通过的部分消息都将完全丢失。如果 TCP 流在 block 1 的末尾发送一半消息,而其余部分在 block 2 中发送,则拆分消息将被完全丢弃。

简单而可靠的方法是使用像 ØMQ 这样的消息传递协议(protocol)。您将需要在两个端点上使用它。它负责将 TCP 流构建为原子消息。

如果出于某种原因您要连接到外部来源或从外部来源接收流量,他们可能会使用诸如长度 header 之类的东西。然后您要做的是创建一个转换流来缓冲传入流量,并且仅在 header 中标识的数量到达时才发出数据。

关于node.js - NodeJS 和 TCP 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23513640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com