Hana — VyuApp Support
Online
20/20 pesan tersisa
🌸 Selamat datang di VyuApp! Saya Hana, ada yang bisa saya bantu hari ini?
Semua artikel

Engineering

Apache Kafka untuk Arsitektur Microservices: Panduan Lengkap Event-Driven Architecture

Pelajari cara membangun arsitektur microservices yang scalable dengan Apache Kafka. Panduan lengkap event-driven architecture, async communication, dan best practices 2026.

7 Juli 2026 11 min read#Apache Kafka#Microservices#Event-Driven Architecture#Message Broker
Apache Kafka untuk Arsitektur Microservices: Panduan Lengkap Event-Driven Architecture

Microservices membuat aplikasi lebih modular, tapi juga menciptakan masalah baru: bagaimana ratusan service berkomunikasi tanpa saling menunggu? Apache Kafka hadir sebagai event backbone yang menyelesaikan masalah ini — bukan sekadar message queue, tapi distributed event streaming platform yang bisa memproses jutaan event per detik.

Apache Kafka Event Streaming

Apache Kafka: event streaming platform untuk microservices modern

Butuh contoh event-driven architecture yang lebih detail? Baca juga panduan lengkap Redis Streams untuk developer Indonesia — alternatif ringan untuk use case tertentu. Jika Anda sedang membangun data pipeline end-to-end, simak juga cara membangun data pipeline yang tidak pernah tidur.

2. Mengapa Microservices Butuh Event Backbone?

Bayangkan sebuah e-commerce dengan 50 microservices. Ketika user checkout, service order harus memberi tahu service inventory, payment, shipping, notification, dan analytics. Jika semua komunikasi dilakukan langsung (synchronous), satu service yang lambat akan memblokir seluruh alur. Inilah yang disebut cascading failure.

Kafka menyelesaikan masalah ini dengan pendekatan event-driven architecture. Alih-alih service A memanggil service B secara langsung, service A cukup mempublish event ke Kafka. Service B, C, D — dan service manapun yang butuh data itu — tinggal subscribe ke topic yang sama. Tidak ada coupling langsung antar service.

💡 Konsep Kunci: Dalam event-driven architecture, services berkomunikasi melalui events (perubahan state), bukan RPC calls. Ini membuat setiap service benar-benar independent — bisa di-deploy, di-scale, dan di-maintain secara terpisah.

3. Arsitektur Kafka: Komponen yang Harus Dipahami

Sebelum masuk ke implementasi, pahami dulu komponen utama Kafka:

Microservices Architecture

Arsitektur microservices membutuhkan komunikasi yang reliable antar service

Broker dan Cluster

Broker adalah server Kafka yang menyimpan data. Sebuah cluster terdiri dari minimal 3 broker untuk fault tolerance. Kafka versi 4.0 (rilis Maret 2025) menggunakan KRaft mode — menghapus ketergantungan pada ZooKeeper dan menggantinya dengan protocol Raft bawaan. Ini membuat arsitektur lebih sederhana dan lebih cepat.

Topic dan Partition

Topic adalah kategori message. Setiap topic dibagi menjadi partitions — unit dasar parallelisme Kafka. Partition berisi urutan message yang tidak berubah (immutable log). Semakin banyak partition, semakin tinggi throughput yang bisa dicapai.

Producer dan Consumer

Producer mengirim event ke topic tertentu. Consumer membaca event dari topic. Yang menarik, consumer bisa membaca dari posisi manapun di log — bisa dari awal, dari 1 jam lalu, atau dari posisi terakhir. Ini memungkinkan event replay, fitur yang tidak dimiliki message queue tradisional.

Consumer Group

Consumer group memungkinkan parallel processing. Jika sebuah topic punya 6 partition dan consumer group punya 3 consumer, setiap consumer akan membaca 2 partition secara paralel. Tambah consumer? Throughput naik tanpa mengubah kode.

Replica

