【问题标题】:emqx MQTT broker doesn’t persist session after restartemqx MQTT broker 重启后会话不持久
【发布时间】:2021-08-22 14:50:03
【问题描述】:

我正在使用 emqx 代理,我想在磁盘上持久化会话,以便在代理因任何原因重启时可以恢复会话。

我做什么:

  • 使用 docker-compose 启动 emqx 代理:
emqx1:
    image: emqx/emqx:v4.0.0
    environment:
      - EMQX_NAME=emqx
      - EMQX_NODE__NAME=emqx.local.node
      - EMQX_HOST=node1.emqx.io
      - EMQX_CLUSTER__DISCOVERY=static
      - EMQX_RETAINER__STORAGE_TYPE=disc
    volumes:
      - emqx-data:/opt/emqx/data
      - emqx-etc:/opt/emqx/etc
      - emqx-log:/opt/emqx/log
    ports:
      - 18083:18083
      - 1883:1883
      - 8081:8081
    networks:
      gateway-api:
        aliases:
        - node1.emqx.io
  • 使用 Paho MQTT 库启动一个 Go 订阅客户端,配置如下。客户端的代码可以在paho repo的“stdinpub”和“stdoutsub”文件夹中找到
clientId = "sub1"
qos = 1
clean = false
topic_subscribe = "topic1"
  • 使用此配置启动 Go 发布客户端并发布消息:
clientId = ""
clean = true

和消息:

qos = 1
retain = false
topic = "topic1"
payload = "test"
  • 然后我断开客户端“sub1”的连接并发送第二条 qos=1 的消息:
qos = 1
retain = false
topic = "topic1"
payload = "test2"

此消息未传递到客户端“sub1”,因此代理将其排队(qos=1)。事实上,如果我重新启动 sub1 客户端,它确实会收到消息“test2”。
但是,如果我在重新启动客户端“sub1”之前重新启动代理,那么“test2”会丢失并且无法交付。

我尝试了将retain 设置为true 的相同测试,即使在代理重新启动后,消息“test2”也能很好地传递。因此代理将保留的消息保存在磁盘上,但不是客户端会话。

知道为什么吗?是否有我应该更改的配置以将客户端会话保留在磁盘上?

【问题讨论】:

  • 保留标志与具有持久会话和 QOS >= 1 订阅的离线客户端的排队消息无关,请勿将两者混为一谈。您应该将消息视为已排队,而不是保留。
  • 另外快速浏览一下文档,表明客户端会话持久性可能是一项企业功能,在代理的基本版本中不可用。
  • @hardillb 感谢对词汇的更正,我更新了我的帖子。可以将文档链接到付费计划中的位置吗?我找不到它
  • 免费版本的文档中没有列出配置选项,但专业文档中有配置多个会话存储选项的选项
  • @cylon86 请参阅Features List - 您正在寻找的功能是“数据持久性”。有相同问题的用户也有许多问题(例如12)。

标签: mqtt emq


【解决方案1】:

如 cmets 中所述。

Client Session 存储是 emqx 付费版的“企业版”才有的功能。

这可以从Feature list 和问题12 也询问该功能中看出。

【讨论】:

    【解决方案2】:

    retainer 消息存储在磁盘中:

    # etc/plugins/emqx_retainer.conf
    
    ## Where to store the retained messages.
    retainer.storage_type = disc_only
    

    EMQ X 开源产品不支持消息在服务器内部的持久化,这是一种架构设计的选择。首先,EMQ X 解决的核心问题是连接和路由;其次,我们认为内置持久性是错误的设计。

    具有内置消息持久性的传统 MQ 服务器,例如广泛使用的 JMS 服务器 ActiveMQ,几乎在每个主要版本中都在重新设计持久性部分。内置消息持久化的设计有两个问题:

    如何平衡内存和磁盘的使用?消息路由是基于内存的,而消息存储是基于磁盘的。 多服务器分布式集群架构下,如何放置Queue,如何复制Queue的消息? Kafka针对上述问题做出了正确的设计:完全基于磁盘分布式Commit Log的消息服务器。

    EMQ X 在设计上将消息路由和消息存储职责分离后,可以在数据层面灵活实现数据复制、容灾备份甚至应用集成。

    在 EMQ X 企业版产品中,您可以通过规则引擎或插件将消息持久化到 Redis、MongoDB、Cassandra、MySQL、PostgreSQL 等数据库和 RabbitMQ、Kafka 等消息队列中。

    【讨论】:

    • 正如问题下的 cmets 中所述,这与保留的消息无关,它与客户端会话存储有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 2012-11-20
    • 2012-03-17
    • 2010-12-07
    • 2015-09-06
    • 2014-06-09
    相关资源
    最近更新 更多