将套接字服务器从 Node.js 移植到 C#
Porting socket server from Node.js to C#
我在 Node.js 中为多用户人工智能应用程序构建了多个套接字服务器应用程序。我们正在研究每个盒子 1K 到 10K 的活动插座连接。但是,即使在空闲且活动连接为 0 时,我的一些服务器在 Unix 上运行时也会消耗 50-100 MB 的内存。我敢肯定,对于像 C# 或 C++ 这样的合理平台,这应该接近 0 MB。因此,我们正在考虑移植到"更好"的平台。现在让我澄清一下我的用例:
- 这不是"网络服务器"。不提供任何文件。
- 我们做了大量的CPU密集型数据处理,某些部分已经被移植到C++并通过本机模块拉入节点。
- 我们不需要访问太多的I/O(在大多数情况下访问几个文件,在某些情况下没有,我们也不使用RDBMS(
我们使用node,因为它对Unix友好(与.NET不同(,并且看起来很容易使用。但是对于其当前的内存消耗,我们需要评估其他选项。许多人将 Node.js 与 ASP.NET 进行了比较,但我需要用 C# 或 C++ 构建套接字服务器。
我在 .NET 和 C++ 方面拥有丰富的经验。有像SuperSocket(Redgate和Telerik使用(这样的库可以处理.NET中的所有低级内容。我将不得不为C++找到一个类似的套接字框架。
综上所述,与 Node.js 相比,使用 .NET 或 C++ 的优势是什么?考虑到我的服务器高度受 CPU 限制(不受 I/O 限制(,使用 .NET/C++ 的好处是显着的还是我应该坚持使用 Node.js?关于将 Node.js 应用程序移植到 C# 或 C++ 的任何其他评论?
赏金:我需要建议和推荐的套接字服务器库/实现/C#和/或C++示例应用程序。必须是开源的。我需要它是高性能、异步和无错误的。必须支持二进制数据传输。必须在 Windows 上运行。Unix是一个奖励。
我们正在研究每个盒子 1K 到 10K 的活动插座连接
这里的瓶颈不是编程语言或技术,而是硬件和操作系统支持。 限制并发套接字计数量的因素基本上是运行的计算机。 然而,根据我的经验,C++的确定性对象生存期可以极大地帮助支持大量并发操作系统资源。
这不是"网络服务器"。不提供任何文件。
我做过一些 Node.js在我的专业工作中,我做过一些 C#,但主要是C++。 即使使用 node.js 作为 Web 服务器,除了语言本身之外,大多数客户端和服务器代码也没有太多共同点。 Web服务器主要处理业务逻辑,而客户端处理交互获取和呈现数据。所以,我认为node.js作为Web服务器的主要优点是它使纯JS开发人员能够在不使用他们不熟悉的语言/技术的情况下编写服务器端。
我们做了很多CPU密集型数据处理,某些部分有 已经移植到 C++ 并通过本机模块拉入 Node。
是的。 使用强类型语言可以在这里创造奇迹。 没有冗余和运行时解析。
我们不需要访问太多的I/O(在大多数情况下,一些文件是 访问,在某些情况下没有,我们也不使用 RDBMS(
嗯,我觉得有一个神话,即节点.js以某种方式比其他技术更好地处理 IO。 这是完全错误的。 Node.js的主要特点是默认情况下,IO是异步的。 但Node.js没有发明任何轮子。 你在Java(又名Java.NIO(,C#(async/await(和C++(作为epoll/IOCompletionPort等本机内容(中有异步IO, 或一些更高的东西,如Boost.ASIO/CPP-rest,Proxygen等(
我们使用node,因为它对Unix友好(与.NET不同(
.Net Core是一种相对新技术,.Net可以在基于Unix的系统(如linux(上运行。
我将不得不为C++找到一个类似的套接字框架。
Boost.ASIO,或者自己写点东西,真的没那么难。
因此,将所有这些放在一起,使用.NET或.NET的优势是什么 C++ over Node.js?
更好的 CPU 使用率:由于 C++ 和 C# 是强类型语言,而C++是静态编译的语言,因此编译器在优化 CPU 大量作业方面存在巨大的机会。
内存占用量更低:通常是因为强类型语言具有较小的对象,而不会产生将大量元数据保留在 scences 后面的开销。对于C++,具有堆栈分配和作用域对象生存期通常内存占用量较低。同样,这取决于任何语言的代码质量。
没有回调地狱:C# 有任务和异步等待。C++有期货/承诺,一些编译器(又名VC++(也支持等待。异步代码只是变得纯粹的乐趣,因为与回调相反。是的,我确实知道JS承诺和新的async/await的东西,但与.Net实现相比,它们是相对新的。
编译器检查:由于必须编译C#和C++,因此在编译时捕获了许多愚蠢的错误。 没有"Undefiend 不是函数"或"无法读取未定义的属性"。
除此之外,这几乎是一个选择问题。
NetMQ 是 zeromq 的原生 C# 端口。
Zeromq是轻量级的消息传递库,如果你想了解消息传递,zeromq指南是一个很好的,它也是一本书。它适用于zeromq和NetMQ。
如果您使用的是Windows并且需要处理大量连接,我不建议使用zeromq,因为它不使用IOCP。
NetMQ在Windows上使用IOCP,并且可以在Windows和Linux上运行。
披露 - 我是NetMQ的作者和zeromq(libzmq(项目的维护者。
[1] https://github.com/zeromq/netmq
[2] http://netmq.readthedocs.io/en/latest/
[3] http://zguide.zeromq.org/page:all
[4] http://www.amazon.com/ZeroMQ-Messaging-Applications-Pieter-Hintjens/dp/1449334067/ref=sr_1_1?ie=UTF8&qid=1462550951&sr=8-1&keywords=zeromq
我们做大量的CPU密集型数据处理
Node.js 可能从一开始就是错误的选择,它可能永远无法与C++服务器的性能相提并论。但是,如果您做对了,它可以非常接近。此外,编写好的C++和完全重写系统既困难又耗时。所以,我想给出一些理由让你坚持使用Node.js或者至少在你搬家之前完全用尽你所有的选择。
我的服务器占用 50-100 MB
您是否正在使用 Node.js v0.12?使用 Node.js v4.2 LTS,空闲 Node.js 服务器应使用大约 20 MB 的内存。(由于 V8,它可能永远不会接近 0 MB(您是否检查过内存泄漏?
每盒 1K 至 10K 有源插座连接
这应该很容易实现。如果您使用的是最受欢迎的socket.io
库,这里有一些相关的基准测试。
在使用单核的 3.3 GHz 至强 X5470 上,每秒发送的最大消息速率约为 9,000–10,000,具体取决于并发级别。
从: http://drewww.github.io/socket.io-benchmarking/(由于所有这些连接都同时保持活动状态,因此 CPU 使用率更重要(
如果您已经在使用它并遇到问题,请尝试将socket.io
替换为更快、更具可扩展性的SocketCluster
。替换它应该比完全重写更容易。以下是一些基准:
运行 Linux 的 8 核 Amazon EC2 m3.2xlarge 实例
在 42K 时,最繁忙的工人的 CPU 使用率下降到 45% 左右
http://socketcluster.io/#!/performance
最后,为了证明 Node.js 几乎可以达到C++性能。看看这个:
服务器使用 12G 内存
它支持 1,200,000 个活动的 websocket 连接
https://github.com/smallnest/C1000K-Servers
我的观点是,你应该有平均的性能目标,你应该能够用 Node .js毫不费力地达到。尝试基准测试(https://github.com/machinezone/tcpkali(并找到问题,而不是完全重写。
- 在 ubuntu 上安装 node js pulsar 客户端
- Node.js fs.open() 在尝试打开 4 个以上的命名管道 (FIFO) 后挂起
- 在 node.js 中将缓冲区从 C++ 转换为 UTF-8 字符串
- 使用 Node.js N-API 调用 C 函数时,不会显示预期的输出
- 如何使用 v8 本机插件将 C++ 数组交付到 Node.js
- C++ 和 node.js 之间的 RSA 加密
- node.js Nan:在函数C++调用 JavaScript 回调
- 迭代 Napi::对象属性(键)在 Node.js C++ N-API 中
- 上传大文件并解析时使用 Node.js v10.15.1 时出现致命错误
- 如何在 Node.js 中解压缩 c# 打包结构
- 使用 Node.js 调用child_process与从 C 调用子进程并创建C++绑定以从 node.js 调用
- 我们如何访问 Node.js 应用程序之外的内存?
- 我正在c 中的buidling node.js绑定
- 以有效的方式从 Node .js运行 C 或C++代码
- node.js:如何从C 模块中产生
- 如何编译 node.js for CentOS 6.10 (库问题)
- 如何使用 Node.js 开发一个侦听器来接收许多车辆跟踪数据(通过 TCP)
- 使用 N-API 将数据流式传输到 Node.js C++ 插件中
- 在构建Node.js/Node-webkit插件时,通过binding.gyp将.cpp文件编译为Objective-C
- 终端服务器上的IPC,带有一个nw.js/node.js/node-namemodule(C++)