【问题标题】:Maintaining an open Redis PubSub subscription with Booksleeve使用 Booksleeve 维护开放的 Redis PubSub 订阅
【发布时间】:2013-10-22 22:26:31
【问题描述】:

我正在使用 Redis 发布订阅通道将消息从工作进程池发送到我的 ASP.NET 应用程序。收到消息后,我的应用程序会使用 SignalR 将消息转发到客户端的浏览器。

我发现 this solution 可以保持与 Redis 的开放连接,但它在重新创建连接时不考虑订阅。

我目前正在我的 Global.asax 文件中处理 Redis 发布订阅消息:

public class Application : HttpApplication
{
    protected void Application_Start()
    {
        var gateway = Resolve<RedisConnectionGateway>();
        var connection = gateway.GetConnection();
        var channel = connection.GetOpenSubscriberChannel();

        channel.PatternSubscribe("workers:job-done:*", OnExecutionCompleted);
    }

    /// <summary>
    /// Handle messages received from workers through Redis.</summary>
    private static void OnExecutionCompleted(string key, byte[] message)
    {
        /* forwarded the response to the client that requested it */
    }
}

当当前的 RedisConnection 出于某种原因关闭时,就会出现问题。最简单的解决方案是在连接重置后从RedisConnectionGateway 类中触发一个事件,然后使用新的RedisSubscriberChannel 重新订阅。但是,在重置连接时发布到通道的任何消息都将丢失。

是否有处理这种情况的推荐方法示例?

【问题讨论】:

  • 我的解决方案确实返回一个 Redis 连接,如果它已经打开,或者如果没有打开一个。我相信在“常规使用”中,连接将保持打开状态,您不会将其丢弃在您的 PubSub 架构中。在连接因某种原因关闭的罕见情况下,您将获得一个新连接,是的 - 在连接重置时发布到通道的消息将丢失。但它的时间很短,而且它不应该定期发生。无论如何,让我们让 BookSleeve 的作者在此突出显示 (CC @marcgravell)。
  • @OferZelig 谢谢,但@someone 不起作用,除非我已经以某种方式参与了该帖子;p
  • @MarcGravell 我不知道;无论如何:1)如何与另一个 SE 用户交流以引起他/她对某事的注意?我的意思是 - 在 SE 网站内,而不是通过查看个人资料并访问他/她的博客等; 2)您可以在 SE 中实现识别此问题并发出警报的功能(xxx 模式,其中 xxx 是已知的 SE 用户名)。谢谢!
  • SE 显示名称不强制为唯一。根据设计,您只能使用@username 来吸引已经参与问题的人。在 SO 中,帖子是重要的单位。

标签: asp.net asp.net-mvc redis booksleeve


【解决方案1】:

是的,如果连接中断(网络不稳定、重新控制等),那么您将需要重新应用您所做的任何订阅。重新连接和重新订阅的事件是很正常的,与我们在 SE/SO 上使用的没有太大区别(除了我们通常跟踪更精细的订阅,并有一些处理所有这些的包装代码)。

是的,在您的连接中断时发布的所有事件都已消失。这就是 redis pub/sub 的本质;它不保证交付给断开连接的客户端。要么使用 确实 承诺这一点的工具,要么使用 redis 来驱动队列 - 向/从列表的两端推送/弹出通常是一个合理的选择,并确保不会丢失任何东西(只要因为您的软件在从列表中弹出它后不会删除它)。如果有帮助,我的列表中有一个添加阻塞弹出方法的请求——它们完全破坏了多路复用器的意图,但在某些情况下它们确实有用,所以我不反对添加它们。

【讨论】:

  • 我不介意看到添加到 API 的阻塞弹出方法。现在我的 Web 项目正在使用 Booksleeve,但是为我的 Web 应用程序提供服务的工作人员依赖 ServiceStack.Redis 来获取阻塞弹出 API。
  • @Justin 它应该被添加 - 希望这周
  • 那太棒了!谢谢!
  • @MarcGravell 它仍然相关吗?经过一些测试(“clinet kill type pubsub”,“client publish”)似乎SE.Redis在重新连接后重新订阅了事件,你能确认吗?
  • .net core web api怎么样,如何让订阅者永远运行?
猜你喜欢
  • 2012-01-28
  • 2012-05-01
  • 2013-03-29
  • 2016-03-13
  • 2021-02-07
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多