Jaeger Integration With Spring Boot Application (Norsk)

(Himank Batra) (9. sep. , 2020)

Jaeger Integration with spring boot application

La oss først forstå hva som er Jaeger

Jaeger er programvare med åpen kildekode for sporing av transaksjoner mellom distribuerte tjenester.

Den brukes til å overvåke og feilsøke komplekse mikrotjenestemiljøer.

Ridesharing-selskapet Uber utviklet Jaeger som et open source-prosjekt i 2015. Det ble akseptert som en sky Native Computing Foundation (CNCF) Inkubasjonsprosjekt i 2017 og oppgradert til gradert status i 2019.

Hva distribueres sporing?

Distribuert sporing er en måte å se og forstå en hel hendelseskjede i et komplekst samspill mellom mikrotjenester.

Moderne, skyinnfødt programvareutvikling er avhengig av mikrotjenester: uavhengige tjenester som hver gir en annen kjernefunksjon. Når en bruker gjør en forespørsel i en app, svarer mange individuelle tjenester for å gi et resultat.

En enkelt samtale i en app kan påkalle dusinvis av forskjellige tjenester som samhandler med hverandre. Hvordan kan utviklere og ingeniører isolere et problem når noe går galt eller en forespørsel går sakte? Vi trenger en måte å holde oversikt over alle tilkoblingene.

Det er her distribuert sporing kommer inn. Den kjøres ofte som en del av et servicenett, som er en måte å administrere og observere mikrotjenester på.

Jaeger bruker distribuert sporing for å følge stien til en forespørsel gjennom forskjellige mikrotjenester. I stedet for å gjette, kan vi se en visuell fremstilling av samtalestrømmene.

Organisert informasjon om transaksjoner er nyttig for feilsøking og optimalisering. Jaeger inkluderer verktøy for å overvåke distribuerte transaksjoner, optimalisere ytelse og ventetid, og utføre RCA-årsaksanalyse (RCA), en metode for problemløsning.

Jaeger-terminologi og komponenter

Jaeger presenterer henvendelser om utførelse som spor . Et spor viser data- / kjøringsbanen gjennom et system.

Et spor består av ett eller flere spenn . Et spenn er en logisk arbeidsenhet i Jaeger. Hvert spenn inkluderer operasjonsnavn, starttid og varighet. Spann kan være nestet og bestilt.

Jaeger inkluderer flere komponenter som fungerer sammen for å samle, lagre og visualisere spenn og spor.

Jaeger Client inkluderer språk -spesifikke implementeringer av OpenTracing API for distribuert sporing. Disse kan brukes manuelt eller med en rekke rammeverker med åpen kildekode.

Jaeger Agent er en nettverksdemon som lytter etter spenn som sendes over User Datagram Protocol. Agenten er ment å bli plassert på samme vert som den instrumenterte applikasjonen. Dette implementeres vanligvis gjennom en sidevogn i containermiljøer som Kubernetes.

Jaeger Collector mottar spenner og plasserer dem i en kø for behandling.

Samlere krever en vedvarende lagringsbackend, så Jaeger har også en pluggbar mekanisme for span lagring.

Query er en tjeneste som henter spor fra lagring.

Jaeger Console er et brukergrensesnitt som lar deg visualisere distribuerte sporingsdata.

Hvorfor Jaeger?

Som mikrotjenesteutøvere på stedet raskt innser, er de fleste operasjonelle problemer som oppstår når de flytter til en distribuert arkitektur, til slutt jordet i to områder: nettverk og observerbarhet. Det er rett og slett et større størrelsesordens problem å nettverke og feilsøke et sett av sammenflettede distribuerte tjenester mot en enkelt monolitisk applikasjon.

Jaeger in Action

Vi vil integrere jaeger på en vårstartprogrammer.

Først, la oss raskt sette opp våre vårstartprogrammer.

Ideen her er å generere navn ved å sammenkjenne kjente vitenskapsmannenavn med dyrenavn.

Så, vi vil bygge 3 mikrotjenester ved hjelp av vårstøvler, dvs. > name-generator-service, and scientist-name-service.

Client Request for a scientist and animal concatenated name from name-generator-service som internt kaller animal-name-service og scienceist-name-service.

Det samme vises i diagrammet nedenfor.

Eksempel på mikroservice

La oss raskt bygge våre tre mikrotjenester ved hjelp av vårinitialisering r.

Vi vil legge til spring-boot-starter-web avhengighet mens vi genererer vårstartprogrammer.

Nå har vi 3 vårstartprogrammer klare. La oss legge til disse 3 mikrotjenestene i en mappe som heter sentrifugering-mikrotjenester-eksempel.

Og importere denne mappen i favorittredigereren din. Jeg bruker IntelliJ .

Som vi må kalle animal-name-service og scientist- name-service fra name-generator-service.

vi velger å feignere klienten for dette. Så la oss legge til spring-cloud-starter-openfeign: 2.2.3.RELEASE avhengighet i name-generator-service.

Her er koden for alle tre mikrotjenester.

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:

Her bruker jeg com.shekhargulati: strman: 0.4 .0 bibliotek for å konvertere navn på dyr og forskere til kebab-sak.

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

Nå kjører vi alle de 3 applikasjonene og går til http: // localhost: 8080 / api / v1 / names / tilfeldig i en nettleser.

Vi får noe tilfeldig navneksempel: john-cockcroft-snapping-turtle

Så nå er applikasjonen vår oppsettet er gjort.

La oss nå integrere jaeger i disse applikasjonene slik at vi kan tra ce hver forespørsel.

Vi trenger bare å legge til avhengigheten nedenfor til alle 3 pom.xml.


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

Og vi trenger å legge til under egenskapene i filen application.properties for alle de 3 applikasjonene.

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

Kjør Jaeger i docker via kommandoen nedenfor:

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

Start programmet på nytt. Og gå til localhost: 9090 i en nettleser. Vi får en jaeger-hjemmeside.

Gå også til http: // localhost: 8080 / api / v1 / names / random i en nettleser. På samme måte vil du få et tilfeldig navn.

Men nå kan vi spore forespørselen. Sjekk i jaeger-dashbordet, velg service name-generator-service.

og klikk deretter på finn spor. vi får spor som vist på bildet nedenfor for navnegenerator-tjenesten .

Jaeger Name Generator Service

Vi ser tydelig at det er 5 spenn når vi går nærmere ned på dette.

name-generator-service (1 span)

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

name-generator-service-> scientist- name-service (2 spenn)

Dette vises i bildet nedenfor.

Jaeger Name Generator Service Trace

Her konfigureres alt automatisk av opentracing-spring-jaeger-cloud-starter bibliotek som har en klasse som heter TracingAspect, som i utgangspunktet gjø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();
}
}
}

Jeg har lagt til Dockerfile, docker-compose og docker- setup.sh for å gjøre det enklere å kjøre dette programmet. kassekode og kjør docker-setup.sh direkte.

Du finner koden på Github-depotet mitt link .

Dette er inspirert av Shekhar Gulatis blogg .

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *