1.3 消息队列(7-8)

07 | 消息积压了该如何处理?

​ 消息积压的直接原因:一定是系统中的某个部分出现了性能问题,来不及处理上游发送的消息,才会导致消息积压。

优化性能来避免消息积压

​ 性能优化,主要集中在生产者和消费者这两部分的业务逻辑中。对于消息队列本身的性能,不需要太关注。主要原因是,消息队列本身的处理能力要远大于业务系统的处理能力。

1、发送端性能优化

​ 发送端先执行自己的业务逻辑,最后再发送消息。代码发送消息的性能差,首先检查是不是发消息之前的业务逻辑耗时太多导致的。

解决思路:

  • 设置合适的并发和批量大小;增加每次发送消息的批量大小,还是增加并发;
  • 注重时延的采取增加并发,不注重的采取增加批量大小;

举例:

​ 微服务,主要接受 RPC 请求处理在线业务 ,批量发送必然会影响 RPC 服务的时延。适合通过增加并发来提升发送性能。

​ 离线分析系统,不关心时延,更注重整个系统的吞吐量。更适合增加批量发送大小。

2、消费端性能优化

大部分的性能问题都出现在消费端,当消费的速度跟不上发送端生产消息的速度,就会造成消息积压。

注:设计系统的时候,一定要保证消费端的消费性能要高于生产端的发送性能,这样的系统才能健康的持续运行。

优化思路

  1. 优化消费业务逻辑;
  2. 通过水平扩容,增加消费端的并发数来提升总体的消费性能。

注:在扩容 Consumer 的实例数量的同时,必须同步扩容主题中的分区(也叫队列)数量,确保 Consumer 的实例数和分区数量是相等的。如果 Consumer 的实例数量超过分区数量,这样的扩容实际上是没有效果的。因为对于消费者来说,在每个分区上实际上只能支持单线程消费

消息积压了该如何处理?

情况:正常运转的时候,没有积压或者只有少量积压很快就消费掉了,但是某一个时刻,突然就开始积压消息并且积压持续上涨。

排查思路发送变快了,要么是消费变慢了。

  • 单位时间发送的消息增多,赶上大促或者抢购,可以通过扩容消费端的实例数来提升总体的消费能力
  • 短时间内没有足够的服务器资源进行扩容,可以将系统降级,关闭一些不重要的业务,减少发送方发送的数据量。
  • 发送消息的速度还是消费消息的速度都没什么变化,需要检查一下你的消费端,是不是消费失败导致的一条消息反复消费这种情况比较多,这种情况也会拖慢整个系统的消费速度。
  • 如果监控到消费变慢了,需要检查消费实例,优先检查一下日志是否有大量的消费错误,如果没有错误的话,可以通过打印堆栈信息,看一下消费线程是不是卡在什么地方不动了,比如触发了死锁或者卡在等待某些资源上了。
消费端是否可以通过批量消费的方式来提升消费性能

1.无法提升消费业务效率(仅受消费业务自身逻辑影响),但可以提高mq中堆积消息消费的整体吞吐量(批推比单推mq耗时较短)。
2.批处理意味数据积累和大数据传输,这会让单次消费的最长时延变长。同时批量操作为了保证当前批量操作一致性,在个别失败的情况下会引发批量操作重试。

08 | 答疑解惑(一)

1、网关如何接收服务端的秒杀结果?

  • 发送消息失败,直接给 APP 返回秒杀失败结果;
  • 发送消息成功,线程就阻塞等待秒杀结果同时设定一个等待的超时时间。
  • 处理 APP 请求的线程需要同步等待秒杀结果,性能相对较低。

在这里插入图片描述

2、详解 RocketMQ 和 Kafka 的消息模型

假设有一个主题 MyTopic,我们为主题创建 5 个队列,分布到 2 个 Broker 中。
在这里插入图片描述

生产者:

​ 生产者不用一一对应Broker或者队列,可以随便发送。每个生产者可以在 5 个队列中轮询发送,也可以随机选一个队列发送,或者只往某个队列发送。

消费端:

  • 每个消费组就是一份订阅,它要消费主题 MyTopic 下,所有队列的全部消息。这里的“消费”,只是去队列里面读了消息,并没有删除,消费完这条消息还是在队列里面。
  • 多个消费组在消费同一个主题时,消费组之间是互不影响的。
  • 消费组的内部,一个消费组中可以包含多个消费者的实例。
  • 由于消费确认机制的限制,原则是,在同一个消费组里面,每个队列只能被一个消费者实例占用。若某个消费者宕机,则重新分配。

消费位置:

  • 每个消费组内部维护自己的一组消费位置每个队列对应一个消费位置
  • 消费位置在服务端保存,并且,消费位置和消费者是没有关系的。
  • 每个消费位置一般就是一个整数,记录这个消费组中,这个队列消费到哪个位置了,这个位置之前的消息都成功消费了,之后的消息都没有消费或者正在消费。

3、如何实现单个队列的并行消费?

  1. 若队列当前的消费位置是 5。同时来了三个消费者来拉消息,把编号为 5、6、7 的消息分别给三个消费者,每人一条。过了一段时间,三个消费成功的响应都回来了,可以把消费位置更新为 8 了,这样就实现并行消费。
  2. 若编号 5 的消息响应一直回不来,位置 5 就是一个消息空洞。为了避免位置 5 把这个队列卡住,可以先把消费位置 5 这条消息,复制到一个特殊重试队列中,然后把消费位置更新为 8,继续消费。再有消费者来拉消息的时候,优先把重试队列中的那条消息给消费者
  3. 并行消费开销还是很大的,不应该作为一个常规的,提升消费并发的手段,如果消费慢需要增加消费者的并发数,还是需要扩容队列数。

4、如何保证消息的严格顺序?

全局严格顺序:把消息队列数配置成 1,生产者和消费者也只能是一个实例;

局部严格顺序:在发送端,使用账户 ID 作为 Key,采用一致性哈希算法计算出队列编号,指定队列来发送消息。一致性哈希算法可以保证,相同Key 的消息总是发送到同一个队列上,这样可以保证相同 Key 的消息是严格有序的。如果不考虑队列扩容,也可以用队列数量取模的简单方法来计算队列编号。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值