我的编程空间,编程开发者的网络收藏夹
学习永远不晚

蚊子的持久性不一致

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

蚊子的持久性不一致

知识点掌握了,还需要不断练习才能熟练运用。下面编程网给大家带来一个Golang开发实战,手把手教大家学习《蚊子的持久性不一致》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

我发现 mosquitto 上的消息传递与消息持久性和 qos=2 不一致。我有什么做错的地方吗?

我有一个简单的测试应用程序,它注册一个主题以使用 clientid="receive-client" 进行消费,但立即断开连接。然后,它以 clientid="send-client" 身份连接并发布 10 条消息,“消息 #1”...“消息 #10”。然后断开连接,等待五秒钟,然后再次连接到“receive-client”进行消费,同时打印和统计收到的消息。

结果不一致。有时我收到 6 条消息,有时收到 8 条消息。典型的输出如下所示:

warn[0005] got a message:message #1                     
warn[0005] got a message:message #2                     
warn[0005] got a message:message #3                     
warn[0005] got a message:message #4                     
warn[0005] got a message:message #5                     
warn[0005] got a message:message #6                     
warn[0005] got a message:message #7                     
warn[0005] got a message:message #8                     
warn[0305] pause                                        
warn[0605] received message count=8

我的版本信息显示为1.4.15。我的 mosquitto.conf 是:

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

allow_anonymous false
password_file /etc/mosquitto/passwd

log_dest file /var/log/mosquitto/mosquitto.log

最初,/var/lib/mosquitto/mosquitto.db 直到运行多次迭代后才显示。我的测试应用程序在这里:

import (
    mqtt "github.com/eclipse/paho.mqtt.golang"
    log "github.com/sirupsen/logrus"
    "time"
)

var receivedMsg int

func Persist() {
    const TOPIC = "test"
    const URL = "tcp://localhost:1883"
    const USERNAME = "myuser"
    const PASSWORD = "mypassword"

    defer printReceived()

    options := mqtt.NewClientOptions().AddBroker(URL).SetUsername(USERNAME).SetPassword(PASSWORD)
    options.SetCleanSession(false)
    options.SetConnectRetry(true)
    options.SetConnectRetryInterval(10 * time.Millisecond)

    // register the receive client with broker / TOPIC
    // to be sure the broker knows it needs to save our messages
    // to deliver at a later time
    options.SetClientID("receive-client")
    client := mqtt.NewClient(options)
    token := client.Connect()
    token.Wait()
    if token := client.Subscribe(TOPIC, 2, consume1); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }
    client.Disconnect(0)

    // connect with send client and send 10 messages
    options.SetClientID("send-client")
    client = mqtt.NewClient(options)
    token = client.Connect()
    token.Wait()

    client.Publish(TOPIC, 2, false, "message #1")
    client.Publish(TOPIC, 2, false, "message #2")
    client.Publish(TOPIC, 2, false, "message #3")
    client.Publish(TOPIC, 2, false, "message #4")
    client.Publish(TOPIC, 2, false, "message #5")
    client.Publish(TOPIC, 2, false, "message #6")
    client.Publish(TOPIC, 2, false, "message #7")
    client.Publish(TOPIC, 2, false, "message #8")
    client.Publish(TOPIC, 2, false, "message #9")
    client.Publish(TOPIC, 2, false, "message #10")
    client.Disconnect(4)
    time.Sleep(5* time.Second)

    // subscribe again and try to retrieve the messages we missed
    options.SetClientID("receive-client")
    client = mqtt.NewClient(options)
    token = client.Connect()
    token.Wait()

    if token := client.Subscribe(TOPIC, 2, consume2); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    time.Sleep(300 * time.Second)
    log.Warn("PAUSE")
    time.Sleep(300 * time.Second)
}

func consume1(client mqtt.Client, msg mqtt.Message) {
    receivedMsg++
    log.Warn("THIS SHOULD NOT BE CONSUMING ANY MESSAGES:", string(msg.Payload()))
}

func consume2(client mqtt.Client, msg mqtt.Message) {
    receivedMsg++
    log.Warn("GOT A MESSAGE:", string(msg.Payload()))
}

func printReceived() {
    log.Warn("received message count=", receivedMsg)
}


解决方案


