Luc*_*iva 24 benchmarking udp node.js
我正在对Java UDP客户端进行基准测试,该客户端以尽可能快的速度连续发送具有100字节有效负载的数据报.它是使用实现的java.nio.*.测试表明,它能够实现每秒220k数据报的稳定吞吐量.我没有测试服务器; 客户端只是将数据报发送到localhost上的一些未使用的端口.
我决定在Node.js中运行相同的测试来比较这两种技术,看到Node.js的执行速度比Java快10倍,我感到非常难过.让我带您浏览我的代码.
首先,我使用Node.js的dgram模块创建一个UDP套接字:
var client = require('dgram').createSocket("udp4");
Run Code Online (Sandbox Code Playgroud)
然后我创建一个使用该套接字发送数据报的函数:
function sendOne() {
client.send(message, 0, message.length, SERVER_PORT, SERVER_ADDRESS, onSend);
}
Run Code Online (Sandbox Code Playgroud)
该变量message是在应用程序启动时从包含一百个字符的字符串创建的缓冲区:
var message = new Buffer(/* string with 100 chars */);
Run Code Online (Sandbox Code Playgroud)
该函数onSend只增加一个变量,该变量保存到目前为止发送了多少数据报.接下来我有不断调用一个函数sendOne()使用setImmediate():
function sendForever() {
sendOne();
setImmediate(sendForever);
}
Run Code Online (Sandbox Code Playgroud)
最初我试图使用,process.nextTick(sendForever)但我发现它总是把自己放在事件队列的顶端,甚至在IO事件之前,正如文档所说:
它在事件循环的后续滴答中触发任何其他I/O事件(包括定时器)之前运行.
这可以防止发送 IO事件发生,就像每次打勾时nextTick一直放在sendForever队列的尖端一样.队列随着未读IO事件而增长,直到它使Node.js崩溃:
fish: Job 1, 'node client' terminated by signal SIGSEGV (Address boundary error)
Run Code Online (Sandbox Code Playgroud)
另一方面,setImmediate在I/O事件回调后触发,这就是我使用它的原因.
我还创建了一个计时器,每1秒向控制台打印一次,在最后一秒发送了多少数据报:
setInterval(printStats, 1000);
Run Code Online (Sandbox Code Playgroud)
最后我开始发送:
sendForever();
Run Code Online (Sandbox Code Playgroud)
在运行Java测试的同一台机器上运行,Node.js实现了每秒21k数据报的稳定吞吐量,比Java慢十倍.
我的第一个猜测是sendOne为每个刻度线放两个,看它是否会使吞吐量加倍:
function sendForever() {
send();
send(); // second send
setImmediate(sendForever);
}
Run Code Online (Sandbox Code Playgroud)
但它并没有改变吞吐量.
我在GitHub上有一个存储库,其中包含完整的代码:
https://github.com/luciopaiva/udp-perf-js
只需将其克隆到您的机器,cd进入该文件夹并运行:
node client
Run Code Online (Sandbox Code Playgroud)
我想开一个关于如何在Node.js中改进这个测试的讨论,如果有一些方法我们可以增加Node.js的吞吐量.有任何想法吗?
PS:对于那些感兴趣的人,这里是Java部分.
该测试存在飞越缺陷。UDP 不保证任何内容的传送,也不保证在发生错误时会给出任何错误。
您的应用程序可以从 Java 应用程序以 1GB/s 的速度发送 1000k 数据报/秒,但 90% 的数据报从未到达目的地...目的地甚至可能没有运行。
如果您想要进行任何类型的 UDP 测试,则需要两个应用程序,每一端一个。发送编号数据报 1、2、3... 并检查发送的内容和接收的内容。请注意,UDP 不保证消息的任何顺序。
内核以特殊方式管理本地主机网络。有专用于它的巨大缓冲区和更高的限制,没有流量经过任何网卡或驱动程序。这与真正发送数据包有很大不同。
当仅在本地主机上完成测试时,测试可能看起来还不错。当一切真正通过任何物理基础设施时,预计一切都会严重失败。
PC1 <-----> switch <-----> PC2
Run Code Online (Sandbox Code Playgroud)
比方说,同一个房间里有两台计算机通过交换机连接。在如此简单的设置上实现 10k/s UDP 数据报而不随机丢失消息将是一个不小的壮举。
这只是同一个房间里的两台计算机。在互联网和长途上情况可能会更糟。
| 归档时间: |
|
| 查看次数: |
1747 次 |
| 最近记录: |