如何避免消息队列被淹没?

Dim*_* C. 5 language-agnostic concurrency multithreading synchronization

我正在开发一个应用程序,该应用程序分为瘦客户端和服务器部分,通过 TCP 进行通信。我们经常让服务器向客户端进行异步调用(通知)以报告状态变化。这可以避免服务器浪费太多时间来等待客户端的确认。更重要的是,它避免了死锁

这种死锁可能会发生如下。假设服务器将同步发送状态更改通知(请注意,这是一个有点构造的示例)。当客户端处理通知时,客户端需要同步向服务器询问信息。但是,服务器无法响应,因为他正在等待问题的答案。

现在,通过异步发送通知可以避免这种死锁,但这会带来另一个问题。当异步调用的速度超过处理速度时,调用队列就会不断增长。如果这种情况持续足够长的时间,呼叫队列将完全满(充满消息)。我的问题是:发生这种情况该怎么办?

我的问题可以总结如下。我真的必须在不阻塞发送通知(冒着淹没消息队列的风险)和发送通知时阻塞(冒着引入死锁的风险)之间做出选择吗?有什么技巧可以避免消息队列泛滥吗?

注意:重复一遍,发送通知时服务器不会停止。它们是异步发送的。

注意:在我的示例中,我使用了两个通信进程,但两个通信线程也存在同样的问题。

Chr*_*fer 2

如果您遇到持续的拥塞问题,除了优雅地失败并通知客户端无法发布新消息之外,您几乎无能为力;然后由客户端来维护待发布消息的积压。

引入优先级队列并使用消息过期/过滤可以让您释放队列中的空间,但这实际上只是推迟了问题的发生。如果可能的话,您还可以聚合消息或忽略重复的消息,但问题似乎并不是队列本身。(更不用说更复杂的队列逻辑可能会消耗宝贵的资源,而这些资源本来可以更好地用于实际处理消息。)

根据服务器端的操作,您可以为长时间计算引入结果散列、将某些类型的消息卸载到专用设备、检查服务器是否等待 I/O 操作的时间过长,以及无数其他技术。如果可能的话,至少尝试找出哪些消息导致拥塞。

哦,还有业务解决方案:将估计开发时间的成本与更好的硬件的成本进行比较,并得出结论,您应该购买一台更强大的服务器(或额外的服务器)。