在instrumentation-spring-rabbit中,为什么brave要去掉消息的headers?

In instrumentation-spring-rabbit, why does brave remove the headers of the message?

instrumentation-spring-rabbit模块中,brave正在提取和删除 headers,为什么?

我探索了其他仪器(spring-webhttpclientokhttp3grpc 等)勇敢地从不删除 headers - 它持有跟踪 keys/extras - 来自原始消息。

删除 headers 有一个副作用,即重试 拦截器 - already added by spring-rabbit - 正在第二次尝试处理消息,但是因为brave在第一次重试的时候去掉了headers,以后的重试就找不到了。

消息跟踪在两个主要方面不同于典型的 RPC 跟踪。因为它是不同的,所以与 RPC 比较并不是找出前进道路的最佳方式。我将在这里简要提及几件事,这些事情主要在我就该主题所做的 slide deck 中。

  1. 在消息传递中,消费者和消息处理器之间通常没有线程上下文传递。这与 RPC 不同,RPC 通常至少在请求端进行切换。
  2. 当我们有一个线程上下文时,我们应该用它来建立parent信息(在rabbit处理中就是这样)。然而,通常情况并非如此。因此,当我们不知道消息处理抽象时,我们经常 re-serialize headers 在消息上。

在您的示例中,您谈论的是 spring-rabbit,它在处理块期间使用线程上下文适当地设置 "current span"。由于我们不想将 thread-based 上下文与消息中的内容混淆,我们清除了 headers.

"retry"案确实使这一点受到质疑。在那种情况下 parent 应该是什么,如何知道它?相关检测的问题之一是我们实际上没有看到使用消息的代码。

具体来说,rabbitmq 轮询工具不存在,所以我们放一个 "fake consumer span" 来追溯这个问题。如果消息是 re-played.. 也许第二个消费者跨度是有效的。坦率地说,我们没有考虑到这一点。

无论如何,我的观点是我们不应该过分关注消息跟踪和 RPC 之间的区别,因为那里会有一些故意的区别。让我们关注差距本身,可能会在 gitter 上这样做,我认为这会导致 github 问题。

无论如何,我希望上下文能回答您的问题,即使它不会改变代码当前正在执行的操作这一事实。

@Andrain 感谢您的回答和支持,这真的很有帮助。

作为解决方法,我们需要将重试拦截器移到链中。

@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;
        }
    };
}