Setiap partition direplikasi ke beberapa broker. Satu replica ditandai sebagai leader (melayani read/write), sisanya follower. Jika leader mati, follower otomatis mengambil alih. Data tidak pernah hilang selama minimal 1 replica hidup.

4. Pola Komunikasi Microservices dengan Kafka

Kafka bukan cuma "kirim pesan". Ada beberapa pola arsitektural yang menjadi fondasi microservices modern:

Event Notification

Pola paling sederhana. Ketika service A melakukan sesuatu, ia mempublish event. Service lain tinggal subscribe. Contoh: ketika order dibuat, publish event OrderCreated. Service inventory, payment, dan notification masing-masing subscribe dan memproses sesuai kebutuhan.

Event-Carried State Transfer

Event membawa data yang cukup lengkap, bukan cuma ID. Service consumer tidak perlu memanggil balik service producer untuk mendapatkan data. Ini mengurangi inter-service calls secara drastis.

Saga Pattern

Untuk transaksi yang melibatkan beberapa service, saga pattern memecah transaksi besar menjadi sequence of local transactions. Setiap step mempublish event yang memicu step berikutnya. Jika gagal, compensating events dibuat untuk membatalkan step sebelumnya.

⚡ Contoh Saga: User bayar → OrderService publish PaymentInitiated → PaymentService proses → publish PaymentCompleted → InventoryService kurangi stok → publish StockReserved. Jika PaymentService gagal, publish PaymentFailed → OrderService batalkan order.

CQRS (Command Query Responsibility Segregation)

Memisahkan model write (command) dan read (query). Write model menyimpan data di database utama, lalu mempublish event ke Kafka. Read model subscribe event dan membangun view/aggregate sendiri yang dioptimasi untuk query tertentu. Hasilnya: write dan read bisa di-scale secara independen.

Change Data Capture (CDC)

Menggunakan Kafka Connect dengan Debezium connector untuk mereplikasi perubahan database secara real-time ke Kafka. Ketika ada INSERT, UPDATE, atau DELETE di database, perubahan itu otomatis menjadi event di Kafka. Service lain bisa subscribe tanpa perlu mengakses database langsung.

Message Queue Concept

Message queue memungkinkan komunikasi asynchronous antar service

// Advertisement

5. Kafka vs RabbitMQ vs Pulsar vs Kinesis

Memilih message broker untuk microservices bukan keputusan sepele. Berikut perbandingan yang jujur:

Fitur Apache Kafka RabbitMQ Apache Pulsar Amazon Kinesis
Throughput 1M+ msg/sec ~50K msg/sec 1M+ msg/sec ~1M msg/sec
Lateni Sub-millisecond Low Sub-millisecond Low-medium
Persistence ✅ Disk-based log ⚠️ Queue-based ✅ Tiered storage ✅ 24 jam default
Replay ✅ Full replay ❌ Tidak ada ✅ Full replay ⚠️ 24 jam saja
Consumer Group ✅ Native ✅ Competing consumers ✅ Native ✅ Enhanced fan-out
Ordering ✅ Per-partition ⚠️ Per-queue ✅ Per-partition ✅ Per-shard
Ecosystem ✅ Connect, Streams, ksqlDB ⚠️ Plugins ✅ Functions, IO ⚠️ AWS only
Ops Complexity ⚠️ Medium-high ✅ Low-medium ❌ High ✅ Managed
Vendor Lock-in ✅ Open source ✅ Open source ✅ Open source ❌ AWS only
🎯 Kapan pakai Kafka? Ketika butuh throughput tinggi, event replay, event sourcing, atau build streaming data pipeline. Kafka unggul untuk use case yang butuh log-based persistence dan parallel consumption.
⚠️ Kapan pakai RabbitMQ? Ketika routing yang kompleks lebih penting dari throughput — misalnya work queues dengan priority, delay, atau fan-out yang rumit. RabbitMQ lebih cocok untuk task distribution daripada event streaming.

6. Setup Kafka untuk Microservices

Mulai dari Docker Compose untuk development. Konfigurasi ini menggunakan KRaft mode (tanpa ZooKeeper):

Docker Compose untuk Kafka

# docker-compose.yml
version: '3.8'
services:
  kafka:
    image: apache/kafka:3.9.0
    container_name: kafka-broker
    ports:
      - "9092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
      CLUSTER_ID: 'MkU3OEVBNTcwNTJENDM2Qk'

Producer Microservice (Java)

// OrderService.java - Publish event saat order dibuat
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;

public class OrderService {
    private final KafkaProducer<String, String> producer;
    private final ObjectMapper mapper = new ObjectMapper();

    public OrderService() {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", StringSerializer.class.getName());
        props.put("value.serializer", StringSerializer.class.getName());
        props.put("acks", "all");
        props.put("enable.idempotence", true); // exactly-once delivery
        this.producer = new KafkaProducer<>(props);
    }

    public void createOrder(Order order) throws Exception {
        // Simpan order ke database...

        // Publish event ke Kafka
        OrderEvent event = new OrderEvent("OrderCreated", order.getId(),
            order.getUserId(), order.getItems(), Instant.now());

        ProducerRecord<String, String> record =
            new ProducerRecord<>("orders", order.getId(), mapper.writeValueAsString(event));

        producer.send(record, (metadata, exception) -> {
            if (exception != null) {
                // Handle error, retry atau dead letter queue
                System.err.println("Failed to publish OrderCreated: " + exception.getMessage());
            } else {
                System.out.println("OrderCreated published to " + metadata.topic()
                    + " partition " + metadata.partition());
            }
        });
    }
}

Consumer Microservice (Python)

# inventory_service.py - Subscribe ke order events
from kafka import KafkaConsumer
import json

class InventoryService:
    def __init__(self):
        self.consumer = KafkaConsumer(
            'orders',
            bootstrap_servers='localhost:9092',
            group_id='inventory-service',
            auto_offset_reset='earliest',
            enable_auto_commit=False,  # manual commit untuk at-least-once
            value_deserializer=lambda m: json.loads(m.decode('utf-8'))
        )

    def process_events(self):
        print("InventoryService listening to 'orders' topic...")
        for message in self.consumer:
            event = message.value
            print(f"Received event type: {event['type']}")

            if event['type'] == 'OrderCreated':
                self.reserve_stock(event['payload']['items'])
            elif event['type'] == 'OrderCancelled':
                self.release_stock(event['payload']['items'])

            # Manual commit setelah proses berhasil
            self.consumer.commit()

    def reserve_stock(self, items):
        for item in items:
            # Kurangi stok di database...
            print(f"Reserved {item['quantity']}x {item['name']}")
        print("Stock reserved successfully")

if __name__ == '__main__':
    service = InventoryService()
    service.process_events()

Kafka CLI Commands

# Buat topic baru
bin/kafka-topics.sh --create \
  --topic orders \
  --bootstrap-server localhost:9092 \
  --partitions 6 \
  --replication-factor 3

# Lihat daftar topic
bin/kafka-topics.sh --list --bootstrap-server localhost:9092

# Lihat detail topic
bin/kafka-topics.sh --describe --topic orders --bootstrap-server localhost:9092

# Test kirim message dari CLI
bin/kafka-console-producer.sh --topic orders --bootstrap-server localhost:9092

# Test baca message dari CLI
bin/kafka-console-consumer.sh --topic orders --bootstrap-server localhost:9092 \
  --from-beginning --group test-consumer

# Cek consumer lag
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --describe --group inventory-service

7. Ekosistem Kafka: Lebih dari Sekadar Broker

Kafka bukan cuma message broker. Ekosistemnya punya tools kuat untuk microservices:

Data Pipeline Visualization

Data pipeline modern memanfaatkan streaming untuk real-time processing

Kafka Connect

