Gestió de traces de capçaleres personalitzades a Spring Boot 3.4
Imagineu que teniu un servei web Spring Boot 3.4 que funciona perfectament amb dos clients. El primer client utilitza Spring Boot 3+, fent que la propagació del rastre sigui molt fàcil. Sense cap esforç addicional, obtindreu una bonica continuïtat de traça d'extrem a extrem 🪄. Els registres semblen nets i connectats, com per art de màgia.
Tanmateix, les coses canvien quan entra en joc el client dos. En lloc de capçaleres de traça estàndard, envien capçaleres personalitzades com `ot-custom-traceid` i `ot-custom-spanid`. Tot i que aquestes capçaleres personalitzades contenen informació de traça vàlida, Spring Boot no pot propagar aquestes traces. El resultat? Perds la capacitat de connectar les traces del client amb els registres del servidor.
Això crea una bretxa d'observabilitat. Per al client 1, veureu la ruta completa d'una sol·licitud entre els serveis. Per al client dos, només veureu els registres del servidor, falta el rastre crític del client. És com veure mig trencaclosques: saps que falta alguna cosa però no pots unir les peces. 😓
En aquest article, explorarem com resoldre aquest problema sense dependre de Spring Cloud Sleuth, mantenint-nos fidels a l'ecosistema Spring Boot 3.4. Al final, sabreu com propagar i continuar les traces de les capçaleres personalitzades, garantint una observabilitat perfecta al vostre sistema.
Comandament | Exemple d'ús |
---|---|
MDC.put | Aquesta ordre afegeix parells clau-valor al Context de diagnòstic mapat (MDC), permetent que els ID de traça personalitzats s'incloguin als registres. Per exemple, MDC.put("traceId", "12345"). |
MDC.clear | Esborra totes les entrades de l'MDC després de processar una sol·licitud per evitar la contaminació de rastres entre sol·licituds. Per exemple, MDC.clear(). |
OncePerRequestFilter | Un filtre Spring Boot que garanteix que la lògica del filtre només s'executa una vegada per sol·licitud HTTP, ideal per rastrejar capçaleres. Exemple: la classe pública CustomTraceFilter amplia OncePerRequestFilter. |
filterChain.doFilter | Passa al següent filtre de la cadena, assegurant que la sol·licitud continua a través d'altres filtres. Per exemple, filterChain.doFilter(sol·licitud, resposta). |
RestTemplate.getInterceptors() | Recupera la llista d'interceptors per a una instància de RestTemplate, la qual cosa permet afegir interceptors personalitzats. Exemple: restTemplate.getInterceptors().add(new CustomInterceptor()). |
ClientHttpRequestInterceptor | Una interfície per interceptar sol·licituds HTTP sortints i afegir capçaleres personalitzades. Per exemple, implementar ClientHttpRequestInterceptor per inserir identificadors de traça. |
HttpServletRequest.getHeader | Extreu el valor d'una capçalera HTTP específica de la sol·licitud entrant. Exemple: request.getHeader("ot-custom-traceid"). |
FilterRegistrationBean | Registra filtres personalitzats a l'aplicació Spring Boot. Per exemple: registrationBean.setFilter(new CustomTraceFilter()). |
MockMvc.perform | Simula sol·licituds HTTP en proves unitàries per a aplicacions Spring Boot. Exemple: mockMvc.perform(get("/test-endpoint").header("ot-custom-traceid", "12345")). |
ClientHttpRequestExecution.execute | Executa la sol·licitud HTTP interceptada amb el cos i les capçaleres de la sol·licitud proporcionades. Exemple: execution.execute(request, body). |
Propagació de traça de capçalera personalitzada a Spring Boot
Un dels components clau per resoldre aquest problema és el CustomTraceFilter. Aquest filtre amplia el OncePerRequestFilter classe, assegurant que la lògica de la capçalera de traça només s'executa una vegada per a cada sol·licitud HTTP. Els filtres de Spring Boot són increïblement útils quan es modifiquen sol·licituds o respostes a nivell global. Per exemple, si el client envia informació de seguiment com ot-custom-traceid o ot-custom-spanid a les capçaleres personalitzades, aquest filtre intercepta la sol·licitud, extreu aquestes capçaleres i les propaga al Mapped Diagnostic Context (MDC). En afegir els identificadors de traça a l'MDC, ens assegurem que aquests identificadors siguin visibles als registres generats durant el processament de la sol·licitud.
El MDC és una part crítica dels marcs de registre com SLF4J i Logback. Ens permet emmagatzemar informació contextual per al fil actual, com ara identificadors de traça personalitzats. Utilitzant ordres com MDC.posar i MDC.clar, ens assegurem que el sistema de registre inclou els detalls de la traça i evita la contaminació entre sol·licituds concurrents. Per exemple, si el client dos envia `ot-custom-traceid` com a `8f7ebd8a73f9a8f50e6a00a87a20952a`, aquest ID s'emmagatzema a l'MDC i s'inclou a tots els registres posteriors, creant un camí de traça coherent.
D'altra banda, per a les sol·licituds HTTP sortints, l'interceptor RestTemplate té un paper essencial. Mitjançant la implementació ClientHttpRequestInterceptor, podem adjuntar les mateixes capçaleres de traça (`ot-custom-traceid` i `ot-custom-spanid`) a les sol·licituds sortints. Això garanteix que la continuïtat de la traça es mantingui quan l'aplicació crida a altres microserveis. Per exemple, quan el servidor processa una sol·licitud amb l'identificador de traça `8f7ebd8a73f9a8f50e6a00a87a20952a`, adjunta aquest identificador a les capçaleres sortints, de manera que els serveis aigües avall poden reconèixer i propagar la traça sense problemes.
Finalment, les proves unitàries escrites amb MockMvc validen tota la configuració simulant sol·licituds HTTP i verificant la propagació de la capçalera. A les aplicacions del món real, les proves són crucials per garantir que les capçaleres de traça es gestionen correctament. Per exemple, enviant una sol·licitud GET amb capçaleres personalitzades i inspeccionant la resposta o els registres, podem confirmar que el filtre i l'interceptor funcionen com s'esperava. Aquest enfocament integral resol el repte sense dependre de dependències heretades com Spring Cloud Sleuth. En definitiva, la combinació de filtres, interceptors i MDC garanteix la continuïtat de la traça fins i tot quan els clients utilitzen capçaleres personalitzades, fent que el sistema sigui robust i totalment observable. 🌟
Propagació de capçaleres de traça personalitzades a Spring Boot 3.4
Ús de Java amb Spring Boot 3.4 i Micrometer per al processament de fons
// 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;
}
}
Prova d'unitat per a la propagació de capçalera de traça personalitzada
Prova amb JUnit i MockMvc per validar la propagació de la capçalera de traça
// 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());
}
}
Propagació de capçaleres personalitzades a les sol·licituds HTTP mitjançant RestTemplate
Ús d'Interceptors de RestTemplate per afegir capçaleres personalitzades a les sol·licituds sortints
// 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;
}
}
Gestió de traces de capçaleres personalitzades amb OpenTelemetry a Spring Boot 3.4
Quan es treballa amb Spring Boot 3.4, un altre enfocament potent per propagar rastres de capçaleres personalitzades és integrar OpenTelemetry. OpenTelemetry, un marc d'observabilitat de codi obert, ajuda a instrumentar, recopilar i exportar traces sense problemes. Proporciona mecanismes per extreure i injectar context de traça, incloses capçaleres personalitzades com ot-custom-traceid i ot-custom-spanid, a la vostra aplicació. Aprofitant el TextMapPropagator d'OpenTelemetry, podeu salvar la bretxa entre els clients no estàndard i el vostre sistema d'observabilitat.
Per utilitzar OpenTelemetry a Spring Boot 3.4, es pot implementar un propagador personalitzat per extreure informació de traça de les capçaleres personalitzades i adjuntar-la al context de traça actual. Per exemple, quan el vostre servidor rep una sol·licitud entrant del Client Two, OpenTelemetry pot analitzar les capçaleres personalitzades i reconstruir el context de traça original. Això garanteix que els serveis posteriors vegin els mateixos identificadors de traça, cosa que permet una visibilitat d'extrem a extrem. A diferència de solucions anteriors com Spring Cloud Sleuth, OpenTelemetry és lleuger i s'alinea amb els estàndards d'observabilitat moderns.
En combinar el propagador d'OpenTelemetry amb Micrometer, podeu enriquir les vostres mètriques i el registre amb informació de traça. Imagineu veure rastres de sol·licituds procedents tant del Client One com del Client Two sense problemes a la vostra eina d'observabilitat. OpenTelemetry admet automàticament integracions amb Prometheus, Zipkin o Jaeger, cosa que us permet centralitzar la visualització de traça. Aquest enfocament garanteix que, fins i tot quan hi hagi capçaleres personalitzades, no es perdin dades de traça i la depuració sigui molt més fàcil. 🚀
Preguntes freqüents sobre la propagació de traces personalitzades a Spring Boot
- Com extreu manualment les capçaleres de traça personalitzades a Spring Boot?
- Podeu utilitzar request.getHeader("custom-header") per obtenir manualment una capçalera específica i afegir-la a l'MDC mitjançant MDC.put("traceId", value).
- Quin és l'avantatge d'utilitzar OpenTelemetry per a la propagació de traça personalitzada?
- OpenTelemetry proporciona un enfocament modern i neutral per a proveïdors per propagar traces, incloses les capçaleres personalitzades, a través dels microserveis.
- Puc propagar capçaleres personalitzades amb RestTemplate a Spring Boot?
- Sí, mitjançant la implementació d'un ClientHttpRequestInterceptor, podeu adjuntar capçaleres personalitzades com traceid i spanid a les sol·licituds sortints.
- Com puc registrar un filtre per capturar capçaleres globalment?
- Podeu crear un filtre que ampliï OncePerRequestFilter i registrar-lo mitjançant FilterRegistrationBean per capturar les capçaleres de tots els punts finals.
- Quines eines puc utilitzar per visualitzar traces de Spring Boot?
- Eines com Zipkin, Jaeger i Prometheus es poden integrar amb Spring Boot i OpenTelemetry per visualitzar traces d'extrem a extrem.
Assegurant la continuïtat de la traça perfecta
En els sistemes moderns, la gestió de capçaleres de traça personalitzades és fonamental per a una observabilitat fiable. Mitjançant l'ús de filtres i interceptors, podeu capturar la informació de seguiment proporcionada pel client i propagar-la correctament als vostres serveis. Això evita registres fragmentats i rastres que falten. 🔍
Spring Boot 3.4, combinat amb Micrometer o OpenTelemetry, permet solucions robustes sense dependre d'eines més antigues com Spring Cloud Sleuth. Tant si esteu tractant amb les capçaleres estàndard del Client One com amb les capçaleres personalitzades del Client Dos, la implementació d'aquestes tècniques supera els buits de traça de manera eficient. 🚀
Fonts i referències
- Documentació oficial de Spring Boot: Propagació de contextos de traça. Documentació Spring Boot
- OpenTelemetry per a desenvolupadors de Java: Guia per a la propagació de rastres. OpenTelemetry Java
- Documentació d'observabilitat del micròmetre: integració de capçaleres de traça personalitzades. Observabilitat del micròmetre
- API de registre SLF4J: casos d'ús del context de diagnòstic mapat (MDC). Manual SLF4J