【问题标题】:Java micro service distributed tracing with Istio使用 Istio 进行 Java 微服务分布式跟踪
【发布时间】:2020-06-11 12:29:58
【问题描述】:

Kubernetes 和 Istio 已安装在集群中。三个微服务部署为 POD。流量是

Micro service A to Micro Service B calls => HTTP
Micro service B to Micro service C calls => via Kafka
Micro service A expose a HTTP API to outside 

我猜当客户端点击 Ingres 时,Istio 在 HTTP 标头中生成 traceId 和 spanId 并进入服务 A。 这些 spanId 和 traceId 是否在不使用 Spring Cloud sleuth 之类的单独 API 的情况下传播到微服务 B 和 C?

【问题讨论】:

    标签: istio spring-cloud-sleuth


    【解决方案1】:

    不,Istio 不提供跟踪标头传播。但是,它可以在应用程序端进行配置,而无需使用 3rd 方 API。

    根据Istio 文档:

    Istio 利用 Envoy’s distributed tracing 功能提供开箱即用的跟踪集成。具体来说,Istio 提供了安装各种跟踪后端和配置代理以自动向它们发送跟踪跨度的选项。请参阅 ZipkinJaegerLightStep 任务文档,了解 Istio 如何与这些跟踪系统配合使用。


    Istio 文档还有一个 example 用于 bookinfo 演示应用程序的应用程序端标头传播:

    跟踪上下文传播

    虽然 Istio 代理能够自动发送 span,但它们需要一些提示来将整个跟踪联系在一起。应用程序需要传播适当的 HTTP 标头,以便在代理发送跨度信息时,跨度可以正确关联到单个跟踪中。

    为此,应用程序需要从传入请求收集以下标头并将其传播到任何传出请求:

    • x-request-id
    • x-b3-traceid
    • x-b3-spanid
    • x-b3-parentspanid
    • x-b3-sampled
    • x-b3-flags
    • x-ot-span-context

    此外,基于OpenCensus(例如 Stackdriver)的跟踪集成会传播以下标头:

    • x-cloud-trace-context
    • traceparent
    • grpc-trace-bin

    如果您查看示例 Python productpage 服务,例如,您会看到应用程序使用 OpenTracing 库从 HTTP 请求中提取所需的标头:

    def getForwardHeaders(request):
        headers = {}
    
        # x-b3-*** headers can be populated using the opentracing span
        span = get_current_span()
        carrier = {}
        tracer.inject(
            span_context=span.context,
            format=Format.HTTP_HEADERS,
            carrier=carrier)
    
        headers.update(carrier)
    
        # ...
    
        incoming_headers = ['x-request-id']
    
        # ...
    
        for ihdr in incoming_headers:
            val = request.headers.get(ihdr)
            if val is not None:
                headers[ihdr] = val
    
        return headers
    
    

    评论应用程序 (Java) 做了类似的事情:

    @GET
    @Path("/reviews/{productId}")
    public Response bookReviewsById(@PathParam("productId") int productId,
                                @HeaderParam("end-user") String user,
                                @HeaderParam("x-request-id") String xreq,
                                @HeaderParam("x-b3-traceid") String xtraceid,
                                @HeaderParam("x-b3-spanid") String xspanid,
                                @HeaderParam("x-b3-parentspanid") String xparentspanid,
                                @HeaderParam("x-b3-sampled") String xsampled,
                                @HeaderParam("x-b3-flags") String xflags,
                                @HeaderParam("x-ot-span-context") String xotspan) {
    
      if (ratings_enabled) {
        JsonObject ratingsResponse = getRatings(Integer.toString(productId), user, xreq, xtraceid, xspanid, xparentspanid, xsampled, xflags, xotspan);
    
    

    当您在应用程序中进行下游调用时,请确保包含这些标头。

    【讨论】:

    • 对于 Java 应用程序可以使用 Spring Cloud sleuth 完成吗?因为每个 HTTP 调用都需要修改它的方式,并且 Kafka 必须采用不同的方法(服务 B 到服务 C 调用)。
    • 对不起,我不熟悉 Spring Cloud sleuth 框架。我找不到很多关于你的工具组合的信息,有一个 ebook 有一些关于它的信息。
    猜你喜欢
    • 2019-12-24
    • 2019-02-01
    • 1970-01-01
    • 2021-05-20
    • 2018-05-19
    • 1970-01-01
    • 2018-07-29
    • 2019-10-24
    • 1970-01-01
    相关资源
    最近更新 更多