场景描述
通过RocketMQ SDK接入云消息队列 RocketMQ 版时报错No route info。
适用SDK
商业版 HTTP SDK(仅消息队列RocketMQ 4.0系列实例支持。详见各版本SDK说明)
商业版1.x SDK(Java, Remoting协议),依赖坐标样例(商业版SDK版本必须大于1.7.9):
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>ons-client</artifactId> <version>1.9.1.Final</version> </dependency>开源SDK(Java,Remoting协议,artifactId为rocketmq-client),依赖样例坐标(开源SDK版本必须大于4.5.2,请检查代码配置和SDK版本):
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.9.2</version> </dependency>
简要排查思路
根据实例系列以及SDK协议、语言的不同组合,会有不同的排查方式,需要根据具体场景进行排查。
排查详情
HTTP协议SDK
核实代码中配置的接入点与需要接入的目标实例的控制台显示的接入点是否一致,一致的话检查Topic是否创建。
检查实例详情页是否存在命名空间,有命名空间的实例的生产/消费代码中需要配置 instanceId,详见代码示例。无命名空间实例instanceId则需要传入null空值或字符串空值。

TCP Remoting协议 SDK
确认报错
no router info的资源是否为TBW102或者RMQ_SYS_TRACE_TOPIC。TBW102:是开源RocketMQ用来自动创建Topic使用的,云消息队列 RocketMQ 版的Topic是管控资源,无法自动创建,且TBW102不会影响客户端正常使用,可以忽略。
RMQ_SYS_TRACE_TOPIC:开源RocketMQ用来上报消息轨迹的Topic,在接入云消息队列 RocketMQ 版需要配置云上轨迹兼容,开源Remoting协议SDK(artifactId为rocketmq-client)可以通过以下方式配置,详见收发普通消息(三种方式)。
public static void main(String[] args) throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("YOUR GROUP ID", getAclRPCHook(), new AllocateMessageQueueAveragely(), true, null); consumer.setNamesrvAddr("http://xxxx.mq-internet.aliyuncs.com:80"); //阿里云上消息轨迹需要设置为CLOUD方式,在使用云上消息轨迹的时候,需要设置此项,如果不开启消息轨迹功能,则运行不设置此项。 consumer.setAccessChannel(AccessChannel.CLOUD); ...... consumer.start(); }
核实代码中配置的接入点与需要接入的目标实例的控制台显示的接入点是否一致,一致的话检查Topic是否创建。
在Java Remoting协议客户端,可以查看客户端日志中是否存在网络连接异常,日志路径:
开源社区Java SDK路径
/{user.home}/logs/rocketmqlogs/rocketmq_client.log商业1.x版本路径
/{user.home}/logs/ons.log。
如果日志中存在网络连接异常问题需要先保证网络畅通,可以通过
ping以及telnet命令来检测。需要注意这里不能仅通过telnet测试与接入点的网络连接,还需要看日志中报错的地址是什么,然后通过telnet测试与日志中报错地址的网络连接。查看日志中是否存在鉴权失败问题,若存在鉴权失败问题需要先解决权限问题然后再查看是否还有报错。
4.0系列实例参考云消息队列 RocketMQ 版自定义权限策略,在授权的时候需要根据实例是否存在命名空间选择具体的策略。
核实是否有使用spring-cloud-stream框架,详见配置说明。
如果实例详情页存在命名空间,则Topic需要配置
实例id%Topic。如果实例详情页不存在命名空间,则配置Topic名称即可。判断实例是否存在命名空间可参考HTTP协议SDK中的说明。
核实是否通过公网接入Serverless实例。
通过公网接入Serverless实例需要使用指定版本的SDK以及设置命名空间。
通过内网接入Serverless实例,或者通过公网/内网接入其他类型的5.0系列实例则不需要设置命名空间。
// SDK版本支持:rocketmq-client >= 5.2.0版 producer.setNamespaceV2("rmq-cn-xxxxxxx"); consumer.setNamespaceV2("rmq-cn-xxxxxxx"); // SDK版本支持:rocketmq-client-java >= 5.0.6版 StaticSessionCredentialsProvider staticSessionCredentialsProvider = new StaticSessionCredentialsProvider("访问控制页获取用户信息", “访问控制页获取”); //在RocketMQ 访问控制页面获取用户名和密码 ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder() .setEndpoints("rmq-cn-xxxxxxx.cn-hangzhou.rmq.aliyuncs.com:8080") .setNamespace("rmq-cn-xxxxxxx") .setCredentialProvider(staticSessionCredentialsProvider) .build(); // ons >= 1.9.0.Final properties.setProperty(PropertyKeyConst.Namespace, "rmq-cn-xxxxxxx");