服务间通信:同步调用、异步消息与事件驱动

引子:一次服务雪崩引发的思考 2020年双11凌晨2点,某电商平台订单服务突然不可用,导致用户无法下单。 故障链路: 用户下单 → 订单服务 → 库存服务(超时20秒) → 订单服务线程池耗尽 → 整个系统不可用 问题根源: 订单服务同步调用库存服务(HTTP请求) 库存服务压力大,响应慢(20秒超时) 订单服务线程池耗尽(200个线程全部阻塞) 新的订单请求无法处理,系统崩溃 架构师王明的反思: “同步调用的问题是什么?” “为什么不用异步消息?” “什么场景用同步,什么场景用异步?” 这个案例揭示了微服务通信的核心问题:如何选择合适的通信模式,平衡性能、可靠性、复杂度? 一、通信模式的本质:耦合度与可靠性的权衡 1.1 通信模式的两个维度 维度1:同步 vs 异步 维度 同步通信 异步通信 调用方式 请求→等待→响应 请求→立即返回→回调 阻塞性 调用方阻塞等待 调用方不阻塞 耦合度 强耦合(时间耦合) 弱耦合(时间解耦) 响应时间 快(毫秒级) 慢(秒级或分钟级) 可用性 低(被调用方挂了,调用方也挂) 高(被调用方挂了,消息不丢失) 复杂度 低(简单直接) 高(需要消息队列) 维度2:点对点 vs 发布订阅 维度 点对点(P2P) 发布订阅(Pub/Sub) 调用关系 一对一 一对多 耦合度 强耦合(空间耦合) 弱耦合(空间解耦) 扩展性 差(新增消费者要修改代码) 好(新增消费者不影响发布者) 典型场景 RPC调用 领域事件 1.2 耦合度的四个维度 1. 时间耦合(Temporal Coupling) ...

2025-11-03 · maneng

单线程模型:为什么Redis单线程却这么快?

引言 Redis是单线程的,却能达到10万+QPS,这听起来很矛盾。多线程不是更快吗?为什么Redis坚持单线程设计?单线程如何实现如此高的性能? 今天我们深入Redis的单线程模型,揭秘高性能背后的设计哲学。 一、Redis真的是单线程吗? 1.1 核心工作线程确实是单线程 准确的说法: Redis的核心数据处理逻辑是单线程的(主线程处理所有客户端请求) 客户端1 \ 客户端2 → [主线程] → 串行执行命令 客户端3 / 单线程处理的内容: 接收客户端连接 读取请求命令 执行命令(操作数据结构) 返回响应 处理定时任务 1.2 但Redis不是完全单线程 Redis 4.0+引入多线程(后台线程): 版本 多线程功能 用途 Redis 4.0+ 后台异步删除线程(unlink、flushdb async) 避免删除大key阻塞 Redis 4.0+ AOF重写线程 后台重写AOF文件 Redis 6.0+ I/O多线程 多线程读取请求、发送响应(数据处理仍是单线程) 关键点: 数据操作:仍然是单线程(避免锁的开销) I/O操作:Redis 6.0+支持多线程(提高网络吞吐) 后台任务:多线程(避免阻塞主线程) 二、为什么选择单线程? 2.1 多线程的问题 问题1:锁的开销 // 多线程环境 void increment_counter() { pthread_mutex_lock(&mutex); // 加锁,耗时约25ns counter++; // 操作,耗时1ns pthread_mutex_unlock(&mutex); // 解锁,耗时25ns } // 总耗时:50ns(锁开销占98%) // 单线程环境 void increment_counter() { counter++; // 直接操作,1ns } // 无锁开销! 结论:对于内存操作(纳秒级),锁的开销反而成为瓶颈。 ...

2025-01-21 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...