是否有可能创建具有数千个长时间运行的TCP连接的可伸缩WCF服务?

时间:2011-06-04 01:55:21

标签: c# wcf .net-4.0 nettcpbinding

我正在尝试创建一个WCF服务,其中数千(~10,000)个客户端可以通过双工NetTcpBinding连接很长一段时间(几周,也许几个月)。

经过一些阅读后,看起来在IIS中托管比自定义应用程序或Windows服务更好。

是否可以使用WCF来接受这种服务,甚至可能?如果是这样,我可以在哪里遇到限制或性能问题,例如增加WCF ListenBacklog& MaxConcurrentConnections?

谢谢!

1 个答案:

答案 0 :(得分:5)

为什么需要维持打开的连接数周/月?这将引入许多复杂性,超时处理,错误处理,重新创建连接等。我甚至怀疑这将工作。

Net.tcp连接使用传输会话,导致WCF服务的PerSession实例化 - 单个服务实例服务器在整个会话期间(在您的情况下为几周或几个月)所有请求和生命=实例和整个内容仍然在记忆中。任何中断或未处理的异常都将中断通道并关闭会话=所有会话的本地数据都将丢失,客户端必须创建新代理以再次启动新会话。此外,任何超时(默认为20分钟不活动)都将关闭会话。最后一点 - 根据业务逻辑的复杂性,您可以发现,如果几百个客户端需要同时处理,则单个服务器无法为所有服务器提供服务,而某些客户端将超时(再次中断会话)。允许使用net.tcp进行负载均衡需要负载均衡算法和粘性会话(会话亲和性),整个架构变得更加复杂和脆弱。 net.tcp中的可伸缩性意味着服务可以部署在多个服务器上,但整个客户端会话必须由单个服务器处理(如果服务器死亡,服务器所服务的所有会话也会死亡)。

在IIS / WAS / AppFabric中托管有几个优点,其中两个是健康监控和流程回收。运行状况监视会持续检查工作进程是否仍处于活动状态并且可以处理请求 - 如果不是,它将以静默方式启动新的工作进程并将新的传入请求路由到该进程。进程回收定期回收(默认设置是在29小时后)应用程序域,这使得进程健康并减少内存泄漏。副作用是重新创建进程或应用程序域将终止所有会话。一旦你自己托管服务,你就失去了所有这些服务,所以你必须自己处理服务的健康状况。

修改

恕我直言健康状况信息不必通过TCP发送。这是不需要所有花哨的东西的信息。如果丢失了一些信息,它不会影响任何东西=你可以使用UDP进行健康状态转移。

使用TCP时,您不需要维护代理/会话只是为了保持打开连接。关闭代理时,TCP连接不会立即关闭。它在池中保持打开很短的时间,如果任何其他代理需要连接到同一个服务器,它将被重用(池中的默认空闲超时应为2分钟) - I discussed Net.Tcp transport in WCF in another answer

我不是回调的粉丝 - WCF中的整个概念被过度使用和滥用。保持10.000 TCP连接打开几个月,以防万一有时能将数据发送回几台PC听起来很荒谬。如果需要与PC通信,请在PC上公开服务,并在需要发送命令时调用它。只需添加在PC启动时以及PC即将关闭时调用服务器的功能+添加传输监控信息。

无论如何每分钟发送信息的10,000台电脑 - 这可能会导致您同时收到10.000个请求 - 它可以产生与拒绝服务攻击相同的效果。根据处理时间,您的服务器可能无法处理它们,许多请求将超时。您还可以考虑一些消息队列或发布 - 订阅协议。消息将被传递到队列或主题,服务器将继续处理它们。