Jaeger Integration With Spring Boot Application (Svenska)

(Himank Batra) (9 september , 2020)

Jaeger Integration med fjäderstartapplikation

Låt oss först förstå vad som är Jaeger

Jaeger är programvara med öppen källkod för spårning av transaktioner mellan distribuerade tjänster.

Det används för övervakning och felsökning av komplexa mikrotjänstmiljöer.

Riddelningsföretaget Uber utvecklade Jaeger som ett open source-projekt 2015. Det accepterades som ett moln Inkubationsprojekt Native Computing Foundation (CNCF) 2017 och befordrades till examenstatus 2019.

Vad är distribuerad spårning?

Distribuerad spårning är ett sätt att se och förstå en hel kedja av händelser i en komplex interaktion mellan mikrotjänster.

Modern, molnintegrerad mjukvaruutveckling förlitar sig på mikrotjänster: oberoende tjänster som alla har olika kärnfunktioner. När en användare gör en begäran i en app svarar många enskilda tjänster för att ge ett resultat.

Ett enda samtal i en app kan åberopa dussintals olika tjänster som interagerar med varandra. Hur kan utvecklare och ingenjörer isolera ett problem när något går fel eller en begäran går långsamt? Vi behöver ett sätt att hålla reda på alla anslutningar.

Det är där distribuerad spårning kommer in. Den körs ofta som en del av ett servicenät, vilket är ett sätt att hantera och observera mikrotjänster.

Jaeger använder distribuerad spårning för att följa sökvägen för en begäran genom olika mikrotjänster. Istället för att gissa kan vi se en visuell representation av samtalsflödet.

Organiserad information om transaktioner är användbar för felsökning och optimering. Jaeger innehåller verktyg för att övervaka distribuerade transaktioner, optimera prestanda och latens och utföra rotorsaksanalys (RCA), en metod för problemlösning.

Jaeger-terminologi och komponenter

Jaeger presenterar körningsförfrågningar som spår . Ett spår visar data / exekveringsvägen genom ett system.

Ett spår består av en eller flera spänningar . En spännvidd är en logisk arbetsenhet i Jaeger. Varje intervall inkluderar åtgärdens namn, starttid och varaktighet. Spänn kan vara kapslade och ordnade.

Jaeger innehåller flera komponenter som arbetar tillsammans för att samla, lagra och visualisera spänn och spår.

Jaeger Client inkluderar språk -specifika implementeringar av OpenTracing API för distribuerad spårning. Dessa kan användas manuellt eller med en mängd olika källkodsramar.

Jaeger Agent är en nätverksdemon som lyssnar på spänningar som skickas via User Datagram Protocol. Agenten är avsedd att placeras på samma värd som den instrumenterade applikationen. Detta implementeras vanligtvis via en sidovagn i behållarmiljöer som Kubernetes.

Jaeger Collector tar emot spänn och placerar dem i en kö för bearbetning.

Samlare kräver en beständig lagringsbackend, så Jaeger har också en pluggbar mekanism för span lagring.

Query är en tjänst som hämtar spår från lagring.

Jaeger Console är ett användargränssnitt som låter dig visualisera dina distribuerade spårningsdata.

Varför Jaeger?

Som mikrotjänster inom marken snabbt inser är de flesta operativa problem som uppstår när de flyttar till en distribuerad arkitektur slutligen jordade i två områden: nätverk och observerbarhet. Det är helt enkelt en storleksordning större problem att nätverka och felsöka en uppsättning av sammanflätade distribuerade tjänster kontra en enda monolitisk applikation.

Jaeger i aktion

Vi kommer att integrera jaeger i en vårstartprogram.

Först, låt oss snabbt ställa in våra vårstartprogram.

Tanken här är att generera namn genom att sammanföra kända vetenskapsnamn med djurnamn.

Så, vi kommer att bygga 3 mikrotjänster med hjälp av fjäderkänga, dvs. djurnamnservice , namngenerator-tjänst, och vetenskapsnamn-tjänst.

Klientbegäran om ett forskare och djur sammanhängande namn från namn-generator-tjänst som internt kallar animal-name-service och scienceist-name-service.

Detsamma visas i nedanstående diagram.

Microservice Exempel

Låt oss snabbt bygga våra tre mikrotjänster med vårinitialisering r.

Vi kommer att lägga till spring-boot-starter-web beroende medan vi genererar springboot-applikationer.

Nu har vi tre spring-boot-applikationer redo. Låt oss lägga till dessa tre mikrotjänster i en mapp med namnet opentracing-microservices-exempel.

Och importera den här mappen i din favoritredigerare. Jag använder IntelliJ .

Som vi måste kalla animal-name-service och scientist- name-service från name-generator-service.

vi väljer att feignera klienten för detta. Så låt oss lägga till spring-cloud-starter-openfeign: 2.2.3.RELEASE beroende i name-generator-service.

Här är koden för alla tre mikrotjänsterna.

AnimalNameService :

package com.example.ans;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.core.io.ClassPathResource;import org.springframework.http.HttpHeaders;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.List;import java.util.Random;import java.util.stream.Collectors;@SpringBootApplication
public class AnimalNameService {public static void main(String[] args) {SpringApplication.run(AnimalNameService.class, args);}}@RestController
@RequestMapping("/api/v1/animals")
class AnimalNameResource {private final List animalNames;private Random random;public AnimalNameResource() throws IOException {InputStream inputStream = new ClassPathResource("/animals.txt").getInputStream();try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {animalNames = reader.lines().collect(Collectors.toList());}random = new Random();}@GetMapping(path = "/random")
public String name(@RequestHeader HttpHeaders headers) {String name = animalNames.get(random.nextInt(animalNames.size()));return name;}}

