Методы Spring Boot @Async не наследуют контекст трассировки от родительского метода @Scheduled – как распространить TracJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Методы Spring Boot @Async не наследуют контекст трассировки от родительского метода @Scheduled – как распространить Trac

Сообщение Anonymous »

У меня есть приложение Spring Boot с запланированными заданиями, вызывающими асинхронные методы. Запланированный метод получает идентификатор трассировки автоматически, но он не распространяется на асинхронные методы.
Мне нужно, чтобы каждое запланированное выполнение имело
  • один идентификатор трассировки, общий для всех операций
  • с разными идентификаторами диапазона для каждой асинхронной операции.
Текущая настройка:
  • Spring Boot 3.5.4
  • Micrometer 1.15.2 с Brave Bridge для трассировки
  • Log4j2 с MDC для структурированного ведения журнала
  • Код: Выделить всё

    ThreadPoolTaskExecutor
    для асинхронной обработки
PollingService.java

Код: Выделить всё

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@EnableScheduling
@RequiredArgsConstructor
public class PollingService {

@NonNull
private final DataProcessor dataProcessor;

@Scheduled(fixedDelay = 5000)
public void pollData() {
log.info("Starting data polling");
// Shows traceId and spanId correctly in logs

// These async calls lose trace context
dataProcessor.processPendingData();
dataProcessor.processRetryData();
}
}
DataProcessor.java

Код: Выделить всё

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class DataProcessor {

public static final String THREAD_POOL_NAME = "threadPoolTaskExecutor";

@Async(THREAD_POOL_NAME)
public void processPendingData() {
log.info("Processing pending items");
// Shows traceId: null in logs
// Business logic here
}

@Async(THREAD_POOL_NAME)
public void processRetryData() {
log.info("Processing retry items");
// Shows traceId: null in logs
// Retry logic here
}
}
AsyncConfig.java

Код: Выделить всё

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
public class AsyncConfig {

public static final String THREAD_POOL_NAME = "threadPoolTaskExecutor";

@Value("${thread-pools.data-poller.max-size:10}")
private int threadPoolMaxSize;

@Value("${thread-pools.data-poller.core-size:5}")
private int threadPoolCoreSize;

@Value("${thread-pools.data-poller.queue-capacity:100}")
private int threadPoolQueueSize;

@Bean(name = THREAD_POOL_NAME)
public ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(threadPoolMaxSize);
executor.setCorePoolSize(threadPoolCoreSize);
executor.setQueueCapacity(threadPoolQueueSize);
executor.initialize();
return executor;
}
}
Проблема:
В моих журналах я вижу:
Запланированный метод: трассировка Id=abc123, spanId=def456

Асинхронные методы: трассировка = null, spanId=null
Контекст трассировки не распространяется через границы потока при использовании методов @Async выполнить.
Что мне нужно:
Все методы в одном запланированном выполнении должны использовать один и тот же идентификатор трассировки.
Каждый асинхронный метод должен иметь свой собственный уникальный идентификатор диапазона.
MDC должен правильно содержать TraceId/spanId во всех потоках для корреляции журналов.
Вопрос:
Каков рекомендуемый способ распространения контекста трассировки из Методы @Scheduled на методы @Async в Spring Boot с Micrometer/Brave?
Я бы предпочел решение, которое:
  • Использует встроенные возможности трассировки Spring Boot
  • Поддерживает четкое разделение между бизнес-логикой и трассировкой
  • Работает с существующим шаблоном аннотаций @Async
  • Не требует значительного рефакторинга существующего кода.
Будем очень признательны за любые примеры и рекомендации!

Подробнее здесь: https://stackoverflow.com/questions/798 ... d-parent-m
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»