2016-11-10 5 views
1

In einer Microservice-Umgebung sehe ich zwei Hauptvorteile durch die Verfolgung von Anfragen durch alle Microservice-Instanzen über einen gesamten Geschäftsprozess.Spring Sleuth - Tracing Failures

  1. Finding Latenz Lücken zwischen oder in Dienstinstanzen
  2. Finding Wurzeln von Fehlern, ob technischer oder in Bezug auf das Business Case

Mit Zipkin gibt es ein Werkzeug, das das erste Problem behebt. Aber wie kann das Tracing genutzt werden, um Fehler in Ihrer Microservice-Landschaft aufzudecken? Ich möchte definitiv alle fehlerbehafteten Spannen verfolgen, aber nicht jede Anfrage, bei der nichts schief gelaufen ist. Wie erwähnt here könnte ein benutzerdefinierter Sampler verwendet werden.

Alternativ können Sie Ihre eigene Sampler-Bean-Definition registrieren und programmatisch die Entscheidung treffen, die Anfragen abgetastet werden soll. Sie können intelligentere Entscheidungen treffen, welche Dinge zu verfolgen sind, zum Beispiel, indem Sie erfolgreiche Anfragen ignorieren, vielleicht prüfen, ob sich eine Komponente in einem Fehlerzustand befindet, oder wirklich irgendetwas anderes.

Also habe ich versucht, das zu implementieren, aber es funktioniert nicht oder ich habe es falsch verwendet. So , wie die Blog-Post vorgeschlagen registrierte ich meine eigenen Sampler:

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

Und in meinem Controller erstelle ich einen neuen Span, der als Fehler markiert wird, wenn eine Ausnahme wirft

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

Jetzt , das funktioniert nicht. Wenn ich/calc/a anfordere, wird die Methode Sampler.isSampled (Span) aufgerufen, bevor die Controller-Methode eine NumberFormatException auslöst. Das bedeutet, wenn isSampled() den Span überprüft, hat es noch keine Tags. Und die Sampler-Methode wird später im Prozess nicht erneut aufgerufen. Nur wenn ich den Sampler öffne und erlaube, dass jeder Bereich abgetastet wird, sehe ich später meine getaggte Fehlerspanne in Zipkin. In diesem Fall wurde Sampler.isSampled (Span) nur einmal aufgerufen, aber HttpZipkinSpanReporter.report (Span) wurde dreimal ausgeführt.

Wie also würde der Anwendungsfall aussehen, nur Traces zu übertragen, die Fehlerspannen haben? Ist dies sogar eine korrekte Methode, um einen Bereich mit einem beliebigen "error_" -Tag zu versehen?

Antwort

0

Die Stichprobenentscheidungsentscheidung wird für eine Ablaufverfolgung getroffen. Das heißt, wenn die erste Anfrage eingeht und die Spanne erstellt wird, müssen Sie eine Entscheidung treffen. Sie haben zu diesem Zeitpunkt keine Tags/Gepäckstücke, daher sollten Sie sich nicht auf den Inhalt der Tags verlassen, um diese Entscheidung treffen zu können. Das ist ein falscher Ansatz.

Sie nehmen einen sehr kundenspezifischen Ansatz. Wenn Sie diesen Weg gehen möchten (was nicht empfohlen wird), können Sie eine benutzerdefinierte Implementierung eines 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 erstellen. SpanReporter ist derjenige, der Spannweiten an Zipkin sendet. Sie können eine Implementierung erstellen, die eine vorhandene SpanReporter Implementierung umschließt und die Ausführung nur dann an sie delegiert, wenn einige Werte von Tags übereinstimmen. Aber aus meiner Sicht klingt das nicht richtig.

+0

Ok, dann habe ich Sampler.isSampled (Span span) falsch interpretiert, weil nur der erste Span einer Anfrage, die eine Microservice-Barriere erreicht, von einem Sampler betrachtet wird. Ich nehme aus Ihrer Antwort, dass Sleuth nicht für die Fehlersuche verwendet werden sollte, wie im spring.io-Blogpost erwähnt, erwähnte ich. Ist es jedoch möglich, von einer Spanne auf den aktuellen HTTP-Status zuzugreifen, oder besser: den gesamten HTTP-Header?In diesem Fall könnte ich nur Anfragen mit einem Fehlerstatus an zipkin melden. – Danny

+1

Das stimmt nicht. Sie können * auch * Sleuth verwenden, um Fehler zu verfolgen. Beachten Sie, dass Sie in Zipkin aufgrund von Sampling nur (standardmäßig) 10% der Traces sehen, so dass Sie einen Fehler verfolgen können, wenn Sie ihn tatsächlich abtasten. Mit der Version 1.2.0 Sleuth können Sie Gepäck benutzen. Dort können Sie setzen, was Sie wollen und dieser Kontext wird durch das ganze System weiter verbreitet. –

+0

@marcin isSampled wird für jeden Bereich aufgerufen werden, oder? Wenn ich Impl von PercentageBasedSampler sehe, gibt es eine Wahrscheinlichkeit, dass wenige Spannen in einer Spur verpasst werden. Ist das nicht richtig? –