以 qos 2 进行发布是一个多步骤过程,因此最可能的原因是您在所有消息实际完成向代理的发布之前断开了发布客户端的连接。 您可能应该在循环中进行发布,并使用调用 client.publish() 时返回的令牌来等待它完成,然后再断开客户端连接。

例如如示例所示:

//Publish 5 messages to /go-mqtt/sample at qos 1 and wait for the receipt
//from the server after sending each message
for i := 0; i < 5; i++ {
  text := fmt.Sprintf("this is msg #%d!", i)
  token := c.Publish("go-mqtt/sample", 0, false, text)
  token.Wait()
}

好了,本文到此结束,带大家了解了《蚊子的持久性不一致》,希望本文对你有所帮助!关注编程网公众号,给大家分享更多Golang知识!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

蚊子的持久性不一致

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

蚊子的持久性不一致

知识点掌握了,还需要不断练习才能熟练运用。下面编程网给大家带来一个Golang开发实战,手把手教大家学习《蚊子的持久性不一致》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!问题内容我发现 mos
蚊子的持久性不一致
2024-04-05

跟面试官侃半小时MySQL事务,说完原子性、一致性、持久性的实现

提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关。 而事务的ACID(即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability
跟面试官侃半小时MySQL事务,说完原子性、一致性、持久性的实现
2016-10-14

红帽通过一致且持久的存储扩展Kubernetes平台

红帽OpenShift平台Plus添加了红帽OpenShift容器存储,构建了一个全功能、完整的混合云平台,以满足云原生计算的需求

应用中引入缓存层后,缓存和持久化层数据一致性的思考

一个应用中决定加缓存(Redis,memcached)之前,要考虑的第一个问题就是,引进了缓存之后,会带来哪些收益(利),付出哪些代价,引起哪些额外的问题(弊)?任何新的中间件引进,收益和成本都是伴随的,只有当利大于弊的情况下,能够容忍其弊端(彻底解决?没有额
2022-01-16

redis怎样保持和数据库数据的一致性

redis 与数据库数据一致性维护可以通过以下方式实现:定期数据同步使用 redis 发布/订阅机制使用 redis 事务使用 redis 持久化使用 redis sentinel 或 redis cluster注意事项包括:同步频率、数据
redis怎样保持和数据库数据的一致性
2024-04-19

NoSQL怎么处理数据的不一致性问题

NoSQL数据库通常使用多种方法来处理数据的不一致性问题,具体取决于数据库的类型和实现方式。以下是一些常见的方法:ACID属性:一些NoSQL数据库支持部分或全部的ACID属性(原子性、一致性、隔离性和持久性),这可以确保数据在处理过程中的
NoSQL怎么处理数据的不一致性问题
2024-05-07

MySQL与HBase在数据一致性模型上的不同

MySQL和HBase在数据一致性模型上的主要不同在于,MySQL提供的是强一致性模型,而HBase则采用最终一致性模型。以下是两者在数据一致性模型上的具体差异:MySQL的数据一致性模型MySQL是一个关系型数据库管理系统,它通过事务
MySQL与HBase在数据一致性模型上的不同
2024-10-19

MySQL视图在哪些地方可能会不一致,如何保证它们的一致性?

在可更新视图的情况下,我们很可能更新通过视图不可见的数据,因为我们创建的视图仅显示表的部分数据。这种更新使得视图不一致。我们在创建或修改视图时可以通过使用WITH CHECK OPTION来保证视图的一致性。虽然WITH CHECK OPT
2023-10-22

Java设计规范与代码风格:保持代码的一致性与可读性

本文是一些Java设计规范和代码风格的建议,帮助您保持代码的一致性和可读性。
代码Java2024-11-30

MyBatis字段名和属性名不一致的解决方法

本文主要介绍了MyBatis字段名和属性名不一致的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-01-15

广东云网金服:持续推进服务一致性,不断完善自身服务体系

对于企业来说,业务成功是核心,而优质的服务体验则是业务成功的关键。

新特性解读 | 说说 MySQL 8 对于持久化变量的一些修改

作者:姚嵩爱可生南区交付服务部经理,爱好音乐,动漫,电影,游戏,人文,美食,旅游,还有其他。虽然都很菜,但毕竟是爱好。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。MySQL 变量存在的介质及意义:MySQL
新特性解读 | 说说 MySQL 8 对于持久化变量的一些修改
2021-07-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录