Creating an at-least-once Kafka producer on multiple application instances. #52982
Replies: 1 comment
|
The The
What works in Kubernetes: use the pod name via the mp.messaging.outgoing.outbox.transactional-id=${HOSTNAME}-outboxThis gives each pod its own stable transactional identity, which is exactly what Kafka expects. On the property naming confusion — For dynamic topics with OutgoingKafkaRecordMetadata<String> metadata = OutgoingKafkaRecordMetadata.<String>builder()
.withTopic("dynamic-topic-name")
.build();
KafkaRecord<String, OutboxGenericMessage> record = KafkaRecord.of(key, value)
.addMetadata(metadata);This sidesteps the static topic config entirely and lets you route dynamically inside the transaction boundary. Your |
Uh oh!
There was an error while loading. Please reload this page.
We want to send a batch of message to a dynamic topic. And we want to be sure that a message arrives at least once.
We would rather not have a ack for every message, for performance considerations.
Our current solution (code below) works as long as there is a single application instance, but fails when there are more instances. In that case this error message appears:
Kafka producer failed: org.apache.kafka.common.errors.ProducerFencedException: Producer with transactionalId 'joindata-outbox' and (producerId=399747322, epoch=22) has been fenced by another producer with the same transactionalIdOur theory is that every instance should set its own unique transactional-id. We tried this, but are not able to get it working:
Adding the line below to application.properties has no effect. We still get the producer fenced exception with transactionalId 'joindata-outbox' as if the setting has no effect. Line:
mp.messaging.outgoing.outbox.transactional-id=${quarkus.application.name}-${channelName}-${quarkus.uuid}And with this variant, it also does not work (We get an error about a non-transactional producer being used):
mp.messaging.outgoing.outbox.transactional.id=${quarkus.application.name}-${channelName}-${quarkus.uuid}Question: How should we code a producer that:
We are using Quarkus version 3.20.0. Any advise is greatly appreciated. Are we on the right track or not?
This is the code of the message sending:
application.properties:
All reactions