Framework untuk integrasi data dari/to sistem eksternal tanpa menulis kode custom. Tersedia ratusan connector: PostgreSQL, MongoDB, Elasticsearch, S3, dan banyak lagi. Untuk CDC, gunakan Debezium connector yang mereplikasi perubahan database ke Kafka secara real-time.

Kafka Streams

Java library untuk stream processing. Tidak perlu cluster terpisah — berjalan sebagai bagian dari aplikasi microservice. Cocok untuk aggregasi, filtering, join, dan transformasi data secara real-time.

// Contoh Kafka Streams: Aggregasi order per user
import org.apache.kafka.streams.*;
import org.apache.kafka.streams.kstream.*;

Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "order-aggregation");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");

StreamsBuilder builder = new StreamsBuilder();
KStream<String, OrderEvent> orders = builder.stream("orders");

orders.groupByKey()
    .windowedBy(TimeWindows.ofSizeWithNoGrace(Duration.ofMinutes(5)))
    .count()
    .toStream()
    .to("order-counts");

ksqlDB

SQL engine untuk query data di Kafka secara real-time. Tidak perlu menulis kode Java atau Python. Contoh: buat materialized view dari order events hanya dengan SQL.

-- Buat stream dari topic orders
CREATE STREAM orders_stream (
  event_type VARCHAR KEY,
  order_id VARCHAR,
  user_id VARCHAR,
  total_amount DECIMAL(10,2)
) WITH (
  KAFKA_TOPIC = 'orders',
  VALUE_FORMAT = 'JSON'
);

-- Agregasi: total order per user dalam 1 jam window
SELECT user_id, COUNT(*) as order_count, SUM(total_amount) as total_spent
FROM orders_stream
WINDOW TUMBLING (SIZE 1 HOUR)
GROUP BY user_id;

Schema Registry

Centralized schema management untuk memastikan producer dan consumer menggunakan format data yang konsisten. Mendukung Avro, Protobuf, dan JSON Schema. Tanpa Schema Registry, perubahan format data bisa memecah consumer secara tiba-tiba.

8. Best Practices untuk Microservices dengan Kafka

Partitioning Strategy

Gunakan message key yang tepat untuk memastikan ordering. Semua event untuk order yang sama harus masuk ke partition yang sama — maka gunakan order_id sebagai key. Jangan gunakan null key (akan di-round-robin, menghilangkan ordering guarantee).

Consumer Group Design

Setiap microservice harus punya consumer group sendiri. Hindari sharing consumer group antar service — ini membuat distribusi message tidak terduga. Jika butuh fan-out (satu event diproses banyak service), setiap service harus punya group ID unik.

// Advertisement

Exactly-Once Semantics

Kafka mendukung exactly-once delivery melalui kombinasi idempotent producer dan transactional API. Untuk microservices, gunakan enable.idempotence=true di producer dan manual offset commit di consumer setelah proses berhasil.

Dead Letter Queue (DLQ)

Jika consumer gagal memproses event setelah N kali retry, kirim ke DLQ topic daripada memblokir seluruh consumer. Ini memastikan satu event yang bermasalah tidak menghentikan seluruh pipeline.

Monitoring Consumer Lag

Consumer lag (selisih antara offset terakhir di partition dan offset yang sudah diproses consumer) adalah metrik kunci. Jika lag terus naik, artinya consumer tidak bisa mengikuti throughput producer. Gunakan Kafka Lag Exporter dengan Prometheus dan Grafana untuk monitoring.

🔧 Monitoring Stack: Kafka JMX metrics → Kafka Lag Exporter → Prometheus → Grafana. Dashboard yang perlu dipantau: consumer lag per group, broker throughput, under-replicated partitions, dan request latency.

Retention Policy

Atur retention.ms sesuai kebutuhan. Default 7 hari. Untuk microservices yang butuh event replay jangka panjang, pertimbangkan menggunakan tiered storage (tersedia di Kafka 3.7+) untuk archive data lama ke S3/GCS dengan biaya lebih rendah.