application.properties:

server.port=9000

NameGeneratorService:

Här använder jag com.shekhargulati: strman: 0.4 .0 bibliotek för att konvertera djur- och vetenskapsnamn till kebabfall.

package com.example.ngs;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.openfeign.EnableFeignClients;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import static strman.Strman.toKebabCase;@SpringBootApplication
@EnableFeignClients
public class NameGeneratorService {public static void main(String[] args) {SpringApplication.run(NameGeneratorService.class, args);}}@FeignClient(name = "scientist-service-client", url = "${scientist.service.prefix.url}")
interface ScientistServiceClient {@GetMapping("/api/v1/scientists/random")
String randomScientistName();}@FeignClient(name = "animal-service-client", url = "${animal.service.prefix.url}")
interface AnimalServiceClient {@GetMapping("/api/v1/animals/random")
String randomAnimalName();}@RestController
@RequestMapping("/api/v1/names")
class NameResource {@Autowired
private AnimalServiceClient animalServiceClient;@Autowired
private ScientistServiceClient scientistServiceClient;@GetMapping(path = "/random")
public String name() throws Exception {String animal = animalServiceClient.randomAnimalName();String scientist = scientistServiceClient.randomScientistName();String name = toKebabCase(scientist) + "-" + toKebabCase(animal);return name;}}

application.properties:

server.port=8080scientist.service.prefix.url=http://localhost:8090animal.service.prefix.url=http://localhost:9000

ScientistNameService:

package com.example.sns;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.core.io.ClassPathResource;import org.springframework.http.HttpHeaders;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.List;import java.util.Random;import java.util.stream.Collectors;@SpringBootApplication
public class ScientistNameService {public static void main(String[] args) {SpringApplication.run(ScientistNameService.class, args);}}@RestController
@RequestMapping("/api/v1/scientists")
class ScientistNameResource {private final List scientistsNames;private Random random;public ScientistNameResource() throws IOException {InputStream inputStream = new ClassPathResource("/scientists.txt").getInputStream();try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {scientistsNames = reader.lines().collect(Collectors.toList());}random = new Random();}@GetMapping(path = "/random")
public String name(@RequestHeader HttpHeaders headers) {String name = scientistsNames.get(random.nextInt(scientistsNames.size()));return name;}}

application.properties :

server.port=8090

Nu kör vi alla 3 applikationerna och går till http: // localhost: 8080 / api / v1 / names / random i en webbläsare.

Vi får ett slumpmässigt namnexempel: john-cockcroft-snapping-turtle

Så nu vår applikation installationen är klar.

Låt oss nu integrera jaeger i dessa applikationer så att vi kan tra ce varje begäran.

Vi behöver bara lägga till nedanstående beroende till alla 3 pom.xml.


io.opentracing.contrib
opentracing-spring-jaeger-cloud-starter3.1.2

Och vi måste lägga till egenskaperna nedan i filen application.properties för alla tre applikationer.

spring.application.name= // example : name-generator-service (this will be displayed in jaeger for respective service)opentracing.jaeger.udp-sender.host=localhost //udp host for sender. By default Jaeger libraries use a UDP sender to report finished spans to the jaeger-agent daemonopentracing.jaeger.udp-sender.port=6831 // udp portopentracing.jaeger.log-spans=true // logs the spans in console

Kör Jaeger i dockaren via kommandot nedan:

docker run -p 9090:16686 — name jaeger -d jaegertracing/all-in-one:1.17

Starta om programmet. Och gå till localhost: 9090 i en webbläsare. Vi får en jaeger-hemsida.

Gå också till http: // localhost: 8080 / api / v1 / names / random i en webbläsare. På samma sätt får du ett slumpmässigt namn.

Men nu kan vi spåra begäran. Kontrollera i jaeger-instrumentpanelen, välj tjänsten namn-generator-service.

och klicka sedan på hitta spår. vi får spår som visas i bilden nedan för namn-generator-tjänsten .

Jaeger Name Generator Service

Vi ser tydligt att det finns 5 spänn när vi går igenom detta.

namn-generator-tjänst (1 span)

name-generator-service-> animal-name-service (2 span)

name-generator-service-> scientist- namntjänst (2 spänn)

Detta visas i bilden nedan.

Jaeger Name Generator Service Trace

Här konfigureras allt automatiskt av opentracing-spring-jaeger-cloud-starter bibliotek som har en klass med namnet TracingAspect som i princip gör magi.

@Aspect
class TracingAspect {
TracingAspect() {
}

@Around("execution (* feign.Client.*(..)) && !within(is(FinalType))")
public Object feignClientWasCalled(ProceedingJoinPoint pjp) throws Throwable {
Object bean = pjp.getTarget();
if (!(bean instanceof TracingClient)) {
Object[] args = pjp.getArgs();
return (new TracingClientBuilder((Client)bean, FeignTracingAutoConfiguration.this.tracer)).withFeignSpanDecorators(FeignTracingAutoConfiguration.this.spanDecorators).build().execute((Request)args[0], (Options)args[1]);
} else {
return pjp.proceed();
}
}
}

Jag har lagt till Dockerfile, docker-compose och docker- setup.sh för att göra det enklare att köra denna applikation. kassakod och kör docker-setup.sh direkt.

Du hittar koden på min Github-arkiv länk .

Detta är inspirerat av Shekhar Gulatis blogg .

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *