高并发系统设计 40 问
唐扬
美图公司技术专家
49013 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
高并发系统设计 40 问
15
15
1.0x
00:00/00:00
登录|注册

19 | 消息队列:如何降低消息队列系统中消息的延迟?

零拷贝技术
消息的存储
增加消费者的数量
优化消费代码提升性能
JMX
kafka-consumer-groups.sh
消息队列本身的优化
消费端的目标
通过生成监控消息的方式
使用消息队列提供的工具
提升消息的写入和消费性能
监控消息延迟
消息队列性能优化

该思维导图由 AI 生成,仅供参考

你好,我是唐扬。
学完前面两节课之后,相信你对在垂直电商项目中如何使用消息队列应对秒杀时的峰值流量已经有所了解。当然了,你也应该知道要如何做才能保证消息不会丢失,尽量避免消息重复带来的影响。那么我想让你思考一下:除了这些内容,你在使用消息队列时还需要关注哪些点呢?
先来看一个场景:在你的垂直电商项目中,你会在用户下单支付之后向消息队列里面发送一条消息,队列处理程序消费了消息后会增加用户的积分或者给用户发送优惠券。用户在下单之后,等待几分钟或者十几分钟拿到积分和优惠券是可以接受的,但是一旦消息队列出现大量堆积,用户消费完成后几小时还拿到优惠券,那就会有用户投诉了。
这时你要关注的就是消息队列中消息的延迟了,这其实是消费性能的问题,那么你要如何提升消费性能保证更短的消息延迟呢?在我看来,首先需要掌握如何来监控消息的延迟,因为有了数据之后你才可以知道目前的延迟数据是否满足要求,也可以评估优化之后的效果。然后你要掌握使用消息队列的正确姿势以及关注消息队列本身是如何保证消息尽快被存储和投递的。
接下来,我们先来看看第一点:如何监控消息延迟。

如何监控消息延迟

