0
0
Microservicessystem_design~7 mins

Message brokers (Kafka, RabbitMQ) in Microservices - System Design Guide

Choose your learning style9 modes available
Problem Statement
When multiple microservices need to communicate, direct calls can cause tight coupling and failures cascade if one service is down. Without a reliable message system, messages can be lost, delayed, or cause bottlenecks, leading to inconsistent data and poor user experience.
Solution
Message brokers act as intermediaries that receive, store, and forward messages between services asynchronously. They decouple services by allowing producers to send messages without waiting for consumers, ensuring reliable delivery, buffering, and load leveling.
Architecture
Producer 1
Producer 2
(Kafka or

This diagram shows producers sending messages to a message broker, which then routes messages asynchronously to multiple consumers.

Trade-offs
✓ Pros
Decouples microservices, allowing independent scaling and deployment.
Provides reliable message delivery with persistence and retries.
Enables asynchronous communication, improving system responsiveness.
Supports load balancing and buffering to handle traffic spikes.
✗ Cons
Adds operational complexity and requires managing broker infrastructure.
Introduces eventual consistency, which may complicate data synchronization.
Can increase latency compared to direct synchronous calls.
Use when microservices need reliable, asynchronous communication at scale, especially with high message volumes or when services have different processing speeds.
Avoid when system requires strict synchronous interactions or when message volume is very low (under 100 messages per second), as overhead may outweigh benefits.
Real World Examples
Netflix
Uses Kafka to decouple microservices for event-driven data pipelines, ensuring reliable streaming data delivery across services.
Uber
Employs Kafka to handle high-throughput event streams for real-time analytics and dispatching, preventing service bottlenecks.
Spotify
Uses RabbitMQ for asynchronous task queues to manage background jobs and improve system resilience.
Code Example
The before code shows a direct call from ServiceA to ServiceB, causing tight coupling and blocking. The after code uses RabbitMQ to send messages asynchronously; ServiceA publishes messages to a queue, and ServiceB consumes them independently, improving decoupling and reliability.
Microservices
### Before: Direct synchronous call (no message broker)
class ServiceA:
    def send_data(self, data):
        service_b = ServiceB()
        service_b.process_data(data)

class ServiceB:
    def process_data(self, data):
        print(f"Processing {data}")


### After: Using RabbitMQ message broker
import pika

class ServiceA:
    def send_data(self, data):
        connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
        channel = connection.channel()
        channel.queue_declare(queue='task_queue', durable=True)
        channel.basic_publish(
            exchange='',
            routing_key='task_queue',
            body=data.encode(),
            properties=pika.BasicProperties(delivery_mode=2))
        connection.close()

class ServiceB:
    def start_consuming(self):
        connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
        channel = connection.channel()
        channel.queue_declare(queue='task_queue', durable=True)

        def callback(ch, method, properties, body):
            print(f"Processing {body.decode()}")
            ch.basic_ack(delivery_tag=method.delivery_tag)

        channel.basic_qos(prefetch_count=1)
        channel.basic_consume(queue='task_queue', on_message_callback=callback)
        channel.start_consuming()
OutputSuccess
Alternatives
Direct synchronous API calls
Services call each other directly and wait for responses, creating tight coupling.
Use when: When low latency and immediate response are critical and service dependencies are stable.
Event streaming platforms (e.g., Apache Pulsar)
Similar to Kafka but with multi-tenancy and geo-replication features.
Use when: When advanced multi-region replication and topic management are required.
Shared database polling
Services read/write to a shared database to communicate, polling for changes.
Use when: For very simple or legacy systems where introducing a broker is not feasible.
Summary
Message brokers decouple microservices by enabling asynchronous communication through reliable message passing.
They improve system resilience and scalability by buffering and retrying messages between producers and consumers.
Choosing the right broker depends on message volume, delivery guarantees, and system requirements.