为啥使用 PUBSUB 订阅时无法 PING?
Posted
技术标签:
【中文标题】为啥使用 PUBSUB 订阅时无法 PING?【英文标题】:Why can I not PING when Subscribed using PUBSUB?为什么使用 PUBSUB 订阅时无法 PING? 【发布时间】:2014-07-16 13:48:22 【问题描述】:我在 Azure 上使用 PUBSUB 时遇到问题。
Azure 防火墙将关闭空闲时间不限的连接。时间长度有很多争论,但人们认为大约是 5 到 15 分钟。
我使用 Redis 作为消息队列。为此,ServiceStack.Redis 库提供了一个订阅以下频道的 RedisMqServer:
mq:topic:in
在后台线程上,它阻塞从套接字接收数据,等待从 Redis 接收消息。问题是:
如果等待 Redis 消息的套接字空闲了任意时间长度,Azure 防火墙 静默关闭连接。我的应用程序不知道,因为它是 现在等待关闭的连接(就其而言 打开)。后台线程被有效挂起。
我曾想过实现某种 Keep Alive,即等待消息一分钟,但如果未收到消息,则 PING 服务器有两个目标:
-
通过告诉 Azure 这个连接是保持连接打开
仍在使用中。
检查连接是否已经关闭,如果是
重新开始并重新订阅。
但是,当我实现这个时,我发现我不能在订阅时使用 PING 命令??不知道为什么会这样,但有人有替代解决方案吗?
我不想定期退订和重新订阅,因为我可能会错过消息。
我已阅读以下文章:http://blogs.msdn.com/b/cie/archive/2014/02/14/connection-timeout-for-windows-azure-cloud-service-roles-web-worker.aspx,其中介绍了 Azure 负载均衡器如何在 4 分钟后断开连接。但是即使我可以保持连接处于活动状态,如果连接因其他原因(redis 节点关闭)而被终止,我仍然需要实现重新启动订阅的第二个目标。
【问题讨论】:
【参考方案1】:我刚刚在此提交中的 Redis 的 unstable
分支中以 Pub/Sub 模式实现了 PING 支持:https://github.com/antirez/redis/commit/27839e5ecb562d9b79e740e2e20f7a6db7270a66
这将在接下来的几天内向后移植到 Redis 2.8 稳定版中。
【讨论】:
太棒了!我将在 PUBSUB 期间将此功能添加到 PING Redis 客户端,作为 ServiceStack.Redis 中的保持活动功能。我使用 Azure 托管的 Redis 作为我的服务器,因此我无法控制它们的版本,但我会密切关注并尽快使用它。非常感谢!【参考方案2】:这是由于我们在 Azure 中托管 Redis 时处理 keepAlive 数据包造成的。我们很快就会解决这个问题。
此外,如上所述,您可以通过 ping 手动保持连接。对于 sub/pub 连接,您今天可以使用的一个技巧是取消订阅随机频道。 (这就是 StackExchange.Redis 所做的)
【讨论】:
感谢迈克的澄清。我发现如果我使用 B2(非复制)提供超时问题并没有那么糟糕,但是当我使用 S1(复制、共享硬件)时,情况会更糟。不确定这是否有用。我会考虑暂时将该功能添加到我的 ServiceStack.Redis 分支中。【参考方案3】:当客户端订阅时,该连接基本上被阻止用于传出命令,因为它用于侦听传入消息。一种可能的解决方法是在频道上发布定期的 keepalive 消息。
【讨论】:
多么巧合 - antirez 今天已经修复了这个问题:github.com/antirez/redis/commit/… :)以上是关于为啥使用 PUBSUB 订阅时无法 PING?的主要内容,如果未能解决你的问题,请参考以下文章
无法从本地假 PubSub 服务器执行请求订阅的 GET 请求
尝试在 Google PubSub python 中创建主题订阅时出错
Google PubSub 订阅无法从 StatusCode.UNAVAILABLE [code=8a75] 错误中恢复