在我看来,监控消息的延迟有两种方式:
使用消息队列提供的工具,通过监控消息的堆积来完成;
通过生成监控消息的方式来监控消息的延迟情况。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文从监控消息延迟和提升消息写入和消费性能两个方面进行了探讨。首先,监控消息延迟可以通过消息队列提供的工具或生成监控消息的方式来实现。作者推荐结合两种方式使用,以更直观地了解消息消费的延迟情况。其次,提升消息的写入和消费性能需要掌握消息队列的正确姿势,关注消息队列本身如何保证消息尽快被存储和投递。文章以Kafka为例介绍了如何监控消息的堆积情况和消费者的消费进度,同时提到了使用JMX和生成监控消息的方式来监控消息的延迟情况。通过本文的总结,读者可以了解到如何降低消息队列系统中消息的延迟,从而提升系统的性能和用户体验。文章还提到了消费端提升处理能力的方式,包括优化消费代码、增加消费者数量以及提升处理消息的并行度。此外,对消息队列本身在读取性能优化方面做了哪些事情也进行了讨论,包括消息的存储和零拷贝技术。总之,本文为读者提供了降低消息延迟的方法和技术,对于消息队列的使用和性能优化具有一定的指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《高并发系统设计 40 问》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(34)

  • 最新
  • 精选
  • 仙道
    老师,关于消息队列的一个重要东西,您还没有讲到。 消息的顺序性。比如订单消息要在配送消息消费之前消费 对于这种问题,有因果一致性来解决。因果一致性的一种做法是,消息的编号递增,小的号码先消费,大的号码要在后消费。 但是在分布式集群环境下,每个消费者消费的时候要把它的最大消息编号广播给其他消费者。 这样一来的话,代价就比较高了。

    作者回复: 也可以比如在Kafka下,把要求严格顺序的消息写到一个partition

    2019-11-06
    5
    27
  • 陆离
    并行消费那块有数据丢失的风险吧。 server接收到数据返回给队列ack,然后丢给线程池,数据还没处理完这个节点挂掉了,数据不就全丢了。

    作者回复: 会有这个风险,不过为了提升性能,需要一些权衡

    2019-11-01
    11
    19
  • 每天晒白牙
    今日学习总结 我们使用消息队列,一般会关注消息的延迟,然后优化消息的读写性能,但首先要做的是对延迟的监控,那怎么监控消息队列的延迟呢? 1.通过消息队列的工具,来监控消息的堆积情况 一般消息队列都会提供这种工具,拿kafka来说,可以通过 kafka-consumer-groups.sh 这个命令来监控堆积情况。主要关注【lag】列 同时kafka会通过jmx暴露消息的堆积情况,所以可以使用jconsole这种工具进行查看 2.通过生成监控消息的方式来监控延迟情况 这种方式就是启动一个监控程序,并生产一种特殊的消息,比如是消息生成的时间戳,然后循环的写入到消息队列中,真正的消费者对于这种特殊的消息不进行处理,而监控程序会处理这种特殊的消息,通过比较消费到该消息的时间和生成该消息的时间差来判断是否有延迟 那如何减少消息的延迟呢? 1.优化消费端的代码以提升性能 2.增加消费者的数量 关于第2点对消息队列会有限制,比如对于kafka来说,在同一个分区下,消息只能被一个消费者【同一个consumer_group】消费,这样也是考虑到了多个消费者消费需要抢占锁,会有性能损失 【topic的分区数量决定了消费者的并行度】 所以想提高并行度就得增加分区,那如何不增加分区呢?可以在处理消息上做工作了,比如可以在一个消费者中增加处理消息的并行度,比如多线程的方式去处理,或者加入异步处理 【这里有值得注意的,就是消费消息时消费线程的空转问题】 消费端通过不断轮训去topic中拉取消息,就存在线程空转的情况,这里可以增加一个策略就是拉取不到消息,等待一会儿,等待时间可以是固定的。也可以是阶梯的,当然这样可能加重消息消费延迟情况 消息队列本身读取性能提升可以从下面两个方面着手 1.消息的存储 2.零拷贝技术

    作者回复: 赞

    2019-12-22
    3
    17
  • Klaus
    数据库数据本身也是属于磁盘数据啊,为什么在存储的时候将数据库换成本地磁盘,qps会提高一个数量级呢?

    作者回复: 数据库是随机写,磁盘是顺序写

    2019-12-18
    4
    12
  • intomymind
    消费者接收到消息后,放入到线程池里面,那么在线程池里对消息处理完之后,如何实现返回ack给kafka呢

    作者回复: 为了性能可能要损失一些消息完整性

    2019-11-01
    4
    6
  • dondon
    Kafka 通过 JMX 暴露了消息堆积的数据,我在本地启动了一个 console consumer,然后使用 jconsole 连接 consumer 就可以看到 consumer 的堆积数据了(就是下图中红框里的数据)。 意思是说,生产环境Linux服务器上的kafka服务,我可以在本地写一个consumer订阅broker, 然后能通过jconsole可以看到kafka里的消息队列情况?

    作者回复: 可能生产环境不好用jconsole,不过可以写代码获取jmx的数据

    2020-03-26
    4
  • 桂爸
    消息处理时避免耗时操作也很重要

    作者回复: 是的,必要时可以做多级队列

    2020-02-06
    4
  • hunterlodge
    老师,请问怎么采集每个consumer的JMX数据呢,让监控程序去连接每一个consumer应用吗?

    作者回复: 是的呢~

    2019-11-26
    3
  • 你净瞎说~
    老师,我想问一下,消息中间件的读写都是顺序的吗?写文件的时候会先写到pageCache中,然后往文件写,写文件的时候应该是一行一行写的吧?如果不写入pageCache直接写入文件,也是一行一行写的吧,有什么区别吗?比如说写到文件的第1万行了,再往后继续写,是可以快速定位到这个位置的吗?读取消息的时候也是读的文件,假如说读到了第1万行,再往后读,也是可以很快定位到这个1万行吗?java有没有api,比如说,我直接读取第1万行的数据?

    作者回复: 写文件一般都会写入pagecache 由操作系统来刷盘

    2019-11-05
    3
    3
  • 电光火石
    零拷贝时,从内核缓冲区到socket缓冲区是否可以通过共享缓冲区的方式,再减少一次拷贝?谢谢!

    作者回复: 可以将描述符传输到socket缓冲区,这样可以减少一次拷贝

    2019-11-03
    2
    3
收起评论
显示
设置
留言
34
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部