Spring Boot @Async-Methoden erben keinen Trace-Kontext von der übergeordneten @Scheduled-Methode – wie kann man die TracJava

Java-Forum
Anonymous
 Spring Boot @Async-Methoden erben keinen Trace-Kontext von der übergeordneten @Scheduled-Methode – wie kann man die Trac

Post by Anonymous »

Ich habe eine Spring Boot-Anwendung mit geplanten Jobs, die asynchrone Methoden aufrufen. Die geplante Methode erhält automatisch eine Ablaufverfolgungs-ID, die jedoch nicht an die asynchronen Methoden weitergegeben wird.
Ich benötige für jede geplante Ausführung
  • eine gemeinsame Ablaufverfolgungs-ID für alle Vorgänge
  • mit unterschiedlichen Span-IDs für jeden asynchronen Vorgang.
Aktuelles Setup:
  • Spring Boot 3.5.4
  • Micrometer 1.15.2 mit Brave Bridge für die Ablaufverfolgung
  • Log4j2 mit MDC für strukturierte Protokollierung
  • Code: Select all

    ThreadPoolTaskExecutor
    für die asynchrone Verarbeitung
PollingService.java

Code: Select all

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

Code: Select all

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

Code: Select all

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;
}
}
Problem:
In meinen Protokollen sehe ich:
Geplante Methode: TraceId=abc123, spanId=def456

Asynchrone Methoden: TraceId=null, SpanId=null
Der Trace-Kontext wird nicht über Threadgrenzen hinweg weitergegeben, wenn @Async-Methoden ausgeführt werden.
Was ich brauche:
Alle Methoden in einer geplanten Ausführung sollten die gleiche Trace-ID haben
Jede asynchrone Methode sollte ihre eigene eindeutige Span-ID haben
MDC sollte in allen Threads ordnungsgemäß TraceId/spanId für die Protokollkorrelation enthalten
Frage:
Was ist die empfohlene Methode zur Weitergabe des Trace-Kontexts von @Scheduled? Methoden zu @Async-Methoden in Spring Boot mit Micrometer/Brave?
Ich würde eine Lösung bevorzugen, die:
  • Die integrierten Ablaufverfolgungsfunktionen von Spring Boot nutzt
  • Eine klare Trennung zwischen Geschäftslogik und Ablaufverfolgung beibehält
  • Funktioniert mit dem vorhandenen @Async-Annotationsmuster
  • Nicht erfordern eine erhebliche Umgestaltung des vorhandenen Codes
Beispiele oder Best Practices wären sehr willkommen!

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post