同步与异步通信对比
同步通信(如 HTTP/RPC)和异步通信(如消息队列)是分布式系统中两种核心的服务间交互方式。
同步通信(RPC)
模型:调用方发送请求后阻塞等待,直到被调用方返回结果。
Java
服务A ──[请求]──> 服务B ──[处理]──> 数据库
│ │
│<─[等待响应]──────┤
└─[返回结果]
代码示例(HTTP 同步调用):
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class SyncRpcExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8080/api/order"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"id\": 1001}"))
.build();
// 阻塞等待响应
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("响应状态: " + response.statusCode());
System.out.println("响应内容: " + response.body());
}
}
特点:
- 调用链路清晰,调试方便
- 实时返回,调用方可立即获得结果
- 调用方与被调用方强耦合,任一节点故障影响整体
异步通信(消息队列)
模型:发送方将消息放入队列后立即返回,接收方在后续时间点独立处理。
text
服务A ──[发送消息]──> [消息队列] ──[推送]──> 服务B
│ │ │
└─[立即返回] │ └─[独立处理]
│
└──> 服务C(同时消费)
代码示例(RabbitMQ 异步发送):
text
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class AsyncMqExample {
private static final String QUEUE = "order.async.queue";
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(QUEUE, true, false, false, null);
String message = "{\"orderId\": 1001, \"action\": \"process\"}";
// 发送后立即返回,不等待消费者处理
channel.basicPublish("", QUEUE, null, message.getBytes("UTF-8"));
System.out.println("消息已发送,主流程继续执行");
}
}
}
特点:
- 发送方与接收方解耦,可独立扩展
- 发送方无需等待,响应速度快
- 消息可能被延迟处理,非实时
核心对比
| 对比维度 | 同步 RPC | 异步消息队列 |
|---|---|---|
| 调用方式 | 阻塞等待 | 发送即返回 |
| 耦合度 | 强耦合(直接调用) | 松耦合(通过队列) |
| 实时性 | 高(毫秒级响应) | 低(取决于消费速度) |
| 可用性 | 被调用方故障直接影响 | 消息堆积,后续可补消费 |
| 扩展性 | 需协调调用链路 | 消费者独立扩展 |
| 调试难度 | 低(调用链清晰) | 高(消息流转不直观) |
| 适用场景 | 需立即获取结果的操作 | 可延迟处理、需解耦的操作 |
场景选择
选同步 RPC:
- 用户登录验证(需立即返回成功/失败)
- 查询操作(需实时获取数据)
- 简单调用链(2-3个服务以内)
选异步消息队列:
- 订单创建后发邮件/短信(无需等待)
- 日志采集与聚合(可批量处理)
- 服务间解耦(多对多调用关系)
同步调用总耗时 = 所有下游服务耗时之和;异步调用主链路耗时 = 自身处理耗时。
异步通信需额外考虑消息丢失、重复消费、顺序错乱等问题。
要点总结
- 同步 RPC:阻塞等待、实时响应、强耦合,适合需立即返回结果的场景
- 异步消息队列:发送即返回、解耦双方、适合可延迟处理的场景
- 选型核心:是否需要实时结果、系统耦合度、可接受的延迟范围
- 异步通信的代价:复杂度提升、调试困难、需处理消息可靠性问题
📝 发现内容有误?点击此处直接编辑