Production Patterns · Intermediate
Consumer with Message Headers
Kafka message headers carry metadata: trace IDs, event type, schema version, retry count. Essential for distributed tracing and routing.
@Service
public class HeaderAwareConsumer {
// Inject specific headers via @Header
@KafkaListener(topics = "orders.order.created")
public void onOrder(
OrderEvent event,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
@Header(KafkaHeaders.RECEIVED_PARTITION) int partition,
@Header(KafkaHeaders.OFFSET) long offset,
@Header(value = "X-Trace-Id", required = false) String traceId,
@Header(value = "X-Event-Version", required = false) String eventVersion
) {
MDC.put("traceId", traceId != null ? traceId : "unknown");
log.info("Processing order from {}-{} @ offset {}", topic, partition, offset);
// process...
}
}
// Producer: add headers
@Service
public class TracingOrderProducer {
public void publish(Order order) {
var record = new ProducerRecord<>("orders.order.created",
null, System.currentTimeMillis(), order.getId(),
new OrderCreatedEvent(order));
record.headers()
.add("X-Trace-Id", TraceContext.current().toBytes())
.add("X-Event-Version", "2".getBytes())
.add("X-Source-Service", "order-service".getBytes());
kafkaTemplate.send(record);
}
}