将套接字服务器从 Node.js 移植到 C#

Porting socket server from Node.js to C#

本文关键字:js Node 套接字 服务器      更新时间:2023-10-16

我在 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(并找到问题,而不是完全重写。