Gestionarea urmelor de antet personalizate în Spring Boot 3.4
Imaginați-vă că aveți un serviciu web Spring Boot 3.4 care funcționează fără probleme cu doi clienți. Primul client folosește Spring Boot 3+, ceea ce face ca propagarea urmelor să fie o ușoară. Fără niciun efort suplimentar, obțineți o continuitate a urmei de la capăt la capăt 🪄. Jurnalele par curate și conectate, ca prin farmec.
Cu toate acestea, lucrurile iau o întorsătură când intră în joc clientul doi. În loc de anteturile de urmărire standard, acestea trimit anteturi personalizate precum `ot-custom-traceid` și `ot-custom-spanid`. Deși aceste anteturi personalizate conțin informații de urmărire valide, Spring Boot nu reușește să propage aceste urme. Rezultatul? Pierzi capacitatea de a conecta urmele clientului cu jurnalele de pe server.
Acest lucru creează un decalaj de observabilitate. Pentru clientul unu, vedeți calea completă a unei solicitări între servicii. Pentru clientul doi, vedeți doar jurnalele de pe server, lipsând următorul client critic. Este ca și cum ai vedea o jumătate de puzzle - știi că lipsește ceva, dar nu poți pune piesele împreună. 😓
În acest articol, vom explora cum să rezolvăm această problemă fără a ne baza pe Spring Cloud Sleuth, rămânând fideli ecosistemului Spring Boot 3.4. Până la sfârșit, veți ști cum să propagați și să continuați urmele din anteturile personalizate, asigurând o observabilitate perfectă în sistemul dumneavoastră.
Comanda | Exemplu de utilizare |
---|---|
MDC.put | Această comandă adaugă perechi cheie-valoare la Contextul de diagnosticare mapat (MDC), permițând ca ID-urile de urmărire personalizate să fie incluse în jurnale. De exemplu, MDC.put("traceId", "12345"). |
MDC.clear | Șterge toate intrările din MDC după ce o solicitare este procesată pentru a evita contaminarea urmelor între cereri. De exemplu, MDC.clear(). |
OncePerRequestFilter | Un filtru Spring Boot care asigură că logica filtrului este executată o singură dată pentru fiecare solicitare HTTP, ideal pentru urmărirea antetelor. Exemplu: clasa publică CustomTraceFilter extinde OncePerRequestFilter. |
filterChain.doFilter | Trece la următorul filtru din lanț, asigurându-se că cererea continuă prin alte filtre. De exemplu, filterChain.doFilter(cerere, răspuns). |
RestTemplate.getInterceptors() | Preia lista de interceptori pentru o instanță RestTemplate, permițând adăugarea de interceptori personalizați. Exemplu: restTemplate.getInterceptors().add(new CustomInterceptor()). |
ClientHttpRequestInterceptor | O interfață pentru interceptarea solicitărilor HTTP trimise și adăugarea antetelor personalizate. De exemplu, implementarea ClientHttpRequestInterceptor pentru a insera ID-uri de urmărire. |
HttpServletRequest.getHeader | Extrage valoarea unui anumit antet HTTP din cererea de intrare. Exemplu: request.getHeader("ot-custom-traceid"). |
FilterRegistrationBean | Înregistrează filtre personalizate în aplicația Spring Boot. De exemplu: registrationBean.setFilter(new CustomTraceFilter()). |
MockMvc.perform | Simulează solicitările HTTP în testele unitare pentru aplicațiile Spring Boot. Exemplu: mockMvc.perform(get("/test-endpoint").header("ot-custom-traceid", "12345")). |
ClientHttpRequestExecution.execute | Execută cererea HTTP interceptată cu corpul și anteturile cererii furnizate. Exemplu: execution.execute(cerere, corp). |
Propagare personalizată a urmăririi antetului în Spring Boot
Una dintre componentele cheie în rezolvarea acestei probleme este CustomTraceFilter. Acest filtru extinde OncePerRequestFilter clasa, asigurându-se că logica antetului de urmărire rulează o singură dată pentru fiecare solicitare HTTP. Filtrele din Spring Boot sunt incredibil de utile atunci când modificați solicitările sau răspunsurile la nivel global. De exemplu, dacă clientul trimite informații de urmărire, cum ar fi ot-custom-traceid sau ot-custom-spanid în anteturile personalizate, acest filtru interceptează cererea, extrage aceste antete și le propagă în Contextul de diagnosticare mapat (MDC). Prin adăugarea ID-urilor de urmărire la MDC, ne asigurăm că acești identificatori sunt vizibili în jurnalele generate în timpul procesării cererii.
MDC este o parte critică a cadrelor de înregistrare, cum ar fi SLF4J și Logback. Ne permite să stocăm informații contextuale pentru firul curent, cum ar fi ID-uri de urmărire personalizate. Folosind comenzi precum MDC.put şi MDC.clear, ne asigurăm că sistemul de înregistrare include detaliile de urmărire și evită contaminarea între solicitările concurente. De exemplu, dacă Client Two trimite `ot-custom-traceid` ca `8f7ebd8a73f9a8f50e6a00a87a20952a`, acest ID este stocat în MDC și inclus în toate jurnalele din aval, creând o cale de urmărire consecventă.
Pe de altă parte, pentru cererile HTTP de ieșire, Interceptor RestTemplate joacă un rol esențial. Prin implementare ClientHttpRequestInterceptor, putem atașa aceleași anteturi de urmărire (`ot-custom-traceid` și `ot-custom-spanid`) la cererile trimise. Acest lucru asigură menținerea continuității urmăririi atunci când aplicația apelează alte microservicii. De exemplu, atunci când serverul procesează o solicitare cu ID-ul de urmărire `8f7ebd8a73f9a8f50e6a00a87a20952a`, atașează acest ID la anteturile de ieșire, astfel încât serviciile din aval să poată recunoaște și propaga traseul fără probleme.
În cele din urmă, testele unitare scrise cu MockMvc validează întreaga configurație prin simularea solicitărilor HTTP și prin verificarea propagării antetului. În aplicațiile din lumea reală, testarea este crucială pentru a se asigura că anteturile de urmărire sunt gestionate corect. De exemplu, trimițând o solicitare GET cu anteturi personalizate și inspectând răspunsul sau jurnalele, putem confirma că filtrul și interceptorul funcționează conform așteptărilor. Această abordare cuprinzătoare rezolvă provocarea fără a se baza pe dependențe vechi, cum ar fi Spring Cloud Sleuth. În cele din urmă, combinația de filtre, interceptoare și MDC asigură continuitatea urmăririi chiar și atunci când clienții folosesc anteturi personalizate, făcând sistemul robust și pe deplin observabil. 🌟
Propagarea antetelor de urmărire personalizate în Spring Boot 3.4
Utilizarea Java cu Spring Boot 3.4 și Micrometer pentru procesarea backend
// Solution 1: Extract and Propagate Custom Trace Headers Manually
// Import necessary Spring Boot and Micrometer libraries
import org.slf4j.MDC;
import org.springframework.http.HttpHeaders;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CustomTraceFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException {
String traceId = request.getHeader("ot-custom-traceid");
String spanId = request.getHeader("ot-custom-spanid");
try {
if (traceId != null) {
MDC.put("traceId", traceId); // Add traceId to Mapped Diagnostic Context
}
if (spanId != null) {
MDC.put("spanId", spanId);
}
filterChain.doFilter(request, response); // Continue request processing
} finally {
MDC.clear(); // Ensure MDC is cleared after processing
}
}
}
// Register the filter in your configuration class
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<CustomTraceFilter> traceFilter() {
FilterRegistrationBean<CustomTraceFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CustomTraceFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
Test unitar pentru propagarea antetului de urmărire personalizată
Testarea cu JUnit și MockMvc pentru a valida propagarea antetului de urmărire
// Import necessary libraries
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest
public class CustomTraceFilterTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testCustomTraceHeaders() throws Exception {
mockMvc.perform(get("/test-endpoint")
.header("ot-custom-traceid", "12345")
.header("ot-custom-spanid", "67890"))
.andExpect(status().isOk());
}
}
Propagarea antetelor personalizate în solicitările HTTP utilizând RestTemplate
Utilizarea RestTemplate Interceptors pentru a adăuga anteturi personalizate în cererile de ieșire
// Import necessary libraries
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
public class CustomHeaderInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
HttpHeaders headers = request.getHeaders();
headers.add("ot-custom-traceid", "12345");
headers.add("ot-custom-spanid", "67890");
return execution.execute(request, body);
}
}
// Register the interceptor with RestTemplate
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new CustomHeaderInterceptor());
return restTemplate;
}
}
Gestionarea urmelor de antet personalizate cu OpenTelemetry în Spring Boot 3.4
Când lucrați cu Spring Boot 3.4, o altă abordare puternică pentru a propaga urmele din anteturile personalizate este integrarea OpenTelemetry. OpenTelemetry, un cadru de observabilitate open-source, ajută la instrumentarea, colectarea și exportarea urmelor fără probleme. Oferă mecanisme pentru extragerea și injectarea contextului de urmărire, inclusiv antete personalizate precum ot-custom-traceid şi ot-custom-spanid, în aplicația dvs. Utilizând TextMapPropagator de la OpenTelemetry, puteți reduce decalajul dintre clienții non-standard și sistemul dvs. de observabilitate.
Pentru a utiliza OpenTelemetry în Spring Boot 3.4, un propagator personalizat poate fi implementat pentru a extrage informații de urmărire din anteturile personalizate și pentru a le atașa contextului de urmărire curent. De exemplu, atunci când serverul dvs. primește o solicitare de la Client Two, OpenTelemetry poate analiza anteturi personalizate și reconstrui contextul de urmărire original. Acest lucru asigură că serviciile din aval văd aceleași ID-uri de urmărire, permițând vizibilitate de la capăt la capăt. Spre deosebire de soluțiile mai vechi precum Spring Cloud Sleuth, OpenTelemetry este ușor și se aliniază cu standardele moderne de observabilitate.
Combinând propagatorul OpenTelemetry cu Micrometru, vă puteți îmbogăți valorile și înregistrarea cu informații de urmărire. Imaginați-vă că vedeți fără probleme urme pentru solicitările venite atât de la Clientul Unu, cât și de la Clientul doi în instrumentul dvs. de observabilitate. OpenTelemetry acceptă automat integrările cu Prometheus, Zipkin sau Jaeger, permițându-vă să centralizați vizualizarea urmei. Această abordare asigură că, chiar și atunci când sunt implicate anteturi personalizate, nu se pierde nicio urmă de date, iar depanarea devine semnificativ mai ușoară. 🚀
Întrebări frecvente despre propagarea urmelor personalizate în Spring Boot
- Cum extrag manual anteturile de urmărire personalizate în Spring Boot?
- Puteți folosi request.getHeader(„custom-header”) pentru a prelua manual un anumit antet și pentru a-l adăuga la MDC folosind MDC.put(„traceId”, value).
- Care este beneficiul utilizării OpenTelemetry pentru propagarea urmelor personalizate?
- OpenTelemetry oferă o abordare modernă, neutră din punctul de vedere al furnizorului, pentru propagarea urmelor, inclusiv antete personalizate, între microservicii.
- Pot propaga antete personalizate cu RestTemplate în Spring Boot?
- Da, prin implementarea unui ClientHttpRequestInterceptor, puteți atașa antete personalizate precum traceid și spanid la cererile trimise.
- Cum înregistrez un filtru pentru a captura anteturi la nivel global?
- Puteți crea un filtru care extinde OncePerRequestFilter și îl puteți înregistra folosind FilterRegistrationBean pentru a captura anteturi pentru toate punctele finale.
- Ce instrumente pot folosi pentru a vizualiza urmele din Spring Boot?
- Instrumente precum Zipkin, Jaeger și Prometheus se pot integra cu Spring Boot și OpenTelemetry pentru a vizualiza urmele de la capăt la capăt.
Asigurarea continuității traseului fără întreruperi
În sistemele moderne, gestionarea antetelor de urmărire personalizate este esențială pentru o observabilitate fiabilă. Folosind filtre și interceptori, puteți captura informații de urmărire furnizate de client și le puteți propaga corect în serviciile dvs. Acest lucru evită jurnalele fragmentate și urmele lipsă. 🔍
Spring Boot 3.4, combinat cu Micrometer sau OpenTelemetry, permite soluții robuste fără a se baza pe instrumente mai vechi precum Spring Cloud Sleuth. Indiferent dacă aveți de-a face cu anteturile standard ale Clientului One sau cu anteturile personalizate ale Clientului doi, implementarea acestor tehnici compensează eficient golurile de urmărire. 🚀
Surse și referințe
- Documentație oficială Spring Boot: Propagarea contextelor de urmărire. Documentația Spring Boot
- OpenTelemetry pentru dezvoltatori Java: Ghid pentru propagarea urmăririi. OpenTelemetry Java
- Documentație privind observabilitatea micrometrului: integrarea antetelor de urmărire personalizate. Observabilitatea micrometrului
- SLF4J Logging API: Mapped Diagnostic Context (MDC) cazuri de utilizare. Manual SLF4J