问题描述
我正在使用 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
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”也能很好地传递。因此,broker 将保留的消息很好地保存在磁盘上,而不是客户端会话。
知道为什么吗?是否有我应该更改的配置以在磁盘上保留客户端会话?
解决方法
正如评论中所说。
客户端会话存储功能仅在“企业”付费版 emqx 中可用,而不是免费使用版。
这可以从 Feature list 以及问题 1 和 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 等消息队列中。