Designing Service Communication Patterns
1. Designing Synchronous Communication
| Protocol | Strength | Watch Out |
|---|---|---|
| REST/HTTP | Universal, debuggable | Verbose, no streaming |
| gRPC | Binary, multiplexed, streaming | Browser needs proxy |
| GraphQL | Client-shaped responses | Caching complex |
| Sync risk | Cascading failure, latency stacking | — |
2. Designing Asynchronous Communication
| Pattern | Detail |
|---|---|
| Event-driven | Pub/sub via Kafka, NATS |
| Message queue | Work queue (SQS, RabbitMQ) |
| Pros | Decoupled, resilient, buffer load |
| Cons | Eventual consistency, harder debugging |
3. Designing Request-Reply Pattern
| Channel | Mechanism |
|---|---|
| HTTP | Native request/response |
| MQ-based | ReplyTo + correlation_id; temp queue |
| Async + callback | Webhook URL + correlation |
| RPC over MQ | RabbitMQ RPC, NATS req/reply |
4. Designing Publish-Subscribe Pattern
| Component | Detail |
|---|---|
| Topic | Logical channel |
| Producer | Publishes events; doesn't know consumers |
| Consumer group | Parallel processing within group |
| Fan-out | Multiple groups → independent reads |
| Tools | Kafka, Pulsar, Redis Streams, GCP Pub/Sub |
5. Designing Event-Driven Communication
| Event Type | Use |
|---|---|
| Domain event | Past-tense fact (OrderPlaced) |
| Notification event | "Something happened, ask me for details" |
| State transfer | Includes entity snapshot |
| Command (event-like) | Async work request |
6. Designing Service Timeout Strategy
| Type | Recommendation |
|---|---|
| Connection timeout | 1–2s |
| Read timeout | p99 + buffer (often 1–3s) |
| Total request timeout | End-to-end budget |
| Cascading rule | Caller timeout < sum of callee budgets |
7. Designing Retry Policies with Exponential Backoff
Example: Exponential backoff with jitter
long base = 100, cap = 5000;
for (int i = 0; i < maxRetries; i++) {
try { return call(); }
catch (Transient e) {
long expo = Math.min(cap, base * (1L << i));
long sleep = ThreadLocalRandom.current().nextLong(0, expo); // full jitter
Thread.sleep(sleep);
}
}
throw new RetriesExceeded();
| Policy | Detail |
|---|---|
| Only retry transient | 5xx, timeout; not 4xx |
| Cap retries | 3–5 |
| Add jitter | Avoid thundering herd |
| Idempotency required | For non-GET |
8. Designing Circuit Breaker Architecture
| Param | Typical |
|---|---|
| Failure threshold | 50% over 20 reqs |
| Open duration | 30s |
| Half-open trial calls | 5 |
| Per-dependency | One breaker per downstream |
| Metrics | State changes, rejection count |
9. Designing Bulkhead Pattern
| Implementation | Detail |
|---|---|
| Thread pool isolation | Per dependency or tenant |
| Semaphore | Bound concurrent calls |
| Connection pool per upstream | One slow dep doesn't drain all |
| Pod isolation | Critical workloads on dedicated nodes |
10. Designing Service-to-Service Authentication
| Method | Detail |
|---|---|
| mTLS | SPIFFE/SPIRE, Istio auto-cert |
| Service JWT | Workload identity (OIDC) |
| API key | Static; rotate regularly |
| OAuth2 client credentials | Centralized issuer |
11. Designing Correlation ID Propagation
| Header | Purpose |
|---|---|
| traceparent (W3C) | Trace ID + parent span |
| tracestate | Vendor-specific |
| x-correlation-id | Business-level request id |
| Propagation | HTTP headers + MQ message attributes |
12. Designing Service Contracts
| Type | Tool |
|---|---|
| REST | OpenAPI 3.1 |
| gRPC | Protobuf .proto |
| Async/events | AsyncAPI + Schema Registry |
| Validation | Server-side validation + consumer-driven contracts |