【发布时间】:2023-03-19 08:20:01
【问题描述】:
下面的文字是对这个问题的扩展和添加颜色:
如何防止行为不端的客户端取消整个服务?
我基本上有这种情况:WCF 服务启动并运行,客户端回调具有直接、简单的单向通信,与这个没有太大区别:
public interface IMyClientContract
{
[OperationContract(IsOneWay = true)]
void SomethingChanged(simpleObject myObj);
}
我可能每秒从服务调用此方法数千次,最终将有大约 50 个并发连接的客户端,并且延迟尽可能低(一个 客户端应用程序上设置断点,然后在服务挂起 2-5 秒后一切都挂起,并且其他客户端都没有收到任何数据约大约 30 秒,直到服务注册连接故障事件并断开有问题的客户端。此后,所有其他客户端继续愉快地接收消息。
我已经对 serviceThrottling、并发调整、设置线程池最小线程、WCF 秘诀和整个 9 码进行了研究,但归根结底,这篇文章 MSDN - WCF essentials, One-Way Calls, Callbacks and Events 准确描述了我遇到的问题提出建议。
允许服务安全回调客户端的第三种解决方案是将回调合约操作配置为单向操作。这样做可以让服务在并发设置为单线程的情况下进行回调,因为不会有任何回复消息来争夺锁。
但在本文前面,它仅从客户的角度描述了我所看到的问题
当单向调用到达服务时,它们可能不会一次全部调度,可能会在服务端排队等待一次调度,这一切都取决于服务配置的并发模式行为和会话模式。服务愿意排队多少条消息(无论是单向还是请求-回复)是配置的通道和可靠性模式的产物。如果排队的消息数量超过了队列的容量,那么客户端将阻塞,即使发出单向调用也是如此
我只能假设反之亦然,发送到客户端的排队消息数量已超过队列容量,线程池现在充满了试图调用此客户端的线程,这些线程现在都被阻塞了。
处理这个问题的正确方法是什么?我是否应该研究一种方法来检查每个客户端在服务通信层排队的消息数量,并在达到一定限制后中止它们的连接?
几乎看起来,如果 WCF 服务本身在队列填满时阻塞,那么每当一个客户端的队列满时,我可以在服务中实现的所有异步/单向/即发即弃策略仍然会被阻塞。
【问题讨论】:
-
带详细信息的长格式表示赞赏,但执行摘要 / TL;DR 也将不胜感激。
-
您是否检查了性能计数器或跟踪的网络活动以查看在您暂停的客户端上阻止了多少请求?
-
我正在尝试fire-and-forget,这实际上显示了一些进展。我用 catch 块包装同步委托 DynamicInvoke,然后使用 delegate.Target.GetHashCode() 作为当前连接字典的键来识别有问题的客户端通道,使用它来终止客户端连接......不要知道这是否可扩展
-
@Ladislav Mrnka,这是个好主意,如果你知道有一个好方法来计算有多少邮件被阻止,我会这样做
标签: wcf asynchronous concurrency performance fire-and-forget