Microservices Architecture
Learn to decompose monolithic Django applications into microservices. Understand service communication patterns, API gateways, message queues with Celery and RabbitMQ, and deployment strategies for distributed Django systems.
Microservices vs Monolith
Microservices split a monolithic Django app into independent services that communicate over HTTP/gRPC or message queues. Each service owns its database, has its own deployment pipeline, and can be scaled independently. Django works well for individual services — use DRF for HTTP APIs and Celery for async communication. Start monolithic, extract services only when team size or scale demands it.
Microservices Patterns for Django
- API Gateway: Use Kong, Traefik, or Nginx to route requests to the right service
- Service Discovery: Each service registers itself; gateway routes by path prefix
- Event-Driven: Use Celery + RabbitMQ/Redis for async communication between services
- Database per Service: Each Django service has its own PostgreSQL database
- Circuit Breaker: Use pybreaker to prevent cascading failures between services
- Health Checks: Add /health/ endpoint to each service for load balancer monitoring
Service Communication with Celery
# settings.py — Celery configuration
CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/0"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
# project/celery.py
import os
from celery import Celery
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
app = Celery("project")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()
# orders/tasks.py — Async tasks
from celery import shared_task
import requests
@shared_task(bind=True, max_retries=3)
def notify_shipping_service(self, order_id):
"""Notify shipping microservice about new order."""
try:
response = requests.post(
"http://shipping-service:8001/api/shipments/",
json={"order_id": order_id},
timeout=10,
)
response.raise_for_status()
return {"status": "success", "shipment_id": response.json()["id"]}
except requests.RequestException as exc:
raise self.retry(exc=exc, countdown=60)
@shared_task
def send_order_confirmation_email(order_id):
"""Send confirmation email asynchronously."""
from orders.models import Order
from django.core.mail import send_mail
order = Order.objects.select_related("user").get(id=order_id)
send_mail(
subject=f"Order #{order.id} Confirmed",
message=f"Thank you! Your order of {order.total} has been placed.",
from_email="noreply@store.com",
recipient_list=[order.user.email],
)
# orders/views.py — Trigger async tasks
from rest_framework import viewsets, status
from rest_framework.response import Response
class OrderViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
order = serializer.save(user=self.request.user)
# Fire-and-forget async tasks
notify_shipping_service.delay(order.id)
send_order_confirmation_email.delay(order.id)