9. Studi Kasus: E-Commerce dengan Kafka

Mari lihat bagaimana sebuah e-commerce membangun arsitektur microservices dengan Kafka sebagai backbone:

Service Topic yang Dipublish Topic yang Diasubscribe
Order Service orders payments, inventory
Payment Service payments orders
Inventory Service inventory orders
Notification Service notifications orders, payments
Analytics Service orders, payments, inventory, notifications
Search Service inventory (via CDC)

Alur satu transaksi: User checkout → OrderService publish OrderCreated → PaymentService proses payment → publish PaymentCompleted → InventoryService kurangi stok → NotificationService kirim email → AnalyticsService catat transaksi. Semua berjalan asynchronous, tidak ada service yang menunggu service lain.

🎯 Manfaat untuk e-commerce: Jika NotificationService down, order tetap diproses. Ketika service naik lagi, ia akan membaca event yang terlewat dari Kafka log. Tidak ada data yang hilang.

10. FAQ

Berapa minimum broker yang dibutuhkan untuk production?

Minimal 3 broker untuk fault tolerance. Dengan 3 broker dan replication factor 3, cluster bisa survive jika 1 broker mati tanpa kehilangan data. Untuk throughput tinggi, mulai dari 5-10 broker dan scale sesuai kebutuhan.

Kapan harus pakai Kafka Streams vs Apache Flink?

Kafka Streams cocok untuk transformasi sederhana yang berjalan di dalam microservice — tidak perlu cluster terpisah. Apache Flink dibutuhkan untuk complex event processing, stateful computation skala besar, atau ketika butuh window yang lebih sophisticated. Mulai dari Kafka Streams, migrasi ke Flink jika kebutuhan berkembang.

Bagaimana menangani event yang gagal diproses?

Gunakan retry dengan exponential backoff. Jika tetap gagal setelah N kali percobaan, kirim ke Dead Letter Queue (DLQ) topic. Bangun DLQ consumer yang bisa memanually review dan reprocess event yang bermasalah. Jangan pernah memblokir consumer group karena satu event bermasalah.

Apakah Kafka aman untuk data sensitif?

Kafka mendukung TLS encryption, SASL authentication, dan ACL authorization. Untuk data sensitif (PII, payment data), gunakan encryption in-transit (TLS) dan encryption at-rest. Pertimbangkan juga field-level encryption menggunakan Confluent Schema Registry dengan custom serializer.

Berapa biaya operasional Kafka untuk startup kecil?

Jika di-self-host: 3 VPS minimal (Rp 500K/bulan per VPS) = Rp 1.5 juta/bulan. Jika pakai managed service: Confluent Cloud mulai dari $100/bulan, Amazon MSK mulai dari $0.11/jam. Untuk MVP, pertimbangkan Confluent Cloud atau Aiven untuk mengurangi operational overhead.

Jika Anda membangun stack backend yang mencakup caching dan real-time data, pertimbangkan juga membaca panduan Redis caching patterns untuk scalable web apps sebagai pelengkap arsitektur microservices ini.

Butuh Arsitektur Microservices yang Reliable?

VyuApp membantu Anda membangun sistem event-driven yang scalable dengan pendekatan yang tepat.

Kunjungi VyuApp →

Image Attribution

  • Photo by Markus Spiske on Unsplash - Unsplash
  • Photo by Growtika on Unsplash - Unsplash
  • Photo by Samuel Angor on Unsplash - Unsplash
  • Photo by Deng Xiang on Unsplash - Unsplash

Referensi

  1. Apache Kafka Documentation — kafka.apache.org
  2. Confluent Kafka Documentation — docs.confluent.io
  3. LinkedIn Engineering Blog: Building Kafka — engineering.linkedin.com
  4. Red Hat: What is Apache Kafka? — redhat.com
  5. Debezium Documentation (CDC with Kafka) — debezium.io

// Advertisement

V

VyuApp Studio

Bespoke web engineering — Garut, ID