0
0
Microservicessystem_design~7 mins

Ambassador pattern in Microservices - System Design Guide

Choose your learning style9 modes available
Problem Statement
When microservices need to communicate with external systems or other services, direct calls can cause duplicated code, inconsistent configurations, and difficulty managing cross-cutting concerns like retries, logging, or security. This leads to fragile services that are hard to maintain and scale.
Solution
The Ambassador pattern introduces a helper service (the ambassador) that sits alongside the main service. It handles all communication with external systems, managing retries, logging, and security consistently. The main service interacts only with the ambassador, simplifying its code and centralizing communication logic.
Architecture
┌─────────────┐       ┌─────────────┐       ┌───────────────┐
│  Service A  │──────▶│ Ambassador  │──────▶│ External API  │
└─────────────┘       └─────────────┘       └───────────────┘

Description:
Service A sends requests to the Ambassador, which manages all external communication with the External API, handling retries, logging, and security.
Trade-offs
✓ Pros
Centralizes communication logic, reducing duplication across services.
Improves maintainability by isolating cross-cutting concerns like retries and logging.
Enables independent scaling and updating of communication logic without changing the main service.
✗ Cons
Adds an extra network hop, potentially increasing latency.
Increases system complexity by introducing additional components to manage.
Requires deployment and monitoring of ambassador services alongside main services.
Use when multiple services need consistent communication handling with external systems, especially at scale above hundreds of requests per second or when cross-cutting concerns are complex.
Avoid when the system is small with simple communication needs under a few dozen requests per second, as the added complexity and latency outweigh benefits.
Real World Examples
Netflix
Uses the Ambassador pattern to manage communication between microservices and external APIs, centralizing retries and security policies.
Uber
Implements ambassadors to handle service-to-service communication, ensuring consistent logging and fault tolerance.
Google
Uses ambassador proxies in Kubernetes environments to manage external traffic and service mesh integration.
Code Example
Before applying the Ambassador pattern, each service implements its own retry logic, causing code duplication and inconsistent behavior. After applying the pattern, the main service calls the Ambassador service, which centralizes retries and error handling, simplifying the main service code.
Microservices
### Before Ambassador pattern (direct call with duplicated retry logic)
import requests

def call_external_api():
    for _ in range(3):
        try:
            response = requests.get('https://external.api/data')
            if response.status_code == 200:
                return response.json()
        except requests.exceptions.RequestException:
            pass
    raise Exception('Failed after retries')


### After Ambassador pattern (service calls ambassador, ambassador handles retries)

# In Service A
import requests

def call_ambassador():
    response = requests.get('http://localhost:9000/api/data')
    response.raise_for_status()
    return response.json()

# In Ambassador service
import requests
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/data')
def proxy_data():
    for _ in range(3):
        try:
            response = requests.get('https://external.api/data')
            if response.status_code == 200:
                return jsonify(response.json())
        except requests.exceptions.RequestException:
            pass
    return jsonify({'error': 'Failed after retries'}), 500

if __name__ == '__main__':
    app.run(port=9000)
OutputSuccess
Alternatives
Sidecar pattern
Sidecar runs alongside the main service in the same host or container, managing auxiliary tasks beyond communication, while Ambassador focuses specifically on external communication.
Use when: Choose Sidecar when you need broader support like configuration, logging, and monitoring alongside communication.
API Gateway
API Gateway acts as a single entry point for clients to access multiple services, whereas Ambassador is a helper for individual services to communicate externally.
Use when: Choose API Gateway when you need centralized client request routing and aggregation.
Summary
The Ambassador pattern prevents duplicated communication logic by introducing a helper service that manages external calls.
It centralizes retries, logging, and security, simplifying the main service and improving maintainability.
This pattern is best for systems with complex communication needs and multiple services interacting with external APIs.