Spring 云侦探与 Webservicetemplate

Spring cloud sleuth with Webservicetemplate

Spring cloud sleuth 是否支持 WebserviceTemplate?我的意思是 - 我有一项服务可以调用 2 个服务 - 一个使用 RestTemplate,另一个使用 Webservicetemplate。 Rest 调用正在 Zipkin 中显示,而使用 Webservicetemplate 的 Soap 调用则没有。我是否必须将 @NewSpan 添加到我的所有 soap 调用中?不是像Resttemplate那样自动完成吗?

否 - 我们尚未添加任何有关 Webservicetemplate 的工具。您必须添加一个类似于我们为 RestTemplate 添加的拦截器。您必须将所有跟踪 headers 传递给请求,以便另一方可以正确解析它。

这里是如何使用 spring 云侦探与 Webservicetemplate 的示例,

如果服务A向服务B发送请求,

首先,您将通过以下代码

在已发送请求的header中发送跟踪ID
@Service
public class WebServiceMessageCallbackImpl implements WebServiceMessageCallback {

@Autowired
private Tracer tracer;

public void doWithMessage(WebServiceMessage webServiceMessage) throws TransformerException {
    Span span = tracer.currentSpan();
    String traceId = span.context().traceId();
    SoapMessage soapMessage = (SoapMessage) webServiceMessage;
    SoapHeader header = soapMessage.getSoapHeader();
    StringSource headerSource = new StringSource("<traceId>" + traceId + "</traceId>");
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.transform(headerSource, header.getResult());
}
}

然后在服务 B 中,您将创建一个拦截器,然后从即将到来的请求的 header 中读取跟踪 ID,然后将此跟踪 ID 放入 MDC 中,如下面的代码

@Slf4j
@Component
public class HttpInterceptor2 extends OncePerRequestFilter {

private final String traceId = "traceId";
@Autowired
private Tracer tracer;


@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException {


    String payload = new String(request.getInputStream().readAllBytes(), StandardCharsets.UTF_8);

    String traceId = traceId(payload);
    MDC.put("traceId", traceId);

    try {
        chain.doFilter(request, response);
    } finally {
        MDC.remove(traceId);
    }

}

private String traceId(String payload) {
    StringBuilder token = new StringBuilder();

    if (payload.contains(traceId)) {

        int index = payload.indexOf(traceId);

        while (index < payload.length() && payload.charAt(index) != '>') {
            index++;
        }
        index++;

        for (int i = index; ; i++) {
            if (payload.charAt(i) == '<') {
                break;
            }
            token.append(payload.charAt(i));
        }
    }
    if (token.toString().trim().isEmpty()) {
        token.append(traceId());
    }
    return token.toString().trim();

}

private String traceId() {
    Span span = tracer.currentSpan();
    String traceId = span.context().traceId();
    return traceId;
}

}