资源描述
目录RocketMQ 原理及快速入门4什么是消息队列 RocketMQ 4RocketMQ 快速入门教程 16发送问题排查24客户端发送性能问题 24客户端发送常见异常报错 27消费问题排查43堆积负载常见问题 43消息投递重试问题 52订阅关系问题 57客户端消费常见异常报错 59消息轨迹常见问题 75其他问题排查81控制台相关问题 81告警监控相关问题 86资源包费用相关问题 87日志相关问题 91权限相关问题 97使用常见问题 98什么是消息队列RocketMQ核心概念消息队列 RocketMQ 版是阿里云基于 Apache RocketMQ 构建的低延迟、高并发、高可用、高可靠的分布式消息中间件。消息队列 RocketMQ 版既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性。产品功能与特性消息队列 RocketMQ 版在阿里云多个地域(Region)提供了高可用消息云服务。单个地域内采用多机房部署,可用性极高,即使整个机房都不可用,仍然可以为应用提供消息发布服务。消息队列 RocketMQ 版提供 TCP 和 HTTP 协议的多语言接入方式,方便不同编程语言开发的应用快速接入消息队列 RocketMQ 版消息云服务。您可以将应用部署在阿里云 ECS、企业自建云,或者嵌入到移动端、物联网设备中与消息队列 RocketMQ 版建立连接进行消息收发;同时,本地开发者也可以通过公网接入消息队列 RocketMQ 版服务进行消息收发。RocketMQ 原理及快速入门什么是消息队列 RocketMQ什么是消息队列 RocketMQ Name Server:是一个几乎无状态节点,可集群部署,在消息队列 Rocket-MQ 版中提供命名服务,更新和发现 Broker 服务。Broker:消息中转角色,负责存储消息,转发消息。分为 Master Broker 和 Slave Broker,一个 Master Broker 可以对应多个 Slave Broker,但是一个 Slave Broker 只能对应一个 Master Broker。Broker 启动后需要完成一次将自己注册至 Name Server 的操作;随后每隔 30s 定期向 Name Server 上报 Topic 路由信息。生产者:与 Name Server 集群中的其中一个节点(随机)建立长链接(Keep-alive),定期从 Name Server 读取 Topic 路由信息,并向提供 Topic 服务的 Master Broker 建立长链接,且定时向 Master Broker 发送心跳。消费者:与 Name Server 集群中的其中一个节点(随机)建立长连接,定期从 Name Server 拉取 Topic 路由信息,并向提供 Topic 服务的 Master Broker、Slave Broker 建立长连接,且定时向 Master Broker、Slave Broker 发送心跳。Consumer 既可以从 Master Broker 订阅消息,也可以从 Slave Broker 订阅消息,订阅规则由 Broker 配置决定。应用场景削峰填谷 流量削峰也是消息队列 RocketMQ 版的常用场景,一般在秒杀或团队抢购活动中使用广泛。在秒杀或团队抢购活动中,由于用户请求量较大,导致流量暴增,秒杀的应用在处理如此大量的访问流量后,下游的通知系统无法承载海量的调用量,甚至会导致系统崩溃等问题而发生漏通知的情况。为解决这些问题,可在应用和下游通知系统之间加入消息队列 RocketMQ 版。什么是消息队列 RocketMQ什么是消息队列 RocketMQ数据流动如下所述:用户在注册页面填写账号和密码并提交注册信息,这些注册信息首先会被写入注册系统成功。注册信息写入注册系统成功后,再发送请求至邮件通知系统。邮件通知系统收到请求后向用户发送邮件通知。邮件通知系统接收注册系统请求后再向下游的短信通知系统发送请求。短信通知系统收到请求后向用户发送短信通知。以上三个任务全部完成后,才返回注册结果到客户端,用户才能使用账号登录。假设每个任务耗时分别为 50 ms,则用户需要在注册页面等待总共需要 150 ms 才能登录。(2)并行方式并行方式下的注册流程如下图所示。什么是消息队列 RocketMQ什么是消息队列 RocketMQ数据流动如下所述:用户在注册页面填写账号和密码并提交注册信息,这些注册信息首先会被写入注册系统成功。注册信息写入注册系统成功后,再发送消息至消息队列 RocketMQ 版。消息队列 RocketMQ 版会马上返回响应给注册系统,注册完成。用户可立即登录。下游的邮件和短信通知系统订阅消息队列 RocketMQ 版的此类注册请求消息,即可向用户发送邮件和短信通知,完成所有的注册流程。用户只需在注册页面等待注册数据写入注册系统和消息队列 RocketMQ 版的时间,即等待 55 ms 即可登录。异步解耦是消息队列 RocketMQ 版的主要特点,主要目的是减少请求响应时间和解耦。主要的适用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时,由于使用了消息队列 RocketMQ 版,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和。顺序收发 消息队列 RocketMQ 版顺序消息分为两种情况:什么是消息队列 RocketMQ什么是消息队列 RocketMQ流程说明如下:1.注册系统发起注册。2.注册系统向消息队列 RocketMQ 版发送注册消息成功与否的消息。2.1消息发送成功,进入 3。2.2 消息发送失败,导致邮件通知系统未收到消息队列 RocketMQ 版发送的注册成功与否的消息,而无法发送邮件,最终邮件通知系统和注册系统之间的状态数据不一致。3.邮件通知系统收到消息队列 RocketMQ 版的注册成功消息。4.邮件通知系统发送注册成功邮件给用户。在这样的情况下,虽然实现了系统间的解藕,上游系统不需要关心下游系统的业务处理结果;但是数据一致性不好处理,如何保证邮件通知系统状态与注册系统状态的最终一致。什么是消息队列 RocketMQ什么是消息队列 RocketMQ消息类型普通消息普通消息是指消息队列 RocketMQ 版中无特性的消息,即发送到服务端会立马被消费的消息,且消息是无序消费,不会按照发送的顺序一次顺序消费。定时消息Producer 将消息发送到消息队列 RocketMQ 版服务端,但并不期望立马投递这条消息,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费,该消息即定时消息。延时消息Producer 将消息发送到消息队列 RocketMQ 版服务端,但并不期望立马投递这条消息,而是延迟一定时间后才投递到 Consumer 进行消费,该消息即延时消息。定时消息与延时消息在代码配置上存在一些差异,但是最终达到的效果相同:消息在发送到消息队列 RocketMQ 版服务端后并不会立马投递,而是根据消息中的属性延迟固定时间后才投递给消费者。全局顺序消息对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。分区顺序消息对于指定的一个 Topic,所有消息根据 Sharding Key 进行区块分区。同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。Sharding Key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 Message Key 是完全不同的概念。什么是消息队列 RocketMQRocketMQ快速入门教程RocketMQ 快速入门教程如果您使用的是阿里云主账号,则可以通过本文来体验从开通服务、创建资源、到使用 SDK 收发消息的完整流程,快速上手消息队列 RocketMQ 版。无论您使用的是消息队列 RocketMQ 版支持的何种协议、何种语言,前三个步骤都一致,只是在控制台上具体填写的信息会略有不同,请以控制台说明为准。但在调用 SDK 时,不同协议和语言的示例代码有所不同,本文以 TCP 协议下的 Java SDK 为例进行说明。步骤一:开通服务1.在消息队列 RocketMQ 版产品页,单击立即开通。2.在确认订单页面,选择我已阅读并同意消息队列 MQ 服务协议,再单击立即开通即可完成开通。步骤二:创建资源在使用消息队列 RocketMQ 版时,请注意以下网络访问限制:Topic 和 Group ID 需创建在同一个地域(Region)下的同一个实例中才能互通。例如,当某 Topic 创建在华东 1(杭州)下的实例 A 中,那么该 Topic 只能被在华东 1(杭州)下的实例 A 中创建的 Group ID 对应的生产端和消费端访问。如果只是测试,或者需要在本地(非阿里云 ECS 服务器)使用消息队列 RocketMQ 版的服务,请将 Topic 和 Group ID 都创建在公网地域下的实例中。生产端和消费端可以部署在本地或者部署在任意地域的 ECS 上,前提是本地服务器或者相应的 ECS 需要能够访问公网。RocketMQ快速入门教程RocketMQ快速入门教程创建 Group ID创建完实例和 Topic 后,您需要为消息的消费者(或生产者)创建客户端 ID,即 Group ID 作为标识。Group ID 必须在同一实例中是唯一的。Group ID 和 Topic 的关系是 N:N,即一个消费者可以订阅多个 Topic,同一个 Topic 也可以被多个消费者订阅;一个生产者可以向多个 Topic 发送消息,同一个 Topic 也可以接收来自多个生产者的消息。说明:消费者必须有对应的 Group ID,生产者不做强制要求。1.在控制台左侧导航栏,单击 Group 管理。2.在 Group 管理页面上方选择刚创建的实例,然后选择 TCP 协议 创建 Group ID。本文以 TCP 协议为例。说明:TCP 和 HTTP 协议下的 Group ID 不可以共用,因此需分别创建。3.在创建 Group ID 对话框中,输入 Group ID 和描述,然后单击确认。创建阿里云 AccessKey阿里云 AccessKey 用于收发消息时进行账户鉴权。在调用 SDK 发送和订阅消息的时候,除了需要指定创建的 Topic 和 Group ID 以外,还需输入您在 RAM 控制台创建的身份验证信息,即 AccessKey。Access-Key 的信息包含 AccessKeyId 和 AcessKeySecret。步骤三:获取接入点在控制台创建好资源后,您需通过控制台获取实例的接入点。在收发消息时,您需要为生产端和消费端配置该接入点,以此接入某个具体实例或地域的服务。RocketMQ快速入门教程RocketMQ快速入门教程控制台会返回消息发送成功通知以及相应的 Message ID。调用 SDK 发送消息:用于生产环境下使用消息队列 RocketMQ 版。下文以调用 TCP Java SDK 为例进行说明。调用 TCP Java SDK 发送消息1.通过以下任一方式引入依赖:Maven 方式引入依赖:com.aliyun.openservices ons-client XXX/设置为 Java SDK 的最新版本号 下载依赖 JAR 包:2.根据以下说明设置相关参数,运行示例代码:import com.aliyun.openservices.ons.api.Message;import com.aliyun.openservices.ons.api.Producer;import com.aliyun.openservices.ons.api.SendResult;import com.aliyun.openservices.ons.api.ONSFactory;import com.aliyun.openservices.ons.api.PropertyKeyConst;import java.util.Properties;public class ProducerTest public static void main(String args)Properties properties=new Properties();/您在控制台创建的 Group IDproperties.put(PropertyKeyConst.GROUP_ID,XXX);/鉴权用 AccessKeyId,在阿里云服务器管理控制台创建properties.put(PropertyKeyConst.AccessKey,XXX);/鉴权用 AccessKeySecret,在阿里云服务器管理控制台创建properties.put(PropertyKeyConst.SecretKey,XXX);/设置 TCP 接入域名,进入控制台的实例详情页面,在页面上方选择实例后,在实例信息中的“获取接入点信息”区域查看properties.put(PropertyKeyConst.NAMESRV_ADDR,XXX);RocketMQ快速入门教程 按 Message ID 查询。2.在搜索框中输入发送消息后返回的 Message ID,单击搜索查询消息发送状态。储存时间表示消息队列 RocketMQ 版服务端存储这条消息的时间。如果查询到22RocketMQ快速入门教程此消息,表示消息已经成功发送到服务端。步骤五:调用SDK订阅消息消息发送成功后,需要启动消费者来订阅消息。下文以调用 TCP Java SDK 为例说明如何订阅消息。1.调用 TCP Java SDK 订阅消息。您可以运行以下示例代码来启动消费者,并测试订阅消息的功能。请按照说明正确设置相关参数。import com.aliyun.openservices.ons.api.Action;import com.aliyun.openservices.ons.api.ConsumeContext;import com.aliyun.openservices.ons.api.Consumer;import com.aliyun.openservices.ons.api.Message;import com.aliyun.openservices.ons.api.MessageListener;import com.aliyun.openservices.ons.api.ONSFactory;import com.aliyun.openservices.ons.api.PropertyKeyConst;import java.util.Properties;public class ConsumerTest public static void main(String args)Properties properties=new Properties();/您在控制台创建的 Group IDproperties.put(PropertyKeyConst.GROUP_ID,XXX);/鉴权用 AccessKeyId,在阿里云服务器管理控制台创建properties.put(PropertyKeyConst.AccessKey,XXX);/鉴权用 AccessKeySecret,在阿里云服务器管理控制台创建properties.put(PropertyKeyConst.SecretKey,XXX);/设置 TCP 接入域名,进入控制台的实例详情页面,在页面上方选择实例后,在实例信息中的“获取接入点信息”区域查看properties.put(PropertyKeyConst.NAMESRV_ADDR,XXX);Consumer consumer=ONSFactory.createConsumer(properties);consumer.subscribe(TopicTestMQ,*,new MessageListener()public Action consume(Message message,ConsumeContext context)System.out.println(Receive:+message);return Action.CommitMessage;);consumer.start();RocketMQ快速入门教程23System.out.println(Consumer Started);2.查看消息订阅是否成功。完成上述步骤后,您可以在控制台查看消费者是否启动成功,即消息订阅是否成功。a.在控制台左侧导航栏,单击 Group 管理。b.找到要查看的 Group ID,单击该 Group ID 所在行操作列的订阅关系。如果是否在线显示为是,且订阅关系一致,则说明订阅成功。否则说明订阅失败。客户端发送性能问题发送消息耗时久【问题描述】:通过消息轨迹查询到,MQ 消息发送的耗时达到秒级之上。发送问题排查客户端发送性能问题客户端发送性能问题【问题回答】:延时消息我们会先存 DB,在指定的时间扫描 DB,再将消息存储到 broker 上,投递给消费端。并且这个存 DB 和扫码 DB 都是后端完成的。也是因为这个存储 DB 和扫码的 DB 的损耗,所以我们的定时消息性能是没有普通消息高的。普通消息是直接发送存储到 broker 上的。延时消息就是多了两层的消耗的。普通消息和延迟消息是不一样的,这二者不存在转换的关系的。为什么用普通消息的 topic 发送延迟消息也可以成功【问题描述】:topic 主题类型分为好几种,但是测试发现无论使用普通消息类型还是延时定时消息类型都一样没问什么区别。比如创建的普通消息类型 topic 但是发送延时消息也是可以使用的。总结来说:topic 消息类型有作用吗。【问题回答】:往普通消息类型 topic 当中发送延时消息,是可以成功,但是不保证一定成功,也不保证相应的性能。但是如果您严格按照消息类型创建对应的 topic,并且发送相应类型的消息,性能是会得到保障的。客户端发送常见异常报错客户端发送常见异常报错阿里云生产环境中消息队列 For RocketMQ 除了公网 region 之外,其他 region 不允许在本地使用,必须在对应区域的 ECS 机器上部署使用。服务端限流 system|brokerbusy【问题描述】:在 ons.log 日志当中出现 system busy,start flow control for a while 或者broker busy,start flow control for a while 等异常信息。【问题原因】:1.共享集群,当时 broker 压力大,会出现这个问题。2.broker 出现了网络,磁盘,IO 等抖动时,会出现这个问题。【排查步骤】:1.首先看下是短暂偶尔抖动还是持续,持续多长时间?2.如果是偶尔抖动,是系统升级或 broker 压力大,或者抖动异常,但是 sdk 有重试策略,会重试到其它的 broker,不影响消息的发送。3.如果是长时间持续出现这种情况,那么需要收集一下信息:uid/实例 id/地域/topic 等给到技术支持人员,技术人员需要核实下后端集群状态是否正常。4.报错建议您在自己的业务代码层面 try.catch 进行重试。客户端发送常见异常报错291.8.4 版本的 skd 会自定进行 brokerbusy 的重试【不一定保证重试到其他的broker 一定是成功的】。发送端出现发送超时异常【问题描述】:在ons.log日志中出现RemotingConnectException:connect to failed 或者 RemotingTimeoutException 等异常信息。【排查步骤】:1.首先可以确认该时间段内是否属于服务升级时间段内(可以看官网公告)这是 MQ 服务升级过程中,会出现短暂的网络闪断,但是我们的 mq 服务是集群部署的,一台网络的闪断是不会影响消息的。2.在自己的应用服务器上执行 telnet brokerip port,确认服务端的端口是否通畅。3.执行 ping brokerip,查看网络是否延迟。同时检查网络监控指标,观察在问题时间点流量是否有下降的情况。如果 ping 或者 telnet 不通,需要检查下服务器的防火墙,网络设置等。30客户端发送常见异常报错4.检查应用的网络带宽情况,是否打满。5.可执行 jstack-l 进程号 文件名.dump 来分析堆栈信息,判断当时应用系统有没有 Full GC 现象(Full GC 会造成一定的网络延迟)。6.确认下使用的 sdk,如果是较低的 javasdk 版本,建议升级 sdk 版本到1.8.4。这个版本里容灾策略较之前版本优化了许多内容。同时建议客户端做一下补偿机制,可以 trycatch 一下异常,做下消息的重试。启动发送端连接异常【问题描述】:启动消费端的时候,报错连接,异常如下:com.aliyun.openservices.ons.api.exception.ONSClientException:Can not find name server with onsAddr http:/*-See http:/ for further details.at com.aliyun.openservices.ons.api.impl.rocketmq.ONSClientAbstract.fetchNameServerAd-dr(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 协议的公网接入点。客户端发送常见异常报错客户端发送常见异常报错需要注意的是,使用什么连接类型的 sdk,就一定要对应使用控制台提供的对应连接类型的接入点,如果使用错误,那么代码将不会运行成功。Php 的 http 接入方式发送消息失败【问题描述】:使用 php 的 http 接入方式,发送消息报错,导致消息发送失败。报错如图。【问题回答】:internal error 一般是后端记录有类似于网络抖动的报错异常。遇到此类错误,需要将实例 id/地域/topic/sdk 语言版本等信息收集反馈给到技术人员进行后端服务器核实。发 送 消 息 报 错 NumberFormatException:Forinputstring:/XXX【问题描述】:启动发送端,发送消息报错 NumberFormatException:For input string:/XXX。客户端发送常见异常报错客户端发送常见异常报错com.aliyun.openservices.ons.api.impl.authority.exception.AuthenticationException:valid resource owner failed.具体异常类似如图。【问题原因】:代码中配置的 AK、SK 所归属的账号,与创建 Topic 或者是 GID 的账号并不匹配,导致权限错误。【解决办法】:1.检查代码当中配置的 ak 是否有调用 topic 发送消息的权限。2.核实下 sdk 的版本,如果是平时发送消息都是正常,偶尔会出现这种异常报错信息。可以看下 sdk 版本是否是 1.7.9 版本的。如果是,建议升级sdk。1.7.9 版本的 sdk 在鉴权的时候,的确会容易出现鉴权失败的问题,此版本在健全上有一些 bug。3.检查下代码当中的接入点是否配置正确,可以 debug 看下,取到的接入点是否和控制台提供的接入点完全一致。4.检查下代码当中配置的 topic 是否与控制台创建的 topic 完全一致。5.如果以上确认过都没有问题,需要收集实例 id/地域/topic/sdk 版本等信息给到技术人员进行后端服务器状态核实。客户端发送常见异常报错客户端发送常见异常报错length limit 128k,msg properties length limit 32k.此异常为消息属性 properties 太大。CODE:13 the message body size over max value,MAX:4194304。此异常信息为消息 body 太大【解决方案】:1.消息体大小最大为 4MB,一般建议发送的消息体在 4kb 之内(性能最佳)。2.消息属性最大为 32kb,一般建议发送的消息属性在 1kb 之内(性能最佳)。3.4MB 这个上限值不能修改,这个会影响全局性能。如果消息体的确很大,建议侧优化消息体的内容,避免发送大消息或者带有链接地址的消息,或者可以缩短或者分两条发送。应用部署在 edas 当中发送消息失败【问题描述】:mq 的应用部署在 edas 当中,但是发送消息失败。【问题原因】:通过发送报错日志看到 是 ons-client-1.7.1-EagleEye.jar 报错,ons-client的版本比较低,需要升级 ons-sdk 1.8.0-EagleEye 插件。【解决方案】:到 edas 控制台点击运行时环境升降级,将 edas 的容器版本升级到 3.5.3 及其客户端发送常见异常报错客户端发送常见异常报错2.nslookup 接入点的域名看下。检查 dns 是否正确。正确情况下,会获取到绑定。这个域名的 ip,在 ping 下 ip 是否是通的 nslookup onsaddr- 发送消息报错 notsetanyresponsecode【问题描述】:发送延迟消息报错。【问题原因】:设置的 message properties 中某个属性的值过长,造成发送失败。【排查过程】:1.查询问题节点的消息,mq 控制台对应的接口是 ConsoleMessageGetBy-PagedTopic,openApi 对应的接口是 OnsMessagePageQueryByTopic。2.登录 mq 控制台,打开浏览者开发工具(win os:F12 mac os:command+F12),找到如下图所示的接口,查看返回的 response.将其进行 json 化,查看 properties 里是否存在长度比较长的属性值。客户端发送常见异常报错OnsRestMessageDoProperty-ListMessageProperty 里的属性是否有比较长的值。发送消息getuserinfobyaccesskeyfromALIYUNfailed.异常【问题描述】:发送消息的时候日志报错:com.aliyun.openservices.ons.api.impl.authority.exception.Authentica-tionException:get user info by accesskey from ALIYUN failed.异常如图【问题原因】:此问题不是权限报错,而是 AK 出现了问题,去 ak 中心根据 ak 获取子用户信40客户端发送常见异常报错息出错了,可以重新换个 ak 试试。启动发送者时报错 UnknownHostException【问题描述】:启动消息队列 RocketMQ 版的客户端时提示异常 UnknownHostException信息。【问题原因】:导致此问题的主要原因是客户端无法获取系统的主机名(Hostname)或者系统的 IP 地址。【解决方案】:请参考以下步骤进行排查:1.登录客户端所在机器。2.执行 hostname 命令,检查能否正常返回主机名。(1)如果该命令报错,请检查是否为该命令定义了别名(alias),比如在.bash_profile 文件或者.bashrc 文件中设置了 alias hostname=/usr/bin/*的别名。确保 hostname 命令能够正常返回主机名。(2)如果该命令正常执行,记录返回的主机名并继续下一步。3.检查能否 ping 通记录的主机名。(1)如果无法 ping 通,请参考 127.0.0.1$Hostname,将记录的主机名绑定到/etc/hosts 文件中。(2)如果可以 ping 通,请继续下一步。客户端发送常见异常报错客户端发送常见异常报错Tcp 协议开源 sdk 连接 mq 失败【问题描述】:Tcp 协议开源 sdk 无法连接 mq,代码层面报错。【问题回答】:可能原因:开源 sdk 接入阿里云,阿里云都是与各个开源语言的 sdk 做过适配的。因此一定需要使用阿里云官方文档上推荐的各个语言的 sdk 版本,如果使用的开源版本非阿里云提供的官网推荐使用的 sdk 版本,那么是无法成功连接到阿里云 mq 的。堆积负载常见问题Java 进程消息堆积严重【问题描述】:消费者状态页面,Group ID 的实时消息堆积量的值高于预期,且性能明显下降。【排查步骤】:1.在消息队列 MQ 控制台,通过查看消费者状态获取消息堆积的消费者实例所对应的宿主机 IP,并登录该宿主机或容器。2.执行以下任一命令查看进程 pid:-ps-ef|grep java -jps-lm3.执行以下命令查看堆栈信息:-jstack-l pid /tmp/pid.jstack4.执行以下命令查看 ConsumeMessageThread 的信息,重点关注线程的状态及堆栈:cat/tmp/pid.jstack|grep ConsumeMessageThread-A 10 color消费问题排查44堆积负载常见问题只需要注意两种状态就可以。-BLOCKED 此状态说明消费者线程被阻塞了,导致消息的消费被停滞了,从而导致消息堆积的产生。这时要通过上面的堆栈信息来查看具体是阻塞在那个接口。-WAITING 这个状态要分两种情况来说明:(1)如果是上图所显示的堆栈信息,说明消费者线程在等待消息消费,此为正常状态。(2)如果不是上图所显示的堆栈信息,可以重复上面的 3、4 两步,检查这个这个消费者线程是否一直处于这种状态,而且堆栈信息显示也是一样的。这个现象说明在消费逻辑的代码中,由于某种资源紧张,导致获取这种资源的时间较长,从而导致消息消费的耗时增长,TPS 下降,消息消费的速度跟不上消息生产的速度,从而导致消息堆积。为什么消费者堆积负载不均【问题描述】:每个消费者堆积数量差异很大,负载非常不均,具体现象如图。堆积负载常见问题堆积负载常见问题广播模式消费堆积【问题描述】:广播模式下控制台显示有大量堆积。【问题回答】:广播模式下控制台看到的这个堆积数据是无效的,广播模式下服务端不维护消费进度,消费进度在客户端维护,所以是否有堆积这个需要您客户端来维护,广播模式下我们服务端不维护消费进度,您的消费端的消费位点,我们这边不保存,这个只能您自己消费端配置好消费日志,查看消费情况的。实时消息堆积量和各个具体消费端堆积量不一致【问题描述】:消费者的实时消息堆积量有堆积量,但是各个具体的消费端却显示没有堆积量。【问题原因】:实时消息堆积量是订阅的整个 topic 的堆积量,包括重试队列的。堆积负载常见问题堆积负载常见问题 mq 的消费逻辑是这样的,启动消费者之后,消费者会一直在线。如果 topic 当中一直没有消息过来,我们会每 15 秒长轮询一次,消费者主动到 topic 当中拉取消息。如果有消息,就会将消息拉取到进行消费。所以暂时不支持挤压一定的消息之后再批量消费的。2.有序消息不支持批量消费。消费负载不均衡,有台消费者实例没有消费消息【问题描述】:一个 gid 下面,多个消费端,有一/几台机器显示堆积量为 0,其他的机器堆积量都很大。【排查步骤】:可以查看下堆积量为 0 的机器的 ons.log 日志。通过关键字搜索日志信息(注意要找到对应的 topic)。只用关注其中的 perm 的值就行,6 表示正常,如果是 4 表示则表示 mq 后端做了相关的运维操作,后面会恢复正常的,此时没有消费的客户端可以拿来容灾。堆积负载常见问题堆积负载常见问题通过重置消费位点来解决这个问题。2.如果没有,那么需要提供实例 id/地域/topic 等信息给到技术人员进行进一步的查看。消费者 rebalanceservice 线程【问题描述】:在消费者线程当中看到 rebalanceservice 线程是正常的吗?【问题回答】:这个是消费端负载均衡的线程。是一个正常状态的线程。rebalance 是有时间间隔的。堆积负载常见问题消息投递重试问题消息投递重试问题如果消息业务消费时间太久,那过多久会重新投递该消息【问题描述】:在订阅消费消息时,假如消费这条消息需要 10 分钟,那么 MQ 大概多久会重新投递该消息。【问题回答】:消费端到 mq 当中拉到消息进行消费之后,会反馈给 mq 已经成功拿到消息并且消费。如果 mq 没有接收到消费端的反馈,那么 mq 就会认为这个消息没有消费成功,那么这个消息在 topic 当中就会再次可见,那么消费者就可以再次来拉取这个消息(重试)。第一次发消息算是第 0 次,如果在 10 秒内没有给 mq 反馈,那么这个消息就会再次可见,消费端就会再去拉取这个消息,就是第一次重试了,如果在 10 秒之后,消费者给了第一次发消息(第 0 次)的响应,那么这个消费也是失败的。比如消费者现在拉取到的是 10s 之后第一次重试的,那么在之后的 30 秒之内,如果消费者给了mq 第一次重试拉到的消息的响应,这个才算是消费成功的。所以建议不要把业务逻辑放在返回给 mq 消息的代码之前,最好是保证 10 秒之内要给到 mq 响应。可以将业务逻辑放在其他地方做并发处理。消息投递重试问题消息投递重试问题2.如果是大量消息重复消费,需要核实您的代码是否和 mq 官方提供的一致,在重复消费消息的时候,消费端的网络情况,是否有 fullgc 等。如果以上都没有问题,则需要提供下具体的异常信息:实例 id/地域/topic/msgid 等,给到技术支持人员进行确认。消息消费失败,一直重试【问题描述】:消息消费失败,一直消息重试,并且重试的间隔时间都是正常的。【排查步骤】:1.需要查看下业务上关于这个消息有没有什么报错,一般消费失败是业务处理消息失败,业务如果有问题,重试多少次还是会有问题的。2.可以查看下 ons.log 日志,看下有没有异常。消息投递重试问题消息投递重试问题3.如果配置没问题,可以过会再去检查消息轨迹,因为在共享集群下,某个时间段 broker 压力比较大的时候,消费失败重试会有一定的延迟。可以多检查下,确认没有重试。4.如果以上都确认没有问题了,需要提供实例 id/地域/topic/msgid 等信息给技术人员进行查看。订阅关系问题订阅关系问题http 的消费者看不到订阅关系【问题描述】:http 的 gid 正在消费,但是 topic 当中查看不到这个订阅关系。【问题回答】:http 协议的消费者的订阅关系控制台目前不支持显示的。客户端消费常见异常报错客户端消费常见异常报错【问题回答】:线程阻塞一般是 CPU 或内存消耗过高导致,一般是业务代码处理复杂和线程数较多导致。1.建议重启一下消费端看
展开阅读全文