FAQ-What’s the use of sending messages?
In distributed systems and backend development, the concept of "sending messages" frequently pops up. Beginners often wonder: if direct API calls can already get the job done, why introduce a seemingly roundabout message-passing mechanism? This article explores real-world scenarios to explain the core value and typical use cases of message-driven architectures.
"Sending messages" generally refers to applications passing data through message brokers (such as RabbitMQ, Kafka, or RocketMQ) rather than invoking each other's interfaces directly. The sender simply drops a message into a queue, and the receiver picks it up and processes it whenever it's ready.
This shift introduces two fundamental changes:
- Communication transforms from synchronous waiting to asynchronous delivery.
- Communicating parties move from tight direct coupling to indirect decoupling via queues.
1. Asynchronous Processing for Faster Response Times
Consider a standard user registration flow:
- Synchronous approach: The registration API must sequentially write to the database, send a welcome email, and send an SMS verification. The total latency is the sum of all three, forcing the user to stare at a loading screen.
- Messaging approach: The registration API only writes to the database and dispatches a "User Created" message. The email and SMS services consume this message asynchronously in the background, slashing the API response time.
2. System Decoupling to Lower Maintenance Costs
Imagine an e-commerce order system that needs to notify inventory, loyalty points, and logistics services whenever an order is placed. With direct API calls, any interface change or downtime in downstream services could break the core checkout flow.
By introducing a message queue, the order system only needs to broadcast a message. Downstream services can subscribe independently, meaning you can add or remove consumers without touching a single line of producer code.
3. Traffic Leveling to Protect Backend Services
During flash sales or high-traffic events, incoming request volumes can spike to dozens of times the normal baseline. If every request hits the database directly, the system will quickly collapse.
Message queues act as a buffer, forcing requests to line up. The backend can then pull messages at a steady, manageable pace, converting a destructive traffic spike into a smooth, predictable processing stream.
4. Data Distribution and Broadcasting
A single message can be consumed independently by multiple recipients. For example, an order creation event can be utilized simultaneously by data analytics, fraud detection, and recommendation systems, achieving "write once, consume everywhere."
A Quick Code Example
Here is a simplified pseudocode example of order creation using a message queue:
// Producer: Order Service
public void createOrder(Order order) {
orderDao.save(order); // Core operation
messageSender.send("order.created", JSON.toJSONString(order)); // Send message
}
// Consumer: Points Service
@RabbitListener(queues = "order.created")
public void onOrderCreated(String message) {
Order order = JSON.parseObject(message, Order.class);
pointService.addPoints(order.getUserId(), order.getAmount());
}
The order service doesn't care who consumes the message or when; both sides only need to agree on the message format. This is the essence of decoupling.
Important Trade-offs to Keep in Mind
While messaging is powerful, it is not a silver bullet. You should account for several challenges in practice:
- Message Loss: You must configure persistence and acknowledgement (ACK) mechanisms to guarantee reliable delivery.
- Duplicate Consumption: Network retries can cause duplicate messages, so consumers must implement idempotent logic.
- Ordering Constraints: If your business logic requires strict chronological processing, you need to choose solutions that support ordered messaging or partition keys carefully.
- Increased Complexity: Introducing a broker means managing another infrastructure component. For simple architectures, direct synchronous calls are often cleaner.
Common Message Broker Options
- RabbitMQ: Built on the AMQP protocol, feature-rich, and ideal for small-to-medium workloads.
- Kafka: High throughput with message replay capabilities, widely used for log aggregation and big data pipelines.
- RocketMQ: Strong support for transactional and ordered messages, tailored for e-commerce scenarios.
- Redis (List/Stream): Lightweight options suitable for lower-reliability requirements.
Summary
At its core, sending messages trades synchronous execution for system responsiveness, elasticity, and scalability. When dealing with asynchronous workflows, multi-system collaboration, or erratic traffic spikes, message queues provide an exceptionally high return on investment.
However, for straightforward, strongly consistent scenarios, direct calls remain the simplest approach. Understanding when and why to use messaging matters far more than just adopting it for the sake of it.