2016-11-10 72 views
1

在一个微服务环境中,我看到了通过整个业务流程中的所有微服务实例跟踪请求的两个主要好处。之间或在服务实例 Spring Sleuth - 跟踪失败

  • 查找故障的根源,无论是技术还是关于商业案例
  • 随着Zipkin有一个工具,它解决了第一个问题

    1. 查找延迟差距。但是如何使用追踪来揭示微服务领域的失败呢?我绝对想跟踪所有错误折衷的跨度,但不是每个请求都没有出错。 如提到的here可以使用自定义的采样器。

      或者,您可以注册您自己的Sampler bean定义并以编程方式决定哪些请求应该被采样。例如,您可以通过忽略成功的请求,可能会检查某个组件是否处于错误状态或其他任何其他情况来做出更明智的选择。

      所以我试图实现,但它不工作,或者我用它错了。 所以,作为博客文章建议我注册了自己的取样:

      @Bean 
          Sampler customSampler() { 
          return new Sampler() { 
           @Override 
           public boolean isSampled(Span span) { 
      
            boolean isErrorSpan = false; 
            for(String tagKey : span.tags().keySet()){ 
             if(tagKey.startsWith("error_")){ 
              isErrorSpan = true; 
             } 
            } 
            return isErrorSpan ; 
           } 
          }; 
      } 
      

      而在我的控制,我创建一个新的跨度,如果有异常引发

      private final Tracer tracer; 
      
      @Autowired 
      public DemoController(Tracer tracer) { 
          this.tracer = tracer; 
      } 
      
      @RequestMapping(value = "/calc/{i}") 
      public String calc(@PathVariable String i){ 
          Span span = null; 
          try { 
           span = this.tracer.createSpan("my_business_logic"); 
           return "1/" + i + " = " + new Float(1.0/Integer.parseInt(i)).toString(); 
          }catch(Exception ex){ 
           log.error(ex.getMessage(), ex); 
      
           span.logEvent("ERROR: " + ex.getMessage()); 
           this.tracer.addTag("error_" + ex.hashCode(), ex.getMessage()); 
           throw ex; 
          } 
          finally{ 
           this.tracer.close(span); 
          } 
      } 
      

      现在正在被标记为错误,这是行不通的。如果我请求/ calc/a,则在Controller方法抛出NumberFormatException之前调用Sampler.isSampled(Span)方法。这意味着,当isSampled()检查Span时,它没有标签。采样器方法在以后的过程中不再被调用。只有当我打开采样器并允许采样每个跨度时,我才会在Zipkin中看到我标记的错误跨度。在这种情况下,Sampler.isSampled(Span)仅被调用1次,但HttpZipkinSpanReporter.report(Span)被执行了3次。

      那么,什么样的用例看起来像只传输具有错误跨度的跟踪?这甚至是用一个任意的“error_”标签标记跨度的正确方法吗?

    回答

    0

    采样决定是针对跟踪进行的。这意味着当第一个请求进入并创建跨度时,您必须做出决定。您目前没有任何标签/行李,因此您不得依赖标签的内容来作出此决定。这是一个错误的方法。

    您正在采取非常自定义的方法。如果你想这样做(这是不推荐的),你可以创建一个SpanReporter - https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanReporter.java#L30的自定义实现。 SpanReporter是发送跨度到zipkin的。您可以创建一个实现,该实现将包装现有的SpanReporter实现,并且只有在某些标记值匹配时才会将执行委托给它。但从我的角度来看,这听起来不对。

    +0

    好吧,那么我错误地解释了Sampler.isSampled(Span span),因为采样器只考虑了一个请求的第一个Span,这个请求会碰到微服务障碍。我从你的回答中了解到,Sleuth不应该用于失败追踪,正如我在上面提到的spring.io博客文章中所建议的那样。但是,是否可以从跨度访问当前HTTP状态,或者更好:整个HTTP标头?在这种情况下,我只能报告错误状态为zipkin的请求。 – Danny

    +1

    这是不正确的。你还可以*使用侦查追踪失败。由于抽样记住,您只会在Zipkin中(默认情况下)显示10%的痕迹,因此如果您实际采样它们就能够追踪失败。使用1.2.0 Sleuth版本,您可以使用行李。在那里,你可以放任何你想要的东西,并且上下文在整个系统中进一步传播。 –

    +0

    @marcin isSampled将被调用的每个跨度的权利?如果我看到基于PercentageBasedSampler的impl,那么就有可能在跟踪中遗漏少量跨度。这不对吗? –

    相关问题