Руковање прилагођеним траговима заглавља у Спринг Боот-у 3.4
Замислите да имате веб услугу Спринг Боот 3.4 која неприметно ради са два клијента. Први клијент користи Спринг Боот 3+, чинећи ширење трагова лаким. Без додатног напора, добијате прелеп континуитет праћења од краја до краја 🪄. Дневници се појављују чисти и повезани, као магијом.
Међутим, ствари се окрећу када у игру уђе клијент два. Уместо стандардних заглавља праћења, они шаљу прилагођена заглавља попут `от-цустом-трацеид` и `от-цустом-спанид`. Иако ова прилагођена заглавља садрже важеће информације о праћењу, Спринг Боот не успева да пропагира ове трагове. Резултат? Губите могућност повезивања трагова клијената са евиденцијама на страни сервера.
Ово ствара јаз у видљивости. За клијента један, видите пуну путању захтева у свим услугама. За клијента два, видите само евиденције на страни сервера, недостајуће критично праћење клијента. То је као да видите пола слагалице - знате да нешто недостаје, али не можете да саставите делове. 😓
У овом чланку ћемо истражити како да решимо овај проблем без ослањања на Спринг Цлоуд Слеутх, остајући верни екосистему Спринг Боот 3.4. На крају ћете знати како да пропагирате и наставите трагове из прилагођених заглавља, обезбеђујући беспрекорну видљивост у вашем систему.
Цомманд | Пример употребе |
---|---|
MDC.put | Ова команда додаје парове кључ-вредност у Мапирани дијагностички контекст (МДЦ), омогућавајући да се прилагођени ИД-ови праћења укључе у евиденције. На пример, МДЦ.пут("трацеИд", "12345"). |
MDC.clear | Брише све уносе из МДЦ-а након обраде захтева да би се избегла контаминација трагова између захтева. На пример, МДЦ.цлеар(). |
OncePerRequestFilter | Спринг Боот филтер који обезбеђује да се логика филтера извршава само једном по ХТТП захтеву, идеалан за праћење заглавља. Пример: јавна класа ЦустомТрацеФилтер проширује ОнцеПерРекуестФилтер. |
filterChain.doFilter | Прелази на следећи филтер у ланцу, осигуравајући да се захтев настави кроз друге филтере. На пример, филтерЦхаин.доФилтер(захтев, одговор). |
RestTemplate.getInterceptors() | Преузима листу пресретача за инстанцу РестТемплате, омогућавајући додавање прилагођених пресретача. Пример: рестТемплате.гетИнтерцепторс().адд(нев ЦустомИнтерцептор()). |
ClientHttpRequestInterceptor | Интерфејс за пресретање одлазних ХТТП захтева и додавање прилагођених заглавља. На пример, имплементација ЦлиентХттпРекуестИнтерцептор за уметање ИД-ова праћења. |
HttpServletRequest.getHeader | Извлачи вредност одређеног ХТТП заглавља из долазног захтева. Пример: рекуест.гетХеадер("от-цустом-трацеид"). |
FilterRegistrationBean | Региструје прилагођене филтере у апликацији Спринг Боот. На пример: регистратионБеан.сетФилтер(нев ЦустомТрацеФилтер()). |
MockMvc.perform | Симулира ХТТП захтеве у јединичним тестовима за Спринг Боот апликације. Пример: моцкМвц.перформ(гет("/тест-ендпоинт").хеадер("от-цустом-трацеид", "12345")). |
ClientHttpRequestExecution.execute | Извршава пресретнути ХТТП захтев са датим телом и заглављима захтева. Пример: екецутион.екецуте(захтев, тело). |
Прилагођено ширење трага заглавља у Спринг Боот-у
Једна од кључних компоненти у решавању овог проблема је ЦустомТрацеФилтер. Овај филтер проширује ОнцеПерРекуестФилтер класе, обезбеђујући да се логика заглавља праћења покреће само једном за сваки ХТТП захтев. Филтери у Спринг Боот-у су невероватно корисни када глобално мењате захтеве или одговоре. На пример, ако клијент пошаље информације о праћењу као от-цустом-трацеид или от-цустом-спанид у прилагођеним заглављима, овај филтер пресреће захтев, издваја ова заглавља и шири их у Мапирани дијагностички контекст (МДЦ). Додавањем ИД-ова праћења у МДЦ, обезбеђујемо да су ови идентификатори видљиви у евиденцији генерисаним током обраде захтева.
МДЦ је критичан део оквира за евидентирање као што су СЛФ4Ј и Логбацк. Омогућава нам да складиштимо контекстуалне информације за тренутну нит, као што су прилагођени ИД-ови праћења. Користећи команде попут МДЦ.пут и МДЦ.цлеар, обезбеђујемо да систем евидентирања укључује детаље о праћењу и избегава контаминацију између истовремених захтева. На пример, ако клијент два пошаље `от-цустом-трацеид` као `8ф7ебд8а73ф9а8ф50е6а00а87а20952а`, овај ИД се чува у МДЦ-у и укључује у све низводне евиденције, стварајући конзистентну путању праћења.
С друге стране, за одлазне ХТТП захтеве, РестТемплате пресретач игра суштинску улогу. Имплементацијом ЦлиентХттпРекуестИнтерцептор, можемо приложити иста заглавља праћења (`от-цустом-трацеид` и `от-цустом-спанид`) одлазним захтевима. Ово осигурава да се континуитет праћења одржава када апликација позива друге микросервисе. На пример, када сервер обради захтев са ИД-ом праћења `8ф7ебд8а73ф9а8ф50е6а00а87а20952а`, он прилаже овај ИД одлазним заглављима, тако да низводне услуге могу да препознају и пропагирају праћење неприметно.
Коначно, јединични тестови написани са МоцкМвц потврђују целокупно подешавање симулацијом ХТТП захтева и верификовањем ширења заглавља. У реалним апликацијама, тестирање је кључно како би се осигурало да се заглавља праћења правилно рукују. На пример, слањем ГЕТ захтева са прилагођеним заглављима и прегледом одговора или евиденције, можемо потврдити да филтер и пресретач раде како се очекује. Овај свеобухватни приступ решава изазов без ослањања на наслеђене зависности као што је Спринг Цлоуд Слеутх. На крају, комбинација филтера, пресретача и МДЦ-а обезбеђује континуитет праћења чак и када клијенти користе прилагођена заглавља, чинећи систем робусним и потпуно видљивим. 🌟
Пропагирање прилагођених заглавља праћења у Спринг Боот-у 3.4
Коришћење Јаве са Спринг Боот 3.4 и Мицрометер за позадинску обраду
// 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;
}
}
Јединични тест за прилагођено ширење заглавља трага
Тестирање са ЈУнит и МоцкМвц за валидацију пропагације заглавља трага
// 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());
}
}
Ширење прилагођених заглавља у ХТТП захтевима помоћу РестТемплате-а
Коришћење РестТемплате пресретача за додавање прилагођених заглавља у одлазне захтеве
// 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;
}
}
Руковање прилагођеним траговима заглавља са ОпенТелеметри у Спринг Боот-у 3.4
Када радите са Спринг Боот 3.4, још један моћан приступ за пропагирање трагова из прилагођених заглавља је интеграција ОпенТелеметри. ОпенТелеметри, оквир за посматрање отвореног кода, помаже да инструментално, прикупља и извози трагове неприметно. Пружа механизме за издвајање и убацивање контекста праћења, укључујући прилагођена заглавља попут от-цустом-трацеид и от-цустом-спанид, у вашу апликацију. Користећи ОпенТелеметри ТектМапПропагатор, можете премостити јаз између нестандардних клијената и вашег система видљивости.
Да бисте користили ОпенТелеметри у Спринг Боот-у 3.4, прилагођени пропагатор може бити имплементиран за издвајање информација праћења из прилагођених заглавља и њихово прикључивање тренутном контексту праћења. На пример, када ваш сервер прими долазни захтев од клијента два, ОпенТелеметри може рашчланити прилагођена заглавља и реконструисати оригинални контекст праћења. Ово осигурава да низводне услуге виде исте ИД-ове праћења, омогућавајући видљивост од краја до краја. За разлику од старијих решења као што је Спринг Цлоуд Слеутх, ОпенТелеметри је лаган и усклађен са модерним стандардима за уочљивост.
Комбиновањем ОпенТелеметри пропагатора са Микрометром, можете да обогатите своје метрике и евиденцију информацијама о траговима. Замислите да видите трагове за захтеве који долазе и од клијента један и од клијента два неприметно у свом алату за посматрање. ОпенТелеметри аутоматски подржава интеграције са Прометхеус, Зипкин или Јаегер, омогућавајући вам да централизујете визуелизацију трагова. Овај приступ осигурава да чак и када су прилагођена заглавља укључена, подаци о траговима се не изгубе, а отклањање грешака постаје знатно лакше. 🚀
Често постављана питања о пропагирању прилагођених трагова у Спринг Боот-у
- Како да ручно издвојим прилагођена заглавља праћења у Спринг Боот-у?
- Можете да користите рекуест.гетХеадер("цустом-хеадер") да ручно преузмете одређено заглавље и додате га у МДЦ користећи МДЦ.пут("трацеИд", валуе).
- Која је предност коришћења ОпенТелеметри за прилагођено ширење трагова?
- ОпенТелеметри пружа модеран приступ који је неутралан од произвођача за пропагирање трагова, укључујући прилагођена заглавља, кроз микросервисе.
- Могу ли да ширим прилагођена заглавља помоћу РестТемплате-а у Спринг Боот-у?
- Да, применом ЦлиентХттпРекуестИнтерцептор, можете да приложите прилагођена заглавља као што су трацеид и спанид одлазним захтевима.
- Како да региструјем филтер за хватање заглавља на глобалном нивоу?
- Можете да направите филтер који проширује ОнцеПерРекуестФилтер и да га региструјете помоћу ФилтерРегистратионБеан да бисте ухватили заглавља за све крајње тачке.
- Које алатке могу да користим за визуелизацију трагова из Спринг Боот-а?
- Алати као што су Зипкин, Јаегер и Прометхеус могу да се интегришу са Спринг Боот-ом и ОпенТелеметри-ом да би визуелизовали трагове од краја до краја.
Обезбеђивање беспрекорног континуитета трагова
У савременим системима, руковање прилагођеним заглављима праћења је критично за поуздану видљивост. Коришћењем филтера и пресретача, можете да ухватите информације о праћењу које даје клијент и да их правилно ширите кроз своје услуге. Ово избегава фрагментиране дневнике и трагове који недостају. 🔍
Спринг Боот 3.4, у комбинацији са Мицрометер или ОпенТелеметри, омогућава робусна решења без ослањања на старије алате као што је Спринг Цлоуд Слеутх. Без обзира да ли имате посла са стандардним заглављима клијента један или са прилагођеним заглављима клијента два, примена ових техника ефикасно премошћује празнине у праћењу. 🚀
Извори и референце
- Званична документација Спринг Боот: Пропагација контекста праћења. Спринг Боот документација
- ОпенТелеметри за Јава програмере: Водич за пропагацију трагова. ОпенТелеметри Јава
- Документација о посматрању микрометара: Интегрисање прилагођених заглавља трагова. Мицрометер Обсервабилити
- СЛФ4Ј АПИ за евидентирање: Мапирани дијагностички контекст (МДЦ) случајеви употребе. СЛФ4Ј Мануал