Producer


A producer is an application that sends messages to the messaging system.

Example:

Order Service → sends OrderCreated event

Producer does not know who consumes the event.

A producer is responsible for sending events to Kafka topics.

Why Producers Exist

Producers allow services to publish events without knowing downstream services.

Producer Example

Transaction Service
↓
AccountTransactionCompletedEvent
↓
Kafka Topic: account.transaction.completed.v1

Consumers:

  • Notification Service
  • Audit Service
  • Fraud Detection Service

Flow

Producer → Kafka Broker → Partition → Consumer


How Producer Works

Basic flow:

Application
↓
Producer
↓
Broker
  • Producer sends event to broker.
  • Broker stores it.
  • Consumers read later.

Example Banking Event

Event Class

public class AccountTransactionCompletedEvent {

    private String transactionId;
    private String accountId;
    private double amount;
    private String type; // DEBIT / CREDIT
    private String status;
    private LocalDateTime timestamp;
}

Configuration

application.yaml

spring:
  kafka:
    bootstrap-servers: localhost:9092

    producer:
      acks: all
      retries: 3
      batch-size: 16384
      linger-ms: 10
      buffer-memory: 33554432
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer

What Each Config Means

acks: all

  • Wait for leader + replicas
  • Ensures no data loss

retries: 3

  • Retry sending if failure occurs

batch-size: 16384

  • Producer groups messages into batches
  • Improves performance

linger-ms: 10

  • Wait up to 10ms to fill batch
  • Trade-off: latency vs throughput

buffer-memory: 33554432

  • Memory buffer for unsent messages

Kafka Producer Service

@Service
public class TransactionEventProducer {

    @Autowired
    private KafkaTemplate<String, AccountTransactionCompletedEvent> kafkaTemplate;

    public void publishTransactionEvent(AccountTransactionCompletedEvent event) {

        kafkaTemplate.send(
            "account.transaction.completed.v1",
            event.getAccountId(), // key
            event
        );
    }
}

Why Key = accountId?

Same account → same partition → ordering maintained

Without Key

kafkaTemplate.send(“topic”, event);

  • Kafka distributes randomly
  • No ordering guarantee

Send with CallBack

Even though Kafka handles ACK internally, you can capture result.

public void publishTransactionEvent(AccountTransactionCompletedEvent event) {

    kafkaTemplate.send(
        "account.transaction.completed.v1",
        event.getAccountId(),
        event
    ).addCallback(
        success -> System.out.println("Message sent"),
        failure -> System.out.println("Failed: " + failure.getMessage())
    );
}

Why Callback Matters

  • detect failures
  • log events
  • trigger retry logic (if needed)

Failure Scenario

1. Kafka Down

If Kafka becomes unavailable:

Case Result
retry enabled producer retries : If retries exhausted –> Exception thrown
retry disabled message lost
broker cluster another broker handles

Producer configuration controls behavior.

Example:

spring.kafka.producer.retries: 3

Handling

try {
    kafkaTemplate.send(...);
} catch (Exception e) {
    // log / store in DB (outbox pattern)
}

2. Broker Slow

  • Messages accumulate in buffer
  • batching increases
  • delay increases
  • If buffer full
    • Producer blocks OR fails

3. Network Issue

  • retries triggered
  • possible duplicate sends

Idempotent Producer

Retries can cause duplicates:

Message sent → timeout → retry → duplicate

Enable idempotence:

spring:
  kafka:
    producer:
      enable-idempotence: true
  • Kafka ensures no duplicate writes
  • Exactly-once per partition (producer side)

Delivery Guarantees

At Most Once

acks=0

  • fast
  • data loss possible
At Least Once (Most Common)

acks=all + retries

  • no loss
  • duplicates possible
Exactly Once (Partial)
  • idempotent producer
  • no duplicates from producer

Where Message Is Stored

Kafka stores message in:

/var/lib/kafka/data/account.transaction.completed.v1-0/

File:

00000000000000000000.log


Producer Best Practices

  • Use acks=all
  • Enable retries
  • Use idempotent producer
  • Use proper keys (like accountId)
  • Avoid large payloads
  • Handle failures


This site uses Just the Docs, a documentation theme for Jekyll.