Synchronous Communication
Synchronous Communication
Synchronous communication blocks the caller until the response is received.
Characteristics
Synchronous Flow:
Client → Request → Server
Client ← Response ← Server
(blocks until response)
- Immediate response
- Tight coupling
- Simple to implement
- Latency = client latency
HTTP/REST
import requests
# Synchronous HTTP call
def get_user(user_id):
response = requests.get(f'http://api/users/{user_id}')
return response.json() # Blocks until response
# Timeouts
response = requests.get(url, timeout=5) # 5 second timeout
gRPC
import grpc
# Synchronous gRPC call
channel = grpc.insecure_channel('api:50051')
stub = UserServiceStub(channel)
# Blocks until response
user = stub.GetUser(GetUserRequest(id='123'))
When to Use
| Use Case | Why Sync |
|---|---|
| User queries | Need immediate response |
| CRUD operations | Simple request-response |
| Real-time data | Fresh data required |
| Low latency needs | No async overhead |
Downsides
- Blocks caller
- Cascading failures
- Timeout propagation
- No buffering
Asynchronous Communication
Asynchronous Communication
Asynchronous communication doesn't block the caller; response comes later.
Characteristics
Asynchronous Flow:
Client → Message → Queue → Server
Client ← Ack ← Queue
(continues immediately)
Server processes later
- Non-blocking
- Decoupled
- Buffered
- Eventual response
Message Queues
# Async with message queue
def create_order(order_data):
# Send to queue, don't wait
queue.send({
'type': 'order.created',
'data': order_data
})
# Return immediately
return {'status': 'processing'}
# Worker processes later
def process_order_worker():
while True:
message = queue.receive()
process_order(message['data'])
Event-Driven
# Event-based async
class EventBus:
def __init__(self):
self.subscribers = {}
def publish(self, event_type, data):
for subscriber in self.subscribers.get(event_type, []):
subscriber(data) # Async notification
def subscribe(self, event_type, handler):
if event_type not in self.subscribers:
self.subscribers[event_type] = []
self.subscribers[event_type].append(handler)
When to Use
| Use Case | Why Async |
|---|---|
| Long processing | Don't block user |
| Fire-and-forget | No response needed |
| Event broadcasting | Multiple consumers |
| High throughput | Buffer bursts |
Benefits
- Non-blocking
- Decoupled services
- Buffering
- Fault tolerance
Protocol Choices
Protocol Choices
Protocol Comparison
Protocol Options:
1. HTTP/REST:
- Simple, widely supported
- Text-based (JSON)
- Stateless
- Good for CRUD
2. gRPC:
- Binary (Protocol Buffers)
- HTTP/2 based
- Streaming support
- Strong typing
3. GraphQL:
- Query language
- Client specifies data
- Single endpoint
- Flexible
4. WebSocket:
- Full-duplex
- Real-time
- Persistent connection
- Low latency
5. Message Queue:
- Async
- Decoupled
- Buffered
- Reliable
Decision Matrix
| Factor | HTTP/REST | gRPC | GraphQL | WebSocket | MQ |
|---|---|---|---|---|---|
| Complexity | Low | Medium | Medium | Medium | High |
| Performance | Medium | High | Medium | High | High |
| Real-time | No | Yes | No | Yes | Yes |
| Type safety | No | Yes | Yes | No | No |
| Streaming | No | Yes | Yes | Yes | Yes |
When to Use Each
| Use Case | Protocol |
|---|---|
| Simple CRUD | REST |
| Internal services | gRPC |
| Flexible queries | GraphQL |
| Real-time updates | WebSocket |
| Async processing | Message Queue |
| High throughput | gRPC or MQ |
Protocol Selection
def choose_protocol(requirements):
if requirements['simple_crud']:
return 'REST'
if requirements['internal_communication']:
return 'gRPC'
if requirements['flexible_queries']:
return 'GraphQL'
if requirements['real_time']:
return 'WebSocket'
if requirements['async_processing']:
return 'Message Queue'
return 'REST' # Default
Practice Problems
Design a scalable Service Communication system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale Service Communication to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for Service Communication and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. What is synchronous communication?
2. What is the main advantage of asynchronous communication?
3. When should you use gRPC over REST?
4. What protocol is best for real-time updates?
5. Why use message queues for communication?
Flashcards
Question
Sync vs async communication?
Click to reveal answer
Answer
Sync: blocks until response (HTTP, gRPC). Async: non-blocking, uses queues (MQ, events).
Question
When use gRPC vs REST?
Click to reveal answer
Answer
gRPC: internal services, high performance, streaming. REST: simple CRUD, public APIs, wide support.
Question
When use WebSocket?
Click to reveal answer
Answer
Real-time bidirectional communication: chat, live updates, gaming, financial tickers
Question
When use message queues?
Click to reveal answer
Answer
Async processing, decoupling services, buffering traffic spikes, fault tolerance
Question
GraphQL vs REST?
Click to reveal answer
Answer
GraphQL: client specifies data, single endpoint, flexible. REST: multiple endpoints, simpler, cacheable.
Revision Notes
Key Takeaways
- 1.Synchronous blocks caller; asynchronous is non-blocking
- 2.Choose protocol based on requirements (REST, gRPC, GraphQL, WebSocket, MQ)
- 3.gRPC for internal services; REST for public APIs
- 4.Message queues for async processing and decoupling
- 5.WebSocket for real-time bidirectional communication
Interview Tips
- •Compare sync vs async trade-offs
- •Know when to use each protocol
- •Discuss cascading failures in sync communication
- •Mention message queues for decoupling
Cheat Sheet
Cheat Sheet: Service Communication
Sync Communication
- Blocks until response
- REST, gRPC
- Good for: CRUD, queries
- Con: Cascading failures
Async Communication
- Non-blocking
- Message queues, events
- Good for: Long processing, fire-and-forget
- Pro: Decoupled, buffered
Protocol Choices
- REST: Simple, public APIs
- gRPC: Internal, performance
- GraphQL: Flexible queries
- WebSocket: Real-time
- MQ: Async processing