V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
laters
V2EX  ›  程序员

有没有 MQTT 高可用负载均衡方案

  •  
  •   laters · 261 天前 · 5347 次点击
    这是一个创建于 261 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前设备连接 MQTT ,多个 MQ server 后台不清楚设备具体连接到了哪个 server 上,导致推送时不知道使用哪个 server 推送消息给设备

    有没有 MQTT 高可用、负载均衡方案

    40 条回复    2024-03-09 19:55:14 +08:00
    GeekGao
        1
    GeekGao  
       261 天前
    可以用 nginx 反向代理做 LB
    laters
        2
    laters  
    OP
       261 天前
    @GeekGao 目前是 nginx upstream 转发, 但问题是不清楚设备具体连接到了哪个 server 上,导致推送时不知道使用哪个 server 推送消息给设备
    GeekGao
        3
    GeekGao  
       261 天前
    @laters 你的这个业务为啥一定要知道使用哪个 server 推送消息给设备?
    uleh
        4
    uleh  
       261 天前
    MQTT 是长连接,这种模式一般要在业务服务前面架一个消息 broker 专门负责连接管理和消息收发。
    me1onsoda
        5
    me1onsoda  
       261 天前
    emqx ?这种商业产品肯定妥妥的,你这种方式不叫集群
    laters
        6
    laters  
    OP
       261 天前
    @me1onsoda 还有类似的吗
    laters
        7
    laters  
    OP
       261 天前
    @uleh 有类似的工具和库吗
    laters
        8
    laters  
    OP
       261 天前
    @GeekGao #3 不然有 1 、2 服务器,客户端只连接了 1 ,如果不知道连接了哪个,怎么推送消息
    GeekGao
        9
    GeekGao  
       261 天前
    @laters 对外暴露的 IP 不就是同一个么。。。
    me1onsoda
        10
    me1onsoda  
       261 天前
    @laters 有哪里不满足需要的吗
    Pony69
        11
    Pony69  
       261 天前
    消息路由?以前工作遇到过类似的。
    laters
        12
    laters  
    OP
       261 天前
    @GeekGao #9 现在只能俩 MQTT server 一起发才能保证客户端能接收到,然后后台不知道用哪个 server 给客户端推送
    laters
        13
    laters  
    OP
       261 天前
    @me1onsoda #10 现在只能俩 MQTT server 一起发才能保证客户端能接收到,然后后台不知道用哪个 server 给客户端推送
    me1onsoda
        14
    me1onsoda  
       261 天前
    @laters 最简陋的方案就是 ng 负载均衡按照设备编号选择连接哪台 broker ,给设备推送消息同理
    uleh
        15
    uleh  
       261 天前
    @laters 5 楼说的 emqx 就是啊
    laters
        16
    laters  
    OP
       261 天前
    @uleh #15 除了这种商业的还有别的方案吗
    mango88
        17
    mango88  
       261 天前
    设备连接后不上报连接信息的吗
    xiyou007
        18
    xiyou007  
       261 天前
    emqx 也不是商用的, 你自己搭一个, 几个 emqx-节点 ,emqx 也搭集群的, 官网有教程, 上面再搭个 haproxy 做负载,
    xiyou007
        19
    xiyou007  
       261 天前
    @xiyou007 说错,emqx 也有免费开源的
    l0wkey
        20
    l0wkey  
       261 天前 via iPhone
    百度之前开源了个 MQTT broker ,好像叫 bifromq
    l0wkey
        21
    l0wkey  
       261 天前 via iPhone
    firechat
        22
    firechat  
       261 天前
    用 redis 记录一下设备连的节点,推送时查一下
    cdlnls
        23
    cdlnls  
       261 天前
    用过 emqx ,还是挺好用的,这个在集群模式下,往任意一个节点推送消息,集群内会自己转发消息到对应的节点。
    如果没有集群的话就难搞了,让客户端在连接之前,告诉服务端连了那个节点,然后服务端在发送消息的时候查询一下记录。

    感觉你这种方案很奇怪,几个 mqtt server 都是相互独立的,假如多个设备连上不同的 server ,这个时候假如设备都订阅了同一个 topic ,你还是要给每个节点发送一次消息。
    xylophone21
        24
    xylophone21  
       261 天前
    @laters 有这个问题是因为你的两个 Broker 没有组成集群,这要看你问题规模.
    1. 如果规模小,就建集群,往哪个 broker 发另一个都能收到的.你可以想象成 Client A 连接了 Broker A,订阅了 a topic, B 连 B,然后给 a topic 发 pub. 问题是集群是有上限和代价的,特别是社区版.
    2. 如果规模大,集群搞不定或者不想买商业版,那就自己控制路由.设备连 Broker 之前,通过接口拿到节点的域名(如何分配看你的业务),然后再连接.这样 Broker 之间没有联系,集群规模的大小就只受你业务能力的限制.当然,为了高可用,实际上你的每个节点还是一个小集群,但这是另外一个故事.
    xylophone21
        25
    xylophone21  
       261 天前
    这样做有一个限制,就是设备和设备之间的互发消息必须少,而且需要你通过业务来转发实现.如果这种转发太多且无规律,实际上你就是一个 Broker 集群了. 一般来说,需要通过你的业务来简化这个模型.比如一般的物联网场景下,设备和设备之间是不需要相互发消息的,但如果你有网关类设备,就又不一样了,需要特殊处理.
    wanniwa
        26
    wanniwa  
       261 天前
    开源中国我记得首页经常有个 mqtt 的一个项目更新的消息,可以去搜搜。
    Curtion
        27
    Curtion  
       261 天前
    emqx , 集群一下就行了
    laters
        28
    laters  
    OP
       261 天前
    @xylophone21 #24 感谢
    laters
        29
    laters  
    OP
       261 天前
    @mango88 是的
    laters
        30
    laters  
    OP
       261 天前
    @xiyou007 #19 有吗, 是不是有限制啊
    laters
        31
    laters  
    OP
       261 天前
    @cdlnls 是的,现在就是没办法知道设备连接到了哪个 server 上,,目前的做法是所有的 MQTT server 都推送消息。
    laters
        32
    laters  
    OP
       261 天前
    @Curtion 但我看是商业版,免费的可以做到吗
    laters
        33
    laters  
    OP
       261 天前
    @wanniwa mica-mqtt 吗?
    laters
        34
    laters  
    OP
       261 天前
    @xylophone21 #24 主要是对于公司而言,不太想买商业版
    vultr
        35
    vultr  
       261 天前
    如果你用的是 mosquitto ,写个程序分析日志,根据用户上线下线事件,把信息写回到后端 api 就解决了。
    ITdream
        36
    ITdream  
       260 天前
    @laters 为什么不是用域名+端口( 1883 | 8883 )连接呢? 我们现在就是 emqx + nginx 搭建的集群,设备端监听了 topic ,一般 topic 都有设备信息,设备端怎么会收不到呢
    laters
        37
    laters  
    OP
       260 天前
    @ITdream emqx 是免费版还是商业版 ?
    isnullstring
        38
    isnullstring  
       260 天前
    有点奇怪的思路,既不想付费上成熟的商业 MQ ,免费的也不知道有没有坑

    按 24 楼 的做法 自己做 Server 之间消息中转 对付下 应该没什么毛病,请求多的话还是上付费版吧
    cnhongwei
        39
    cnhongwei  
       260 天前
    我使用的是开源的 artemis 服务器,看文档说是可以群集,你可以试试。
    https://activemq.apache.org/components/artemis/documentation/latest/clusters.html#clusters
    cheng6563
        40
    cheng6563  
       260 天前
    这问题说容易也容易,给设备定多个 MQTT server 地址而不是用反代做负载均衡,设备根据自己的 SN 取模后连固定的某台 MQTT server 。
    后台发消息也是根据同样的规则找到对应 MQTT server 去。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6075 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 06:18 · PVG 14:18 · LAX 22:18 · JFK 01:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.