在 Spring Boot 应用程序中,在哪里关闭对反应式端点的请求的千分尺包袱?

Where to close micrometer baggage for a request to a reactive endpoint in a Spring Boot app?

提问人:machinery 提问时间:11/14/2023 更新时间:11/14/2023 访问量:68

问:

在我的Spring Boot 3.1+应用程序中,我有一个反应式端点,如下所示:

@PostMapping
public Mono<Result> doStuff(@RequestBody String body) {
    // ...
}

此调用触发了我的反应式代码流,我希望在其中设置 MDC 上下文。我还有一个过滤器,负责设置如下所示的 MDC 上下文:

public class MyFilter extends OncePerRequestFilter {

    private final Tracer tracer;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest,
                                    HttpServletResponse httpServletResponse,
                                    FilterChain filterChain) throws ServletException, IOException {

            var baggage = tracer.createBaggageInScope(getBaggageName(), getBaggageValue())
            try {
                filterChain.doFilter(httpServletRequest, httpServletResponse);
            } finally {
                baggage.close();
            }
    }

    // ...

}

但这似乎在反应流完成之前过早地关闭了包袱(导致 MDC 在某些地方消失)。

另一方面,在终结点的代码中(在方法的反应流中)设置包袱并将其关闭将使包袱在异常处理程序中不可用。doStuffdoFinally

Spring 团队似乎以类似的方式实现了这一点,例如:ServerHttpObservationFilter,但是在他们的情况下,他们不会关闭异步处理的观察。 我还考虑过不关闭行李(这似乎很好),但千分尺跟踪文档告诉我“必须关闭行李,以免示波器泄漏”。

关于如何解决这个问题的任何想法?在哪里最好地关闭这个包袱,以便它在整个反应流中可用(如果有必要的话)?

顺便说一句,我已经在使用 Reactor 的,并且在适用的情况下。Hooks.enableAutomaticContextPropagation()contextWrite

spring-boot spring-webflux spring-cloud-sleuth spring-micrometer micrometer-traceing

评论


答: 暂无答案