消息延迟问题

消息延迟监控

监控消息的延迟有两种方式:

  • 使用消息队列提供的工具,通过监控消息的堆积来完成;

    • 利用消息队列实现提供的监控工具,例如Kafka中提供的“kafka-consumer-groups.sh
    • 第三方监控工具:JMX
  • 通过生成监控消息的方式来监控消息的延迟情况。

    • 编写并启动一个监控程序,将监控消息定时地循环写入到消息队列中,消息的内容可以是生成消息的时间戳并且也会作为队列的消费者消费数据。

      业务处理程序消费到这个消息时直接丢弃掉,而监控程序在消费到这个消息时就可以和这个消息的生成时间做比较,如果时间差达到某一个阈值就可以向我们报警

      image-20230505153141842

减少消息延迟

想要减少消息的处理延迟,我们需要在消费端和消息队列两个层面来完成。

  1. 消费端

    在消费端的目标是提升消费者的消息处理能力:

    • 优化消费代码提升性能:

      注意消费线程空转,如果经常发生空转,可以设置固定或者步长递增的等待时间例如10ms~100ms。

    • 增加消费者的数量。

      如果想kafka一样一个 Topic(话题)可以配置多个 Partition(分区),一个分区只能由一个消费者消费,则可以让消费者收到了消息之后利用多线程来异步处理消息。

      image-20230505153504136

  2. 消息队列

    主要从两方面考虑读取性能问题:

    • 消息的存储:

      可以存储在本地磁盘而不是数据库中,因为磁盘读取是顺序读取并且不需要跨网络传输数据。

    • 零拷贝技术:

      减少数据拷贝次数,例如使用操作系统提供的 Sendfile 函数,这样在内核缓冲区的数据不会被拷贝到用户缓冲区而是直接被拷贝到 Socket 缓冲区,节省了一次拷贝的过程提升了消息发送的性能。

      image-20230505154115383

      Java 里面的 java.nio.channels.FileChannel 类就提供了 transferTo 方法提供了 Sendfile 的功能。