上一章:什么是消息队列Rocket MQ| 《Rocket MQ 使用排查指南》第一章>>>
下一章:消费问题排查 | 《Rocket MQ 使用排查指南》第三章>>>
也可以PC端点击https://developer.aliyun.com/topic/download?id=820下载
发送问题排查
客户端发送性能问题
发送消息耗时久
【问题描述】:
通过消息轨迹查询到,MQ 消息发送的耗时达到秒级之上。
【排查步骤】:
- 首先确认该现象是偶发还是频繁出现。
- 其次确认是部分机器发送有问题还是大量机器发送都存在此现象。
- 接着检查是少量的 topic 发送有此现象还是大部分机器如此。
- 确认您的应用机器的外网带宽。
- 检查发送消息的时间占比。
【问题原因】:
-
如果是偶发现象,检查现象存在期间您发送端的 TPS、网络状态以及出口 ip 的连接情况、确认期间应用是否有 Full GC(Full GC 会造成网络延迟 ),可 结合 ons.log 来综合分析。
- 如果部分机器有问题,那么登录该机器,查看网络流量以及 tps。
- 若客户端带宽过小,可建议升级带宽。
- 如果频繁现象,建议收集好信息反馈给技术支持人员,技术支持人员需要查 看下后端的 topic 集群是否有问题。
延时消息发送性能问题
【问题描述】: 业务大量使用发送延时消息,可以指定延时 15 天之后再投递消费吗?
看开源的代码是单线程去处理这些延迟消息的队列, 如果有大量消息在队列中, 性能上也是没有问题的嘛。
【问题回答】:
延时消息我们会先存 DB,在指定的时间扫描 DB,再将消息存储到 broker 上, 投递给消费端。并且这个存 DB 和扫码 DB 都是后端完成的。
也是因为这个存储 DB 和扫码的 DB 的损耗,所以我们的定时消息性能是没有普 通消息高的。
普通消息是直接发送存储到 broker 上的。延时消息就是多了两层的消 耗的。 普通消息和延迟消息是不一样的,这二者不存在转换的关系的。
为什么用普通消息的 topic 发送延迟消息也可以成功
【问题描述】:
topic 主题类型分为好几种,但是测试发现无论使用普通消息类型还是延时定时 消息类型都一样没问什么区别。
比如创建的普通消息类型 topic 但是发送延时消息也是可以使用的。总结来 说 :topic 消息类型有作用吗。
【问题回答】:
往普通消息类型 topic 当中发送延时消息,是可以成功,但是不保证一定成功, 也不保证相应的性能。
但是如果您严格按照消息类型创建对应的 topic,并且发送相应类型的消息,性 能是会得到保障的。
客户端发送常见异常报错
启动发送端时报错 No route info of this topic
【问题描述】:
具体报错异常如图所示。
【排查思路】:
- 确认您在 MQ 控制台 已创建 topic ,确认 topic 拼写及对应,控制台查询比 对 topic。
- 检查您代码的接入点配置,是否是 MQ 控制台上的接入点配置。
- 确认 NameServer 可以连接,telnet 接入点 + 端口,看是否能 telnet 通。
- 确认 NameServer 可用,curl 接入点,将获得的地址和端口号也 telnet 下, 确认通畅。
-
确认 topic 权限可用,检查您代码中配置的 AK、SK 所属的账号是否拥有此 topic 的发布订阅权限发送或消费权限异常。
- 看是否发送消息的实例和发送端是在同一个 region 下的(如果是走的公网, 那么就可以随便在任何可以接入公网的机器上发送消息)。
阿里云生产环境中消息队列 For RocketMQ 除了公网 region 之外,其他 region不允许在本地使用,必须在对应区域的 ECS 机器上部署使用。
服务端限流 system|broker busy
【问题描述】:
在 ons.log 日 志 当 中 出 现 system busy, start flow control for a while 或 者broker busy, start flow control for a while 等异常信息。
【问题原因】:
- 共享集群,当时 broker 压力大,会出现这个问题。
- broker 出现了网络,磁盘,IO 等抖动时,会出现这个问题。
【排查步骤】:
- 首先看下是短暂偶尔抖动还是持续,持续多长时间?
- 如果是偶尔抖动,是系统升级或 broker 压力大 , 或者抖动异常 , 但是 sdk 有 重试策略 , 会重试到其它的 broker,不影响消息的发送。
- 如果是长时间持续出现这种情况 , 那么需要收集一下信息:uid/ 实例 id/ 地域 /topic 等给到技术支持人员,技术人员需要核实下后端集群状态是否正常。
- 报错建议您在自己的业务代码层面 try...catch 进行重试。
1.8.4 版本的 skd 会自定进行 brokerbusy 的重试【不一定保证重试到其他的broker 一定是成功的】。
发送端出现发送超时异常
【问题描述】:
在ons.log日志中出现RemotingConnectException: connect to <118.190.213.56:80>failed 或者 RemotingTimeoutException 等异常信息。
【排查步骤】:
- 首先可以确认该时间段内是否属于服务升级时间段内 ( 可以看官网公告 ) 这 是 MQ 服务升级过程中 , 会出现短暂的网络闪断 , 但是我们的 mq 服务是集 群部署的 , 一台网络的闪断是不会影响消息的。
- 在自己的应用服务器上执行 telnet brokerip port,确认服务端的端口是否 通畅。
- 执行 ping brokerip , 查看网络是否延迟。同时检查网络监控指标,观察在问 题时间点流量是否有下降的情况。如果 ping 或者 telnet 不通,需要检查下 服务器的防火墙,网络设置等。
- 检查应用的网络带宽情况,是否打满。
- 可执行 jstack -l 进程号 > 文件名 .dump 来分析堆栈信息,判断当时应用系 统有没有 Full GC 现象 (Full GC 会造成一定的网络延迟 )。
- 确认下使用的 sdk,如果是较低的 javasdk 版本,建议升级 sdk 版本到 1.8.4。这个版本里容灾策略较之前版本优化了许多内容。 同时建议客户端做一下补偿机制 ,可以 try…catch 一下异常,做下消息的重试。
启动发送端连接异常
【问题描述】:
启动消费端的时候,报错连接,异常如下:
com.aliyun.openservices.ons.api.exception.ONSClientException: Can not find name server with
onsAddr http://**.mqrest.cn-hangzhou.aliyuncs.com
See http://docs.aliyun.com/cn#/pub/ons/faq/exceptions&namesrv_not_exist for further details.
at com.aliyun.openservices.ons.api.impl.rocketmq.ONSClientAbstract.fetchNameServerAddr(ONSClientAbstract.java:131)
at com.aliyun.openservices.ons.api.impl.rocketmq.ONSClientAbstract.(ONSClientAbstract.
java:84)
at com.aliyun.openservices.ons.api.impl.rocketmq.ProducerImpl.(ProducerImpl.java:35)
at com.aliyun.openservices.ons.api.impl.ONSFactoryImpl.createProducer(ONSFactoryImpl.
java:30)
at com.aliyun.openservices.ons.api.ONSFactory.createProducer(ONSFactory.java:89)
【排查方向】:
看报错的异常是和接入点有关的,报错是接入点不存在,需要和核实一下代码当 中填入的接入点信息。
【问题原因】:
代码当中使用的是杭州地域的 http 协议的公网接入点。
但是使用的是 tcp 协议的 sdk,代码配置却是 http 的接入点。
开源 python 发送端发送报错
【问题描述】:
使用开源 python 的 tcp 官方提供的 demo,发送报错。
【排查步骤】:
到 {home}/logs/rocketmqlogs 路径下查看 mq 的日志。
从日志当中看到有连接报错。
根据报错怀疑是接入点接入点接入的有问题
【问题原因】:
代码当中填入的是 http 的接入点,但是使用的是 tcp 的 sdk,应该使用控制台提供的 tcp 的接入点。
需要注意的是,使用什么连接类型的 sdk,就一定要对应使用控制台提供的对应连接类型的接入点,如果使用错误,那么代码将不会运行成功。
Php 的 http 接入方式发送消息失败
【问题描述】:
使用 php 的 http 接入方式,发送消息报错,导致消息发送失败。
报错如图。
【问题回答】:
internal error 一般是后端记录有类似于网络抖动的报错异常。
遇到此类错误,需要将实例 id/ 地域 /topic/sdk 语言版本等信息收集反馈给到技术人员进行后端服务器核实。
发 送 消 息 报 错 NumberFormatException: For inputstring: "//XXX"
【问题描述】:
启动发送端,发送消息报错 NumberFormatException: For input string: "//XXX。
【问题原因】:
出现这种问题肯定是 sdk 版本过低的原因,底层调用的 MQ 版本与 pom 里配置 的 ons-sdk 版本不一致。
【解决方案】:
● 采用 mvn dependency:tree 分析依赖树之间的关系。
● 如果是打出去的是 jar 包,将生成的 jar 解压,然后在 lib 目录下确认下 ons 的 版本是否正确,如下图所示:
发送消息报错权限异常
【问题描述】:
发送消息失败,报错:AuthenticationException 或者是
【问题原因】:
代码中配置的 AK、SK 所归属的账号,与创建 Topic 或者是 GID 的账号并不匹 配,导致权限错误。
【解决办法】:
- 检查代码当中配置的 ak 是否有调用 topic 发送消息的权限。
- 核实下 sdk 的版本,如果是平时发送消息都是正常,偶尔会出现这种异常 报错信息。可以看下 sdk 版本是否是 1.7.9 版本的。如果是,建议升级 sdk。1.7.9 版本的 sdk 在鉴权的时候,的确会容易出现鉴权失败的问题, 此版本在健全上有一些 bug。
- 检查下代码当中的接入点是否配置正确,可以 debug 看下,取到的接入点是 否和控制台提供的接入点完全一致。
- 检查下代码当中配置的 topic 是否与控制台创建的 topic 完全一致。
- 如果以上确认过都没有问题,需要收集实例 id/ 地域 /topic/sdk 版本等信息 给到技术人员进行后端服务器状态核实。
发送消息时日志报错
【问题描述】:
发送消息的时候,日志记录有报错
com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQBrokerException:
CODE: 1 DESC: [REJECTREQUEST]Broker in slave mode
【问题原因】:
这个报错是因为优化后端集群节点的时候导致的报错。对使用是没有影响的哈, 只是日志会有异常记录下来。
也可以再观察下,如果是持续大量报错,并且消息会发送失败,需要提供实例 id/ 地域 /topic 等信息给到技术人员进行查看。 消息体太大导致发送失败
【问题描述】:
发送消息的时候报错:
CODE:13 the message is illegal, maybe msg body or properties length not matched. msg bodylength limit 128k, msg properties length limit 32k. 此异常为消息属性 properties 太大。 CODE:13 the message body size over max value, MAX:4194304。 此异常信息为消息 body 太大
【解决方案】:
- 消息体大小最大为 4MB, 一般建议发送的消息体在 4kb 之内 ( 性能最佳 )。
- 消息属性最大为 32kb,一般建议发送的消息属性在 1kb 之内 ( 性能最佳 )。
- 4MB 这个上限值不能修改,这个会影响全局性能。如果消息体的确很大,建 议侧优化消息体的内容,避免发送大消息或者带有链接地址的消息,或者可 以缩短或者分两条发送。
应用部署在 edas 当中发送消息失败
【问题描述】:
mq 的应用部署在 edas 当中,但是发送消息失败。
【问题原因】:
通过发送报错日志看到 是 ons-client-1.7.1-EagleEye.jar 报错, ons-client 的版本比较低,需要升级 ons-sdk 1.8.0-EagleEye 插件。
【解决方案】:
到 edas 控制台点击运行时环境升降级,将 edas 的容器版本升级到 3.5.3 及其以上,3.5.3 版本及其以上版本升级了 on-client 插件的版本。
发送时报错 fetch name server address exception
【问题描述】:
发送消息的时候日志出现 fetch name server address exception 异常信息。
【问题原因】:
根据代码配置中的 ONSAddr 这个地址来获取 NAMESRV_ADDR 时失败了。
【排查步骤】:
- 检查代码配置,看配置的 ONSAddr 是否和控制台上的一致,有可能配置错了,将 NAMESRV_ADDR 当成了 ONSAddr,进行了如下图配置。
- nslookup 接入点的域名看下。检查 dns 是否正确。正确情况下,会获取到绑定。
这个域名的 ip,在 ping 下 ip 是否是通的
nslookup onsaddr-internet.aliyun.com
发送消息报错 not set any response code
【问题描述】:
发送延迟消息报错。
【问题原因】:
设置的 message properties 中某个属性的值过长,造成发送失败。 【排查过程】:
- 查询问题节点的消息,mq 控制台对应的接口是 ConsoleMessageGetByPagedTopic,openApi 对应的接口是 OnsMessagePageQueryByTopic。
- 登录 mq 控制台,打开浏览者开发工具(win os: F12 mac os: command+ F12),找到如下图所示的接口,查看返回的 response. 将其进行 json 化, 查看 properties 里是否存在长度比较长的属性值。
- openApi 里 可 查 看 MsgFoundList>>OnsRestMessageDo>>PropertyList>>MessageProperty 里的属性是否有比较长的值。
发送消息 get user info by accesskey from ALIYUN failed.异常
【问题描述】:
发送消息的时候日志报错:
com.aliyun.openservices.ons.api.impl.authority.exception.AuthenticationException: get user info by accesskey from ALIYUN failed.
异常如图
【问题原因】:
此问题不是权限报错,而是 AK 出现了问题,去 ak 中心根据 ak 获取子用户信息出错了,可以重新换个 ak 试试。
启动发送者时报错 UnknownHostException
【问题描述】:
启动消息队列 RocketMQ 版的客户端时提示异常 UnknownHostException信息。
【问题原因】:
导致此问题的主要原因是客户端无法获取系统的主机名(Hostname)或者系统的 IP 地址。
【解决方案】:
请参考以下步骤进行排查:
- 登录客户端所在机器。
- 执行 hostname 命令,检查能否正常返回主机名。
(1)如 果 该 命 令 报 错, 请 检 查 是 否 为 该 命 令 定 义 了 别 名(alias), 比 如 在 .bash_profile 文件或者 .bashrc 文件中设置了 alias hostname='/ usr/bin/**' 的别名。确保 hostname 命令能够正常返回主机名。
(2)如果该命令正常执行,记录返回的主机名并继续下一步。
- 检查能否 ping 通记录的主机名。
(1)如果无法 ping 通,请参考 127.0.0.1[$Hostname],将记录的主机名绑 定到 /etc/hosts 文件中。
(2)如果可以 ping 通,请继续下一步。
- 检查 /etc/sysconfig/network 文件中的
Hostname 是否与 /etc/hosts 文件中的主机名一致。
(1)如果不一致,请修改 /etc/sysconfig/network 文件中的 Hostname 参数
值,使其与 /etc/hosts 文件中的主机名一致。
(2)/etc/sysconfig/network 文 件 中 不 存 在 Hostname 配 置, 请 参 考
hostnamectl set-hostname [$Hostname] 命令更新主机名。
(3)如果一致,请继续下一步。
- 重新启动消息队列 RocketMQ 版的客户端,确认不再提示有关未知主机名
的异常信息。
发送消息时报错消息不合法
【问题描述】:
发送消息时报错消息不合法。
【问题原因】:
一般是消息属性、消息内容不合法,不合法的情况有:
- 消息为空;
- 消息内容为空;
- 消息内容长度为 0;
- 消息内容超过限定长度。
Tcp 协议开源 sdk 连接 mq 失败
【问题描述】:
Tcp 协议开源 sdk 无法连接 mq,代码层面报错。
【问题回答】:
可能原因:
开源 sdk 接入阿里云,阿里云都是与各个开源语言的 sdk 做过适配的。因此一定需要使用阿里云官方文档上推荐的各个语言的 sdk 版本,如果使用的开源版本非阿里云提供的官网推荐使用的 sdk 版本,那么是无法成功连接到阿里云 mq 的。