我在Azure上使用PUBSUB有一个问题。
Azure防火墙将关闭任何时间空闲的连接。时间的长短有很多争论,但人们认为大约是5 - 15分钟。
我正在使用Redis作为消息队列。做这个ServiceStack。Redis库提供了一个订阅以下通道的reddismqserver:
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节点关闭)而被杀死,则重新启动订阅。
我刚刚在Redis的unstable
分支中实现了Pub/Sub模式的PING支持:https://github.com/antirez/redis/commit/27839e5ecb562d9b79e740e2e20f7a6db7270a66
这将在接下来的几天内被反向移植到Redis 2.8稳定版。
这是由于我们在Azure中托管Redis时处理keepAlive数据包造成的问题。我们会尽快解决这个问题。
同样,正如上面建议的,您可以通过ping手动保持连接活动。对于订阅/发布连接,你今天可以使用的一个hack是取消订阅一个随机频道。(这就是StackExchange。复述)
当客户端订阅时,该连接基本上被阻止发送命令,因为它用于侦听传入消息。一种可能的解决方法是在通道上定期发布keepalive消息。