Spring Boot 3.4'te Özel Başlık İzlemelerini İşleme
İki istemciyle sorunsuz şekilde çalışan bir Spring Boot 3.4 web hizmetiniz olduğunu hayal edin. İlk istemci Spring Boot 3+ kullanıyor ve iz yayılımını kolaylaştırıyor. Ekstra bir çaba harcamadan güzel bir uçtan uca iz sürekliliği elde edersiniz 🪄. Günlükler sanki sihirli bir değnekmiş gibi temiz ve bağlantılı görünüyor.
Ancak istemci iki devreye girdiğinde işler değişir. Standart izleme başlıkları yerine 'ot-custom-traceid' ve 'ot-custom-spanid' gibi özel başlıklar gönderirler. Bu özel başlıklar geçerli izleme bilgileri içerse de Spring Boot bu izleri yaymakta başarısız olur. Sonuç? İstemci izlerini sunucu tarafı günlüklerine bağlama yeteneğinizi kaybedersiniz.
Bu gözlemlenebilirlik açığı yaratır. Birinci müşteri için, hizmetler genelinde bir isteğin tam yolunu görürsünüz. İkinci istemci için yalnızca kritik istemci izlemesinin eksik olduğu sunucu tarafı günlüklerini görürsünüz. Bir yapbozun yarısını görmek gibi; bir şeyin eksik olduğunu biliyorsunuz ama parçaları bir araya getiremiyorsunuz. 😓
Bu makalede, Spring Boot 3.4 ekosistemine sadık kalarak Spring Cloud Sleuth'a güvenmeden bu sorunu nasıl çözebileceğimizi keşfedeceğiz. Sonunda, sisteminizde kusursuz gözlemlenebilirlik sağlayacak şekilde özel başlıklardan izleri nasıl yayacağınızı ve devam ettireceğinizi öğreneceksiniz.
Emretmek | Kullanım örneği |
---|---|
MDC.put | Bu komut, Eşlenen Tanılama Bağlamına (MDC) anahtar/değer çiftleri ekleyerek özel izleme kimliklerinin günlüklere eklenmesine olanak tanır. Örneğin, MDC.put("traceId", "12345"). |
MDC.clear | İstekler arasında iz kirliliğini önlemek için bir istek işlendikten sonra MDC'deki tüm girişleri temizler. Örneğin, MDC.clear(). |
OncePerRequestFilter | Filtre mantığının HTTP isteği başına yalnızca bir kez yürütülmesini sağlayan bir Spring Boot filtresi, başlıkları izlemek için idealdir. Örnek: genel sınıf CustomTraceFilter, OncePerRequestFilter'ı genişletir. |
filterChain.doFilter | İsteğin diğer filtreler aracılığıyla devam etmesini sağlayarak zincirdeki bir sonraki filtreye ilerleyin. Örneğin, filterChain.doFilter(istek, yanıt). |
RestTemplate.getInterceptors() | Bir RestTemplate örneği için önleyicilerin listesini alarak özel önleyicilerin eklenmesine olanak tanır. Örnek: restTemplate.getInterceptors().add(new CustomInterceptor()). |
ClientHttpRequestInterceptor | Giden HTTP isteklerini engellemek ve özel başlıklar eklemek için bir arayüz. Örneğin, izleme kimliklerini eklemek için ClientHttpRequestInterceptor'ın uygulanması. |
HttpServletRequest.getHeader | Gelen istekten belirli bir HTTP üstbilgisinin değerini çıkarır. Örnek: request.getHeader("ot-custom-traceid"). |
FilterRegistrationBean | Spring Boot uygulamasında özel filtreleri kaydeder. Örneğin: kayıtBean.setFilter(new CustomTraceFilter()). |
MockMvc.perform | Spring Boot uygulamaları için birim testlerinde HTTP isteklerini simüle eder. Örnek: makeMvc.perform(get("/test-endpoint").header("ot-custom-traceid", "12345")). |
ClientHttpRequestExecution.execute | Yakalanan HTTP isteğini, sağlanan istek gövdesi ve üstbilgileriyle yürütür. Örnek: yürütme.execute(istek, gövde). |
Spring Boot'ta Özel Başlık İzleme Yayılımı
Bu sorunu çözmenin temel bileşenlerinden biri CustomTraceFilter'dır. Bu filtre, izleme başlığı mantığının her HTTP isteği için yalnızca bir kez çalışmasını sağlar. Spring Boot'taki filtreler, istekleri veya yanıtları genel olarak değiştirirken inanılmaz derecede faydalıdır. Örneğin, müşteri aşağıdaki gibi izleme bilgileri gönderirse veya özel başlıklarda bu filtre isteği durdurur, bu başlıkları çıkarır ve bunları Eşlenen Tanılama Bağlamı'na (MDC) yayar. İzleme kimliklerini MDC'ye ekleyerek bu tanımlayıcıların istek işleme sırasında oluşturulan günlüklerde görünür olmasını sağlıyoruz.
MDC, SLF4J ve Logback gibi günlük kaydı çerçevelerinin kritik bir parçasıdır. Geçerli iş parçacığı için özel izleme kimlikleri gibi bağlamsal bilgileri saklamamıza olanak tanır. Gibi komutları kullanma Ve , kayıt sisteminin izleme ayrıntılarını içermesini ve eşzamanlı istekler arasındaki kirlenmeyi önlemesini sağlıyoruz. Örneğin, İstemci İki, "ot-custom-traceid"yi "8f7ebd8a73f9a8f50e6a00a87a20952a" olarak gönderirse, bu kimlik MDC'de depolanır ve tüm aşağı akış günlüklerine dahil edilerek tutarlı bir izleme yolu oluşturulur.
Öte yandan, giden HTTP istekleri için RestTemplate önleyici önemli bir rol oynar. Uygulayarak , giden isteklere aynı izleme başlıklarını ("ot-custom-traceid" ve "ot-custom-spanid") ekleyebiliriz. Bu, uygulama diğer mikro hizmetleri çağırdığında izleme sürekliliğinin korunmasını sağlar. Örneğin, sunucu '8f7ebd8a73f9a8f50e6a00a87a20952a' izleme kimliğine sahip bir isteği işlediğinde, bu kimliği giden başlıklara ekler, böylece aşağı akış hizmetleri izi sorunsuz bir şekilde tanıyabilir ve yayabilir.
Son olarak MockMvc ile yazılan birim testleri, HTTP isteklerini simüle ederek ve başlık yayılımını doğrulayarak tüm kurulumu doğrular. Gerçek dünya uygulamalarında, izleme başlıklarının doğru şekilde işlenmesini sağlamak için test yapmak çok önemlidir. Örneğin, özel başlıklarla bir GET isteği göndererek ve yanıtı veya günlükleri inceleyerek filtrenin ve önleyicinin beklendiği gibi çalıştığını doğrulayabiliriz. Bu kapsamlı yaklaşım, Spring Cloud Sleuth gibi eski bağımlılıklara güvenmeden bu sorunu çözüyor. Sonuç olarak, filtrelerin, önleyicilerin ve MDC'nin birleşimi, istemciler özel başlıklar kullandığında bile izleme sürekliliği sağlayarak sistemi sağlam ve tamamen gözlemlenebilir hale getirir. 🌟
Spring Boot 3.4'te Özel İzleme Başlıklarını Yayma
Arka Uç İşleme için Java'yı Spring Boot 3.4 ve Mikrometre ile Kullanma
// 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;
}
}
Özel İzleme Başlığı Yayılımı için Birim Testi
İzleme Başlığı Yayılımını Doğrulamak için JUnit ve MockMvc ile Test Etme
// 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());
}
}
RestTemplate Kullanarak HTTP İsteklerinde Özel Üstbilgileri Yayma
Giden İsteklere Özel Başlıklar Eklemek için RestTemplate Interceptors'ı Kullanma
// 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;
}
}
Spring Boot 3.4'te OpenTelemetry ile Özel Başlık İzlerini İşleme
Spring Boot 3.4 ile çalışırken, özel üstbilgilerden izleri yaymak için başka bir güçlü yaklaşım da entegre etmektir. . Açık kaynaklı bir gözlemlenebilirlik çerçevesi olan OpenTelemetry, izleri sorunsuz bir şekilde ölçmeye, toplamaya ve dışa aktarmaya yardımcı olur. Aşağıdaki gibi özel başlıklar da dahil olmak üzere izleme içeriğini ayıklamak ve enjekte etmek için mekanizmalar sağlar: Ve , uygulamanıza ekleyin. OpenTelemetry'nin TextMapPropagator özelliğini kullanarak standart dışı istemciler ile gözlemlenebilirlik sisteminiz arasındaki boşluğu kapatabilirsiniz.
Spring Boot 3.4'te OpenTelemetry'yi kullanmak için, özel başlıklardan izleme bilgilerini çıkarmak ve bunu geçerli izleme bağlamına eklemek üzere bir özel yayıcı uygulanabilir. Örneğin, sunucunuz İstemci İki'den gelen bir istek aldığında, OpenTelemetry özel başlıkları ayrıştırabilir ve orijinal izleme bağlamını yeniden oluşturabilir. Bu, aşağı akış hizmetlerinin aynı izleme kimliklerini görmesini sağlayarak uçtan uca görünürlük sağlar. Spring Cloud Sleuth gibi eski çözümlerin aksine OpenTelemetry hafiftir ve modern gözlemlenebilirlik standartlarıyla uyumludur.
OpenTelemetry'nin yayıcısını Mikrometre ile birleştirerek ölçümlerinizi ve günlük kaydınızı izleme bilgileriyle zenginleştirebilirsiniz. Gözlemlenebilirlik aracınızda hem İstemci Bir'den hem de İstemci İki'den gelen isteklerin izlerini sorunsuz bir şekilde gördüğünüzü hayal edin. OpenTelemetry, Prometheus, Zipkin veya Jaeger ile entegrasyonları otomatik olarak destekleyerek iz görselleştirmesini merkezileştirmenize olanak tanır. Bu yaklaşım, özel başlıklar dahil olduğunda bile hiçbir izleme verisinin kaybolmamasını ve hata ayıklamanın önemli ölçüde kolaylaşmasını sağlar. 🚀
- Spring Boot'ta özel izleme başlıklarını manuel olarak nasıl çıkarabilirim?
- Belirli bir başlığı manuel olarak getirmek ve MDC.put("traceId", value) kullanarak MDC'ye eklemek için request.getHeader("custom-header") komutunu kullanabilirsiniz.
- Özel iz yayılımı için OpenTelemetry kullanmanın faydası nedir?
- OpenTelemetry, mikro hizmetler genelinde özel üstbilgiler de dahil olmak üzere izlerin yayılmasına yönelik modern, satıcıdan bağımsız bir yaklaşım sağlar.
- Özel başlıkları Spring Boot'ta RestTemplate ile yayabilir miyim?
- Evet, ClientHttpRequestInterceptor uygulayarak, giden isteklere traceid ve spanid gibi özel başlıklar ekleyebilirsiniz.
- Başlıkları genel olarak yakalamak için bir filtreyi nasıl kaydederim?
- OncePerRequestFilter'ı genişleten bir filtre oluşturabilir ve bunu tüm uç noktalara ilişkin başlıkları yakalamak için FilterRegistrationBean kullanarak kaydedebilirsiniz.
- Spring Boot'taki izleri görselleştirmek için hangi araçları kullanabilirim?
- Zipkin, Jaeger ve Prometheus gibi araçlar, uçtan uca izleri görselleştirmek için Spring Boot ve OpenTelemetry ile entegre olabilir.
Modern sistemlerde, özel izleme başlıklarının kullanılması güvenilir gözlemlenebilirlik açısından kritik öneme sahiptir. Filtreleri ve önleyicileri kullanarak istemci tarafından sağlanan izleme bilgilerini yakalayabilir ve bunu hizmetlerinize doğru bir şekilde yayabilirsiniz. Bu, parçalanmış günlükleri ve eksik izleri önler. 🔍
Spring Boot 3.4, Micrometer veya OpenTelemetry ile birleştiğinde Spring Cloud Sleuth gibi eski araçlara bağımlı kalmadan sağlam çözümlere olanak tanır. İster İstemci Bir'in standart başlıklarıyla, ister İstemci İki'nin özel başlıklarıyla ilgileniyor olun, bu tekniklerin uygulanması, iz boşluklarını verimli bir şekilde kapatır. 🚀
- Spring Boot Resmi Belgeleri: İzleme Bağlamlarının Yayılması. Spring Boot Belgeleri
- Java Geliştiricileri için OpenTelemetry: Yayılımı İzleme Kılavuzu. OpenTelemetry Java
- Mikrometre Gözlemlenebilirlik Belgeleri: Özel İzleme Başlıklarının Entegre Edilmesi. Mikrometre Gözlemlenebilirliği
- SLF4J Günlük API'si: Eşlenen Tanılama Bağlamı (MDC) Kullanım Durumları. SLF4J Kılavuzu