2 回答
TA贡献1858条经验 获得超8个赞
邮件跟踪在两个主要方面与典型的 RPC 跟踪不同。因为它是不同的,所以与RPC相比并不是找出前进道路的最佳方法。我将在这里简要提及几件事,这些事情主要在我为该主题制作的幻灯片中。
在消息传递中,通常没有在使用者和消息处理器之间传递线程上下文。这与 RPC 不同,RPC 通常至少在请求端有一个切换。
当我们有一个线程上下文时,我们应该使用它来建立父信息(兔子处理就是这种情况)。但是,情况往往并非如此。因此,当我们不知道消息传递处理抽象时,我们经常重新序列化消息上的标头。
在你的例子中,你说的是spring-rabbit,它在处理块期间使用线程上下文来适当地设置“当前跨度”。由于我们不想将基于线程的上下文与消息中的内容混淆,因此我们清除了标头。
“重试”案确实对此提出了质疑。在这种情况下,父母应该是什么,如何知道?有问题的检测的一个问题是,我们实际上没有看到使用消息的代码。
具体来说,rabbitmq轮询工具不存在,所以我们放了一个“假的消费者跨度”来追溯性地解释这一点。如果消息已重新播放。也许第二个消费者跨度是有效的。坦率地说,我们没有考虑这一点。
无论如何,我的观点是,我们不应该过分关注消息传递跟踪和RPC之间的差异,因为那里会有一些有意的差异。让我们专注于差距本身,并可能在gitter上这样做,我认为这会导致github问题。
无论如何,我希望上下文可以回答您的问题,即使它不会改变代码当前执行其功能的事实。
TA贡献1802条经验 获得超5个赞
作为一种解决方法,我们需要将重试拦截器沿链向下移动。
@Bean
@Order
BeanPostProcessor reorderingSimpleRabbitListenerContainerFactory() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (SimpleRabbitListenerContainerFactory.class.isAssignableFrom(bean.getClass())) {
final Class<RetryOperationsInterceptor> retryInterceptor = RetryOperationsInterceptor.class;
Advice[] adviceChain = ((SimpleRabbitListenerContainerFactory) bean).getAdviceChain();
Arrays.sort(adviceChain, (o1, o2) -> {
if (o1.getClass().isAssignableFrom(retryInterceptor)) {
return 1;
}
if (o2.getClass().isAssignableFrom(retryInterceptor)) {
return -1;
}
return 0; // it is stable sort, so no worry
});
}
return bean;
}
};
}
添加回答
举报