目录

一、消息延迟场景

二、如何监控消息延迟

三、减少消息延迟的正确姿势

1.消费端

2.消息队列

(1)消息的存储

(2)零拷贝技术

四、课程小结


一、消息延迟场景

在你的垂直电商项目中,你会在用户下单支付之后向消息队列里面发送一条消息,队列处理程序消费了消息后会增加用户的积分或者给用户发送优惠券。用户在下单之后,等待几分钟或者十几分钟拿到积分和优惠券是可以接受的,但是一旦消息队列出现大量堆积用户消费完成后几小时还拿到优惠券,那就会有用户投诉了


二、如何监控消息延迟

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

  • 使用消息队列提供的工具,通过监控消息的堆积来完成;
  • 通过生成监控消息的方式来监控消息的延迟情况。

Kafka提供了工具叫做“kafka-consumer-groups.sh” 

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_消息队列

  • 图中的前两列是队列的基本信息,包括话题名分区名
  • 第三列是当前消费者的消费进度
  • 第四列是当前生产消息的总数
  • 第五列就是消费消息的堆积数(也就是第四列与第三列的差值)

JMX

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_笔记_02

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_kafka 发送遇到延迟后会重试么_03


三、减少消息延迟的正确姿势

1.消费端

  • 优化消费代码提升性能;
  • 增加消费者的数量

Kafka的方式

在Kafka中,一个Topic(话题)可以配置多个Partition(分区),数据会被平均或者按照生产者指定的方式写入到多个分区中,那么在消费的时候,Kafka约定一个分区只能被一个消费者消费,为什么要这么设计呢?在我看来,如果有多个consumer(消费者)可以消费一个分区的数据,那么在操作这个消费进度的时候就需要加锁,可能会对性能有一定的影响

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_数据_04

2.消息队列

消息队列本身在读取性能优化方面做了哪些事情

  • 消息的存储
  • 零拷贝技术

(1)消息的存储

使用了普通的数据库来存储消息,但是受限于数据库的性能瓶颈,读取QPS只能到2000,后面我重构了存储模块,使用本地磁盘作为存储介质。Page Cache的存在就可以提升消息的读取速度,即使要读取磁盘中的数据,由于消息的读取是顺序的并且不需要跨网络读取数据,所以读取消息的QPS提升了一个数量级。

(2)零拷贝技术

说是零拷贝,其实我们不可能消灭数据的拷贝,只是尽量减少拷贝的次数。在读取消息队列的数据的时候,其实就是把磁盘中的数据通过网络发送给消费客户端

  1. 数据从磁盘拷贝到内核缓冲区
  2. 系统调用将内核缓存区的数据拷贝到用户缓冲区;
  3. 用户缓冲区的数据被写入到Socket缓冲区中;
  4. 操作系统再将Socket缓冲区的数据拷贝到网卡的缓冲区中

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_kafka 发送遇到延迟后会重试么_05

 

kafka 发送遇到延迟后会重试么 kafka延迟消息队列_消息队列_06


四、课程小结

  • 我们可以使用消息队列提供的工具,或者通过发送监控消息的方式来监控消息的延迟情况;
  • 横向扩展消费者是提升消费处理能力的重要方式;
  • 选择高性能的数据存储方式配合零拷贝技术,可以提升消息的消费性能