Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redis 为发布/订阅和消息队列中的多个使用者提供消息传递保证_Redis_Rabbitmq_Publish Subscribe_Messaging - Fatal编程技术网

Redis 为发布/订阅和消息队列中的多个使用者提供消息传递保证

Redis 为发布/订阅和消息队列中的多个使用者提供消息传递保证,redis,rabbitmq,publish-subscribe,messaging,Redis,Rabbitmq,Publish Subscribe,Messaging,要求 一个系统经历一些状态变化,系统的多个其他部分必须知道这一点(让我们称之为观察者),以便他们可以根据当前状态执行一些操作,如果一些观察者不在线(由于一些问题,目前没有监听,但很快就会回来),观察者的操作很重要,在所有观察者都获得该消息之前,不应丢弃该消息 试图通过发布/订阅模型实现这一点,以下是我的发现(如果这种理解是错误的,请更正)- 发布者在特定主题上创建事件,多个订阅者可以使用相同的消息。此模型要么不提供传递保证(在redis中),要么保证一次传递(使用消息队列),即当一个消费者确认消

要求

一个系统经历一些状态变化,系统的多个其他部分必须知道这一点(让我们称之为观察者),以便他们可以根据当前状态执行一些操作,如果一些观察者不在线(由于一些问题,目前没有监听,但很快就会回来),观察者的操作很重要,在所有观察者都获得该消息之前,不应丢弃该消息

试图通过发布/订阅模型实现这一点,以下是我的发现(如果这种理解是错误的,请更正)-

发布者在特定主题上创建事件,多个订阅者可以使用相同的消息。此模型要么不提供传递保证(在redis中),要么保证一次传递(使用消息队列),即当一个消费者确认消息时,消息被丢弃(rabbitmq)

示例

在数据库中创建一个新的人员配置文件实体

现在,

  • 后台验证服务必须知道这一点才能触发验证过程
  • 订阅服务必须知道这一点,才能向用户添加默认订阅
  • 现在这两个任务都很重要,互不相关,可以并行运行

    现在在队列模型中,如果订阅服务由于某种原因关闭,BG验证过程会确认消息,消息将从队列中删除,或者如果消息像大多数发布/订阅一样被触发并忘记,则无论如何都不能保证这两种服务都能交付

    还有一点是,这两个任务都是不相关的,不需要一个接一个地触发


    简言之,我的需要是确保所有消费者都得到相同的信息,并且他们应该能够单独确认,只有在所有消费者都确认上述任何一种方法都不能做到这一点后,才应该删除该信息


    我有什么遗漏吗?我应该如何处理这个问题?

    正如您所提到的,它不是您可以通过Redis发布/订阅数据结构来控制的

    但你可以很容易地做到这一点

    Streams将允许您使用
    XADD
    命令发布消息,然后控制哪些消费者正在处理消息,并确认消息已被处理

    您可以查看这些示例应用程序,它(在Java中)提供了以下示例:

    • 发布和使用消息
    • 创建多个消费群体
    • 管理异常
    链接:

    • (展示如何使用ADD/ACK/PENDING/CLAIM并使用Redis Streams和SpringData构建防错流应用程序的项目)

    正如您所提到的,它不是您可以用Redis发布/订阅数据结构控制的

    但你可以很容易地做到这一点

    Streams将允许您使用
    XADD
    命令发布消息,然后控制哪些消费者正在处理消息,并确认消息已被处理

    您可以查看这些示例应用程序,它(在Java中)提供了以下示例:

    • 发布和使用消息
    • 创建多个消费群体
    • 管理异常
    链接:

    • (展示如何使用ADD/ACK/PENDING/CLAIM并使用Redis Streams和SpringData构建防错流应用程序的项目)

    此方案由明确支持,它将“交换”与“队列”分开:

    • 发布者总是向“交换”发送消息,这只是一个无状态路由地址;它不需要知道消息应该在哪个队列中结束
    • 消费者总是从“队列”中读取消息,该队列包含其自己的消息副本,而不管消息来自何处
    • 多个使用者可以订阅同一个队列,并且每条消息将只传递给一个使用者
    • 至关重要的是,exchange可以将同一消息路由到多个队列,每个队列都将收到消息的副本
    这里要理解的关键是,当我们谈论消费者“订阅”队列时,“发布订阅”设置的“订阅”部分实际上是从exchange到队列的路由

    因此RabbitMQ发布子系统可能如下所示:

  • 在数据库中创建一个新的人员配置文件实体
  • 此事件作为消息发布到路由键为“entity.profile.created”的“events”
  • exchange将邮件副本路由到多个队列:
    • “验证服务”队列已绑定到此exchange,以接收与“entity.profile.#”匹配的所有邮件的副本
    • “订阅\设置\服务”队列已绑定到此exchange,以接收与“entity.profile.created”匹配的所有邮件的副本
  • 使用脚本不知道有关此路由的任何信息,它们只知道与它们相关的事件的消息将出现在队列中:
    • 验证服务在“验证服务”队列中拾取消息副本,处理并确认它
    • 订阅设置服务在“订阅设置服务”队列中拾取消息副本,处理并确认它
  • 如果有多个使用脚本查看同一队列,则它们将共享该队列上的消息,但仍然完全独立于任何其他队列
  • 以下是显示此场景的屏幕截图:


    此方案由明确支持,它将“交换”与“队列”分开:

    • 发布者总是向“交换”发送消息,这只是一个无状态路由地址;它不需要知道消息应该在哪个队列中结束
    • 消费者总是从一个“队列”中读取消息,该队列包含其消息