Методы 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»