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

我在Node.js中为多用户人工智能应用程序构build了多个套接字服务器应用程序。 我们正在寻找每个盒子1K到10K的活动sockets连接。 但是,即使空闲并且有0个活动连接,我的一些服务器在Unix上运行时也会消耗50-100 MB的内存。 我敢肯定,像C#或C ++这样的明智的平台,这应该是接近0 MB。 所以我们正在考虑把一个港口变成一个“更好”的平台。 现在让我澄清我的用例:

  • 这不是一个“networking服务器”。 没有文件被送达。
  • 我们做大量的CPU密集型数据处理,并且某些部分已经被移植到C ++,并通过本地模块进入节点。
  • 我们不需要访问太多的I / O(在大多数情况下,访问一些文件,在某些情况下,没有,我们也不使用RDBMS)

我们去节点,因为它是Unix友好(不像.NET),似乎易于使用。 但是由于目前的内存消耗,我们需要评估其他选项。 许多人已经将Node.js与ASP.NET进行了比较,但我需要用C#或C ++构build套接字服务器。

我有与.NET和C ++的重要经验。 有像SuperSocket (由Redgate和Telerik使用)在.NET中处理所有低层次的东西的库。 我将不得不为C ++find一个类似的套接字框架。

所以把这一切放在一起,使用.NET或C ++优于Node.js有什么优势? 考虑到我的服务器高度受CPU限制(不受I / O限制),使用.NET / C ++的好处是显着的,还是应该坚持使用Node.js? 有关将Node.js应用程序移植到C#或C ++的其他意见?

赏金:我需要在C#和/或C ++中build议和推荐的套接字服务器库/实现/示例应用程序。 必须是开源的。 我需要它是高性能,asynchronous和无错的。 必须支持二进制数据传输。 必须在Windows上运行。 Unix是一个奖金。

我们正在寻找每个盒子1K到10K的活动sockets连接

这里的瓶颈不在于编程语言或技术,而在于硬件和操作系统的支持。 限制并发套接字数量的东西基本上就是你正在运行的机器。 但是,从我的经验来看,C ++的确定性对象生命周期对于支持大量的并行操作系统资源可以起到很大的帮助。

这不是一个“networking服务器”。 没有文件被送达。

在我的专业工作中,我做了一些Node.js,我做了一些C#,但主要是C ++。 即使使用node.js作为Web服务器,除了语言本身之外,大多数客户端和服务器代码并没有太多共同之处。 web服务器大都处理buisness逻辑,而客户端则是交互处理获取和呈现数据。 所以,我认为node.js作为一个web服务器的主要优势在于它使纯粹的JS开发人员能够编写服务器端,而不使用他们不熟悉的语言/技术。

我们做大量的CPU密集型数据处理,并且某些部分已经被移植到C ++,并通过本地模块进入节点。

是的。 使用强types语言可以在这里创造奇迹。 没有redunadand运行时parsing。

我们不需要访问太多的I / O(在大多数情况下,访问一些文件,在某些情况下,没有,我们也不使用RDBMS)

那么,我觉得node.js在某种程度上处理IO比其他技术更好。 这是完全错误的。 Node.js的主要function是默认情况下IO是asynchronous的。 但Node.js没有发明任何车轮。 你在Java(aka Java.NIO),C#(async / await)和C ++(像epoll / IOCompletionPort这样的本地东西,或者像Boost.ASIO / CPP-rest,Proxygen等更高的东西)

我们去节点,因为它是Unix友好(不像.NET)

.Net Core是一种相对较新的技术,.Net可以运行在基于Unix的系统上(比如linux)

我将不得不为C ++find一个类似的套接字框架。

Boost.ASIO,或者自己写点东西,其实并不难。

所以把这一切放在一起,使用.NET或C ++优于Node.js有什么优势?

更好的CPU使用率:因为C ++和C#是强types语言,而C ++是静态编译语言,所以编译器有很大的优势来优化CPU广泛的作业。

更低的内存占用:通常是因为强types语言具有更小的对象,而没有在场景中保留大量元数据的开销。 与C ++,有堆栈分配和范围对象的生命周期通常内存占用低。 再次,这取决于任何语言的代码质量。

没有callback地狱:C#有任务和asynchronous等待。 C ++有期货/承诺,一些编译器(又名VC ++)也支持等待。 asynchronous代码简单地变成纯粹的乐趣,写callback相反。 是的,我知道JS的承诺和新的asynchronous/等待的东西,但它们相对于.Net实现相对较新。

编译器检查:由于必须编译C#和C ++,所以在编译时会捕获很多愚蠢的错误。 没有“undefiend不是一个函数”或者“不能读取undefined的属性”。

除此之外,这几乎是一个select的问题。

我们做大量的CPU密集型数据处理

Node.js可能从一开始就是错误的select,它可能永远不会匹配C ++服务器的性能。 但是,如果你正在做的事情可以相当接近。 另外,编写好的C ++和完整的系统重写是困难和耗时的。 所以,我想给你一些坚持Node.js的理由,或者至less在你移动之前完全用尽你所有的select。

我的服务器消耗50-100 MB

你在使用Node.js v0.12吗? 使用Node.js v4.2 LTS,空闲的Node.js服务器应该使用大约20 MB的内存。 (由于V8,它可能永远不会接近0 MB)您是否检查过内存泄漏?

每盒1K到10K有源sockets连接

这应该很容易实现。 如果你使用的是最stream行的socket.io库,这里有一些相关的基准。

在使用一个内核的3.3 GHz Xeon X5470上,根据并发级别,每秒​​最大消息发送速率大约为9,000-10,000。

来自: http : //drewww.github.io/socket.io-benchmarking/ (因为所有这些连接同时保持活跃,CPU使用率更重要)

如果你已经在使用它,并且遇到了问题,可以尝试用SocketClusterreplacesocket.io ,这个更快,更具可扩展性。 replace这应该比完全重写更容易。 这里有一些基准:

运行Linux的8核Amazon EC2 m3.2xlarge实例

在42K,最繁忙的工人的CPU使用率下降到45%

http://socketcluster.io/#!/performance

最后,certificateNode.js几乎可以达到C ++的性能。 看看这个:

服务器使用12G内存

它支持120万个活动websocket连接

https://github.com/smallnest/C1000K-Servers

我的观点是你有平均的性能目标,你应该可以用Node.js轻松实现。 尝试基准( https://github.com/machinezone/tcpkali )并find问题,而不是做一个完整的重写。

NetMQ是zeromq的本地C#端口。

Zeromq是一个轻量级的消息库,如果你想了解消息传递,那么zeromq指南是非常棒的,它也是一本书。 它适用于zeromq和NetMQ。

如果您正在使用Windows并需要处理大量的连接,我不build议使用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