代码之家  ›  专栏  ›  技术社区  ›  allan.simon Michael Krelin - hacker

Rabbitmq:工作人员如何“忽略”消息并让其他工作人员处理它

  •  1
  • allan.simon Michael Krelin - hacker  · 技术社区  · 6 年前

    这是我当前的架构

    我有一堆物联网设备,它们通过原始双工持久TCP连接到我的“worker”的1个实例,该实例连接到RabbitMQ队列

    我的出版商发布了一些类似的消息

    {
       "iot_device_name" : "A",
       "command" : "reboot"
    }
    

    然后,工人可以映射 iot_device_name 到TCP套接字。

    所有这些都工作得很好,但如果我们想添加HA并扩展一点,最好有4个worker实例。负载平衡TCP问题不是问题(对于HaProxy或Nginx)。

    现在的问题是如何分割队列部分的负载,因为工作人员处理的物联网设备列表是动态的(即设备可以断开连接并重新连接到其他工作人员)

    那么,有没有一种方法可以让员工说:“嗯,不,我不能处理这条消息,因为我不知道这个设备,给我一个其他的”,这样其他员工就可以处理它了?

    其他可能有用的信息:

    • 工人们都在同一个网络中,这与出版商的情况相同
    • 工作人员的数量不是动态的,即使我们推测未来几年的设备数量,8个工作人员也会让我们走得很远,因为它只是路由消息/转码消息,所以他们的cpu负载是荒谬的。
    1 回复  |  直到 6 年前
        1
  •  1
  •   Olivier    6 年前

    因此,如果我正确理解了您的体系结构,那么您可以将命令发送到发布服务器的一侧,并将其推送到rabbitmq中。 在用户端,您有多个工作线程,消息被调度到这些工作线程,每个工作线程都有一组连接到它的设备。

    如果这确实是您的体系结构,我将为您的rabbitmq配置提出以下建议:

    • 使用直接交换
    • 每个工作进程都有自己的队列(独占),并动态管理exchange与其队列之间的绑定:
      • 每次设备连接到工作线程时,该工作线程都会在其队列和exchange之间添加一个绑定,并将设备的标识符作为路由密钥
      • 每次worker检测到设备不再连接到它时,他都会从rabbitmq配置中删除相关绑定
    • 与检测断开连接的设备相关,我认为一个常见的情况是,在接收到向设备推送的命令时,工作人员会意识到设备不再连接到它,在这种情况下,除了调整绑定之外,工作人员还会使用相同的路由密钥将消息重新发布到相同的交换机,这样它就可以再次被合适的工人吃掉
    • 我还考虑在队列上配置一个TTL,没有必要使用太旧的消息
    • 发布者当然还需要更改消息,包括作为路由密钥的预期设备标识

    我希望这里的建议是有意义的,还有一些其他情况需要考虑:备用交换,以确保在设备没有重新连接到工作进程的(短)时间内,我们不会丢失请求,并且我们无论如何都会得到一个命令,在重新发布的消息中添加一个属性,以确保我们不会在系统中添加无限循环。。。但以上所述应该是实现目标的合理起点