【RocketMQ】记录一次广播模式消费遇到的问题
文章目录
- 问题详情
- 问题定位
- 问题解决
问题详情
业务团队反馈使用RocketMQ时,消费失败,报如下的错误:
错误1:
java.io.FileNotFoundException: C:\Users\zhurunhua\.rocketmq_offsets\10.201.241.170@172.24.140.45:9876;172.24.130.73:9876@12188\sas_rule_event_consumer\offsets.json.tmp (文件名、目录名或卷标语法不正确。)
at java.io.FileOutputStream.open0(Native Method) ~[?:?]
at java.io.FileOutputStream.open(FileOutputStream.java:298) ~[?:?]
at java.io.FileOutputStream.<init>(FileOutputStream.java:237) ~[?:?]
错误2:
问题定位
根据异常信息中的一些文字:“.rocketmq_offsets”、“offsets.json”,能判断出:
- 程序使用了广播模式消费,因为使用广播模式消费的话,消费者会在本地保存offset信息(如果是集群模式消费,保存在服务端Broker上)
- 在创建本地offset文件的时候,因为命名规则问题,导致文件夹/文件创建失败
所以需要查看源码,确定一下在广播模式下,offset文件的生成规则即可定位到问题,阅读源码,发现两个相关联的类:
- org.apache.rocketmq.client.ClientConfig
- org.apache.rocketmq.client.consumer.store.LocalFileOffsetStore
这里定义了文件的路径和文件名,默认为:/用户根目录/.rocketmq_offset/消费者ClientId/消费组名/offsets.json
这里定义了消费者ClientId的生成规则,默认为:本机IP@instanceName@unitName
根据之前程序日志分析,现在问题就出在instanceName上,这个字段默认是取系统参数:rocketmq.client.name的值,如果没有配置,则为字符串“DEFAUT”,当为“DEFAULT”时,会被转为当前应用的PID
但是从程序报错日志来看,本地offset文件的命名规则并不是上述这样,而是本地IP@NameServer地址@应用PID,而业务团队使用的RocketMQ客户端并非原生的客户端,是公司内部封装的xcloud客户端,所以猜测,xcloud客户端内将Instance参数替换成了nameserver,查看xcloud代码,果然发现:
问题解决
方案一:修改xcloud代码,保证ClientId的生成规则和官方一致;
方案二:缩短nameserver地址;
方案三:使用原生的Consumer客户端
还没有评论,来说两句吧...