如何防止一个不良客户端使整个服务崩溃?
我的情况基本上是这样的:一个WCF服务正在运行,并且具有客户端回调,其单向通信非常简单,与此类似:
public interface IMyClientContract
{
[OperationContract(IsOneWay = true)]
void SomethingChanged(simpleObject myObj);
}
我正在从服务端向大约50个并发连接的客户端中的一个潜在地以每秒数千次的速度调用此方法,并希望延迟尽可能低(<15毫秒最好)。这样做一切正常,直到我在连接到服务器的某个客户端应用程序上设置断点,然后所有东西都停止工作,在大约2-5秒钟后服务挂起,并且其他所有客户端在大约30秒左右没有收到任何数据,直到服务注册了连接故障事件并断开有问题的客户端。之后,所有其他客户端继续接收消息。
我已经研究了serviceThrottling、并发优化、设置线程池最小线程、WCF秘密酱和整个过程,但归根结底,这篇文章MSDN-WCF essentials,单向调用,回调和事件描述了我正在遇到的问题,但并没有真正提出建议。
允许回调契约操作配置为单向操作的第三个解决方案可以使服务安全地回调客户端。这样做可以使服务在并发设置为单线程时进行回调,因为不会有任何回复消息争夺锁。
但是在文章的前面,它描述了我所看到的问题,只是从客户端的角度描述。
当单向调用到达服务时,它们可能不会一次性分派并可能在服务端排队以一个接一个地分派,这完全取决于服务配置的并发模式行为和会话模式。服务愿意排队多少消息(无论是单向还是请求-回复)是由配置的通道和可靠性模式确定的。如果排队的消息数超过了队列的容量,那么即使发出单向调用,客户端也会被阻塞。
我只能假设相反的情况是真的,即客户端的排队消息数已超过队列容量,线程池现在被尝试调用该客户端的线程填满,现在所有线程都被阻塞。
如何正确处理此问题?我应该研究一种方法来检查每个客户端在服务通信层中排队的消息数,并在达到某个限制后中止它们的连接吗?
似乎如果WCF服务本身在队列填充时被阻塞,则我在服务内部实施的所有异步/单向/快速执行策略仍将被阻塞,每当一个客户端的队列被填满时。