开启spring-amqp批量消费后出现ArrayList转Message的ClassCastException
错误根因
该类型转换异常是Spring Cloud Sleuth旧版本的链路追踪组件TracingRabbitListenerAdvice未适配批量消费场景导致的:开启批量消费后,容器传给监听器的入参是消息列表,而旧版本的该切面直接将入参强转为单个org.springframework.amqp.core.Message对象,因此抛出ArrayList转Message的类型转换错误。
解决方案
方案1:升级Spring Cloud Sleuth版本
将Spring Cloud版本升级到Hoxton.SR12及以上,该版本对应的Sleuth组件已经修复了批量消费场景的兼容问题,适配了批量消息的链路追踪逻辑,无需额外修改业务代码即可解决异常。
方案2:排除批量容器的链路追踪切面(适合暂时无法升级版本的场景)
在定义consumerBatchContainerFactory时,手动指定切面链,排除掉TracingRabbitListenerAdvice,修改后的容器工厂配置如下:
@Bean public SimpleRabbitListenerContainerFactory consumerBatchContainerFactory( SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory, ObjectProvider<ListenerContainerAdvice> adviceProvider) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); factory.setPrefetchCount(1000); factory.setBatchListener(true); factory.setBatchSize(1000); factory.setConsumerBatchEnabled(true); factory.setReceiveTimeout(1000L); // 过滤掉TracingRabbitListenerAdvice,只保留其他自定义切面 List<ListenerContainerAdvice> advices = adviceProvider.stream() .filter(advice -> !advice.getClass().getName().contains("TracingRabbitListenerAdvice")) .collect(Collectors.toList()); factory.setAdviceChain(advices.toArray(new Advice[0])); configurer.configure(factory, connectionFactory); return factory; }
注意:该方案会导致批量消费的链路追踪失效,如果需要保留链路追踪能力,优先选择方案1。
方案3:自定义兼容批量消费的链路追踪切面
如果既不能升级版本也不想丢失链路追踪能力,可以自行重写TracingRabbitListenerAdvice的逻辑,增加批量消息判断:当入参是List类型时遍历每个消息提取链路信息,否则按原有逻辑处理单个消息,将重写后的切面注入到Spring容器中覆盖官方默认实现即可。
内容的提问来源于stack exchange,提问作者Nirmal
相关产品推荐
相关产品推荐

