今天的博客主题
MQ消息中间件 --》RocketMQ --》RocketMQ实战异常汇总
目录
No route info of this topic, xxxTopic
CODE: 1 DESC: The broker does not support consumer to filter message by SQL92
broker配置文件增加aclEnable=true配置开启acl权限认证,MQ控制台Cluster模块异常
CODE: 208 DESC: query message by key finished, but no message.
[10015:signature-failed] unable to calculate a request signature. Algorithm HmacSHA1 not available
No route info of this topic, xxxTopic
按照gitHub上rocketMQ提供的Demo进行生产者发送消息到MQ,出现下面错误
错误原因:没有创建主题,主题不存在,导致MQ路由不到此主题。
解决方案:通过控制台,来创建主题。
还有就是可以在启动broker的时候设定 自动创建Topic nohup sh mqbroker -n localhost:9876 autoCreateTopicEnable=true &
不建议在生产环境这样配置,(弊端待补充)。
CODE: 1 DESC: The broker does not support consumer to filter message by SQL92
错误原因:目前代理不支持消费者通过SQL92过滤消息
解决方案:在broker的配置文件添加 enablePropertyFilter = true 来支持SQL92方式过滤消息
MQ控制台查询%DLQ%Topic消息异常
模拟消息重试,16次之后消息不在消费,消息已经进入死信队列,但想通过控制台查询死信队列里有没有该消息,输入条件之后 SEARCH 出现异常:
{
"status": -1,
"data": null,
"errMsg": "org.apache.rocketmq.client.exception.MQClientException:
Can not find Message Queue for this topic, %DLQ%CG_RDATA_CLINICAL_NCT\nSee
http://rocketmq.apache.org/docs/faq/ for further details."
}
根据异常信息发现是“未找到此主题的消息队列”
在服务端执行命令:sh mqadmin topicList -n localhost:9876,看该topic是否存在,不存在的话那就是服务端没有自动创建死信队列的topic
如果存在,查看该topic的路由信息,执行命令:sh mqadmin topicRoute -n localhost:9876 -t %DLQ%你的死信队列TOPIC
如果看到"perm":2,那就有问题。【至于这个"perm":2 和 "perm":6 是一个权限的问题。】
如果是"perm":2那就改一下执行命令:sh mqadmin updateTopic -b localhost:10911 -n localhost:9876 -t %DLQ%你的死信队列TOPIC -p 6
如果以上情况都不是,那就在搜索引擎下吧。
broker配置文件增加aclEnable=true配置开启acl权限认证,MQ控制台Cluster模块异常
ACL (Access Control List 访问控制列表)
Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 1 DESC: org.apache.rocketmq.acl.common.AclException: request's extFields value is null,org.apache.rocketmq.acl.plain.PlainAccessValidator.parse(PlainAccessValidator.java:57)
具体抛出异常位置的地方
通过下面几行代码就知道了这个ExtFields里面装载是ACCESS_KEY和签名什么的。
在Broker项目下的BrokerController这个类里的initialAcl就是来初始化验证的位置。
MQ控制台是两年前的一个项目,而acl认证是MQ最近4.4.0版本出来的,不排除控制台这边没有进行对其支持。
具体分析:
MQ-console开发人员对MQAdmin做了一个切面,控制台上有些模块操作需要读到broker。
通过这个切面发现不单单是cluster这一块,读topic列表时,也到了这个切面。
看下这个切面里的具体做法,黄色线标识区域就是初始化MQAdmin实例的。
就延伸到这个方法里了,来实例化DefaultMQAdminExt,去操作服务端.
DefaultMQAdminExt具体的构造函数,提供了权限访问的构造方法。可以发现,在控制台这边没有用带RPCHOOK的构造函数。
哪只要把实例化DefaultMQAdminExt的代码修改一下就好了。
Before change:
DefaultMQAdminExt defaultMQAdminExt;
if (timeoutMillis > 0) {
defaultMQAdminExt = new DefaultMQAdminExt(timeoutMillis);
}else {
defaultMQAdminExt = new DefaultMQAdminExt();
}
After change:
DefaultMQAdminExt defaultMQAdminExt;
if (timeoutMillis > 0) {
defaultMQAdminExt = new DefaultMQAdminExt(getAclRPCHook(),timeoutMillis);
}else {
defaultMQAdminExt = new DefaultMQAdminExt(getAclRPCHook());
}
static RPCHook getAclRPCHook() {
return new AclClientRPCHook(new SessionCredentials(ACL_ACCESS_KEY,ACL_SECRET_KEY));
}
ACL_ACCESS_KEY,ACL_SECRET_KEY需要定义一下,写到配置文件,然后从配置文件读取。
最好是把控制台上的所有功能点,都点一遍 看有什么异常,差不多服务端开了acl之后 控制台上有部分功能会异常。
CODE: 208 DESC: query message by key finished, but no message.
在做demo时,服务端都是默认配置,没有aclEnable=true这一项ÿ