共计 2461 个字符,预计需要花费 7 分钟才能阅读完成。
本文次要提到上面两类谬误及解决方案:
- 音讯发送超时
- System busy、Broker busy
一,音讯发送谬误
音讯发送超时,通常客户端的日志如下:
客户端报音讯发送超时,通常第一狐疑的对象是 RocketMQ 服务器 ,是不是 Broker 性能呈现了抖动,无奈抗住以后的量。
那咱们如何来排查 RocketMQ 以后是否有性能瓶颈呢?
首先咱们执行如下命令查看 RocketMQ 音讯写入的耗时散布状况:
cd /${USER.HOME}/logs/rocketmqlogs/
grep -n 'PAGECACHERT' store.log | more
输入后果如下所示:
RocketMQ 会每一分钟打印前一分钟内音讯发送的耗时状况散布,咱们从这里就能窥探 RocketMQ 音讯写入是否存在明细的性能瓶颈,其区间如下:
- [<=0ms] 小于 0ms,即奥妙级别的
- [0~10ms] 小于 10ms 的个数
- [10~50ms] 大于 10ms 小于 50ms 的个数
其余区间显示,绝大多数会落在奥妙级别实现,依照笔者的教训 如果 100~200ms 及以上的区间超过 20 个后,阐明 Broker 的确存在肯定的瓶颈 ,如果只是少数几个,阐明这个是内存或 PageCache 的抖动,问题不大。
在 RocketMQ broker 中还存在疾速失败机制,即当 Broker 收到客户端的申请后会将音讯先放入队列,而后程序执行,如果一条音讯队列中期待超过 200ms 就会启动疾速失败,向客户端返回 [TIMEOUT_CLEAN_QUEUE]broker busy 的谬误。另外,Producer 客户端如果那个时候正好呈现了垃圾回收也是有可能造成音讯发送超时的问题。
针对音讯发送超时咱们应该如何应答呢?
一般来说咱们能够缩小音讯发送的超时工夫,减少重试次数,并减少疾速失败的最大期待时长。具体通过 maxWaitTimeMillsInQueue
进行配置,一般来说超时工夫调为 500ms-1000ms。须要提一下的是超时工夫在不同版本间含意是不同的,在 4.3.0(不含 4.3.0)以下的版本,超时工夫指的是单次发送的工夫;而在 4.3.0 及以上版本中超时工夫指的是所有重试的总的超时工夫。
二,System busy、Broker busy
在应用 RocketMQ 中,如果 RocketMQ 集群达到 1W/tps 的压力负载程度,System busy、Broker busy 就会是大家常常会遇到的问题。例如如下图所示的异样栈。
纵观 RocketMQ 与 System busy、Broker busy 相干的谬误关键字,总共蕴含如下 5 个:
[REJECTREQUEST]system busy
too many requests and system thread pool busy
[PC_SYNCHRONIZED]broker busy
[PCBUSY_CLEAN_QUEUE]broker busy
[TIMEOUT_CLEAN_QUEUE]broker busy
一般来说起因能够演绎为上面 3 种:
- PageCache 压力较大
其中如下三类谬误属于此种状况:
[REJECTREQUEST]system busy
[PC_SYNCHRONIZED]broker busy
[PCBUSY_CLEAN_QUEUE]broker busy
判断 PageCache 是否忙的根据就是,在写入音讯、向内存追加音讯时加锁的工夫,默认的 判断规范是加锁工夫超过 1s,就认为是 PageCache 压力大,向客户端抛出相干的谬误日志。
- 发送线程池积压的回绝策略
在 RocketMQ 中解决音讯发送的,是一个只有一个线程的线程池,外部会保护一个有界队列,默认长度为 1W。如果以后队列中积压的数量超过 1w,执行线程池的回绝策略,从而抛出 [too many requests and system thread pool busy] 谬误。
- Broker 端疾速失败
默认状况下 Broker 端开启了疾速失败机制,就是在 Broker 端还未产生 PageCache 忙碌(加锁超过 1s)的状况,但存在一些申请在音讯发送队列中期待 200ms 的状况,RocketMQ 会不再持续排队,间接向客户端返回 System busy,但因为 RocketMQ 客户端目前对该谬误没有进行重试解决,所以在解决这类问题的时候须要额定解决。
PageCache 忙碌解决方案
一旦音讯服务器呈现大量 PageCache 忙碌(在向内存追加数据加锁超过 1s)的状况,这个是比较严重的问题,须要人为进行干涉解决,解决的问题思路如下。
- transientStorePoolEnable
开启 transientStorePoolEnable 机制,即在 Broker 中配置文件中减少如下配置:transientStorePoolEnable=true
transientStorePoolEnable 的原理如下图所示:
引入 transientStorePoolEnable 能缓解 PageCache 的压力背地要害如下:
- 音讯先写入到堆外内存中,该内存因为启用了内存锁定机制,故音讯的写入是靠近间接操作内存,性能能够失去保障。
- 音讯进入到堆外内存后,后盾会启动一个线程,一批一批将音讯提交到 PageCache,即写音讯时对 PageCache 的写操作由单条写入变成了批量写入,升高了对 PageCache 的压力。
引入 transientStorePoolEnable 会减少数据失落的可能性,如果 Broker JVM 过程异样退出,提交到 PageCache 中的音讯是不会失落的,但存在堆外内存(DirectByteBuffer)中但还未提交到 PageCache 中的这部分音讯,将会失落。但通常状况下,RocketMQ 过程退出的可能性不大,另外,如果启用了 transientStorePoolEnable,音讯发送端须要有从新推送机制(弥补思维)。
- 扩容
如果在开启了 transientStorePoolEnable 后,还会呈现 PageCache 级别的忙碌,那须要集群进行扩容,或者对集群中的 Topic 进行拆分,行将一部分 Topic 迁徙到其余集群中,升高集群的负载。