消息发送常见错误与解决方案,java开发岗位面试题总结

本文介绍了如何在RocketMQ中调整配置以减少system_busy和broker_busy问题,包括增加Broker端快速失败的时长、调整客户端发送策略,并针对PageCache压力提供了解决方案。还提到了提供给Java开发者的学习资源和面试准备指南。
摘要由CSDN通过智能技术生成

1. 增加 Broker 端快速失败的时长,建议为 1000,在 Broker 的配置文件中增加如下配置:

maxWaitTimeMillsInQueue=1000

主要原因是在当前的 RocketMQ 版本中,快速失败导致的错误为 system_busy,并不会触发重试,适当增大该值,尽可能避免触发该机制,详情可以参考本专栏第 3 部分内容,会重点介绍 system_busy、broker_busy。

如果 RocketMQ 的客户端版本为 4.3.0 以下版本(不含 4.3.0):

将超时时间设置消息发送的超时时间为 500ms,并将重试次数设置为 6 次(这个可以适当进行调整,尽量大于 3),其背后的哲学是尽快超时,并进行重试,因为发现局域网内的网络抖动是瞬时的,下次重试的是就能恢复,并且 RocketMQ 有故障规避机制,重试的时候会尽量选择不同的 Broker,相关的代码如下:

DefaultMQProducer producer = new DefaultMQProducer(“dw_test_producer_group”);

producer.setNamesrvAddr(“127.0.0.1:9876”);

producer.setRetryTimesWhenSendFailed(5);// 同步发送模式:重试次数

producer.setRetryTimesWhenSendAsyncFailed(5);// 异步发送模式:重试次数

producer.start();

producer.send(msg,500);//消息发送超时时间

如果 RocketMQ 的客户端版本为 4.3.0 及以上版本:

如果客户端版本为 4.3.0 及其以上版本,由于其设置的消息发送超时时间为所有重试的总的超时时间,故不能直接通过设置 RocketMQ 的发送 API 的超时时间,而是需要对其 API 进行包装,重试需要在外层收到进行,例如示例代码如下:

public static SendResult send(DefaultMQProducer producer, Message msg, int

retryCount) {

Throwable e = null;

for(int i =0; i < retryCount; i ++ ) {

try {

return producer.send(msg,500); //设置超时时间,为 500ms,内部有重试机制

} catch (Throwable e2) {

e = e2;

}

}

throw new RuntimeException(“消息发送异常”,e);

}

System busy、Broker busy

在使用 RocketMQ 中,如果 RocketMQ 集群达到 1W/tps 的压力负载水平,System busy、Broker busy 就会是大家经常会遇到的问题。例如如下图所示的异常栈。

6

7

纵观 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

原理分析

我们先用一张图来阐述一下,在消息发送的全生命周期中,分别在什么时候会抛出上述错误。

8

根据上述 5 类错误日志,其触发的原由可以归纳为如下 3 种。

1. PageCache 压力较大

其中如下三类错误属于此种情况:

[REJECTREQUEST]system busy

[PC_SYNCHRONIZED]broker busy

[PCBUSY_CLEAN_QUEUE]broker busy

判断 PageCache 是否忙的依据就是,在写入消息、向内存追加消息时加锁的时间,默认的判断标准是加锁时间超过 1s,就认为是 PageCache 压力大,向客户端抛出相关的错误日志。

2. 发送线程池挤压的拒绝策略

在 RocketMQ 中处理消息发送的,是一个只有一个线程的线程池,内部会维护一个有界队列,默认长度为 1W。如果当前队列中挤压的数量超过 1w,执行线程池的拒绝策略,从而抛出 [too many requests and system thread pool busy] 错误。

3. Broker 端快速失败

默认情况下 Broker 端开启了快速失败机制,就是在 Broker 端还未发生 PageCache 繁忙(加锁超过 1s)的情况,但存在一些请求在消息发送队列中等待 200ms 的情况,RocketMQ 会不再继续排队,直接向客户端返回 System busy,但由于 RocketMQ 客户端目前对该错误没有进行重试处理,所以在解决这类问题的时候需要额外处理。

PageCache 繁忙解决方案

一旦消息服务器出现大量 PageCache 繁忙(在向内存追加数据加锁超过 1s)的情况,这个是比较严重的问题,需要人为进行干预解决,解决的问题思路如下。

1. transientStorePoolEnable

开启 transientStorePoolEnable 机制,即在 Broker 中配置文件中增加如下配置:

transientStorePoolEnable=true

transientStorePoolEnable 的原理如下图所示:

9

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

再分享一波我的Java面试真题+视频学习详解+技能进阶书籍

美团二面惜败,我的凉经复盘(附学习笔记+面试整理+进阶书籍)

-1710426568281)]

最后

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

再分享一波我的Java面试真题+视频学习详解+技能进阶书籍

[外链图片转存中…(img-ZgPuSU8B-1710426568282)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值