互联网架构八大维度最佳实践
互联网架构八大维度最佳实践 #
高可用、高性能、高并发、可扩展、容灾容错、安全可靠、可观测性、限流熔断降级!所有中间件底层原理完全通用!
📋 目录 #
一、开篇:八大维度,一套技术池 ⭐⭐⭐⭐⭐ #
核心观点:八大维度,一套通用技术池! #
八大维度全景表 #
| 维度 | 核心目标 | 关键技术 |
|---|---|---|
| 高性能 | 快响应、高吞吐 | IO多路复用、缓存、分片、批量处理 |
| 高可用 | 少宕机、自动恢复 | 集群、副本、选举、故障转移 |
| 高并发 | 扛流量、不崩溃 | 异步、线程池、队列、削峰填谷 |
| 可扩展 | 易扩容、弹性伸缩 | 无状态、微服务、水平扩展 |
| 容灾容错 | 灾难恢复、故障隔离 | 多活、备份、降级、演练 |
| 安全可靠 | 安全合规、数据可信 | 鉴权、加密、防攻击、审计 |
| 可观测性 | 可监控、可排查、可分析 | 日志、监控、链路追踪 |
| 限流熔断降级 | 保护系统、防雪崩 | 限流、熔断、降级、热点保护 |
结论: 所有中间件做这八大维度,本质都是同一套通用技术池!
一图览:各中间件技术映射表 #
| 通用技术 | Redis | MySQL | Kafka/RocketMQ | ElasticSearch | Nacos |
|---|---|---|---|---|---|
| 高性能 | |||||
| IO多路复用 | ✅ epoll | ✅ | ✅ | ✅ | ✅ |
| 内存缓存 | ✅ 内存数据库 | ✅ Buffer Pool | ✅ Page Cache | ✅ 堆外内存 | ✅ 本地缓存 |
| 数据分片 | ✅ Redis Cluster | ✅ 分库分表 | ✅ Partition | ✅ Shard | ✅ 分片集群 |
| 批量处理 | ✅ Pipeline | ✅ 批量写入 | ✅ 批量发送 | ✅ Bulk API | ✅ 批量通知 |
| 零拷贝 | ✅ | ✅ SendFile | ✅ SendFile | ✅ | |
| 高可用 | |||||
| 集群化 | ✅ Sentinel/Cluster | ✅ MGR | ✅ 集群 | ✅ ES集群 | ✅ 集群 |
| 主从副本 | ✅ 主从复制 | ✅ 主从复制 | ✅ ISR副本 | ✅ 主副分片 | ✅ |
| 心跳检测 | ✅ Sentinel | ✅ | ✅ | ✅ | ✅ |
| 领导者选举 | ✅ Sentinel | ✅ MGR | ✅ Controller | ✅ Master | ✅ Raft |
| 故障转移 | ✅ 自动切换 | ✅ | ✅ 重平衡 | ✅ | ✅ |
| 数据持久化 | ✅ RDB/AOF | ✅ Binlog/Redo | ✅ 刷盘 | ✅ Translog | ✅ Derby/MySQL |
学习方法:先通原理,再看具体 #
第一步:理解通用技术池 ← 掌握核心
↓
第二步:看某中间件如何应用这些技术 ← 举一反三
↓
第三步:对比其他中间件 ← 发现都是同一套
↓
第四步:融会贯通,任意中间件手到擒来
二、高性能篇 #
2.1 通用高性能技术池 ⭐⭐⭐⭐⭐ #
2.1.1 IO多路复用 + 非阻塞异步模型 #
原理:
- 一个线程/少数线程处理成千上万连接
- 非阻塞IO,不等待
- 事件驱动:有数据来了才处理
对比:
| 模式 | 线程数 | 连接数 | 适用场景 |
|---|---|---|---|
| 阻塞IO | 1连接1线程 | 几百 | 传统 |
| IO多路复用 | 少量线程 | 数万+ | Redis/Kafka/Nginx/Netty |
各中间件应用:
| 中间件 | 实现 |
|---|---|
| Redis | epoll 单线程(命令执行) |
| Kafka | Java NIO,epoll |
| Netty | Reactor模式 |
| Nginx | epoll |
2.1.2 内存缓存,减少磁盘/网络IO #
**思想:
请求 → 内存缓存 → 命中直接返回
↓ 未命中
磁盘/网络 → 回源 → 写入缓存
各中间件应用:
| 中间件 | 缓存实现 | 效果 |
|---|---|---|
| Redis | 本身就是内存数据库 | 纳秒级访问 |
| MySQL | Buffer Pool | 减少磁盘IO |
| Kafka | Page Cache | 零拷贝传输 |
| ES | File System Cache | 缓存倒排索引 |
| Nacos | 本地缓存 | 减少远程调用 |
2.1.3 数据分片,拆分压力 #
**分片方式:
- 范围分片: id 1-100万 → 分片1,100-200万 → 分片2
- 哈希分片: hash(key) % N
- 一致性哈希: 减少扩容迁移
各中间件分片对比:
| 中间件 | 分片方式 | 说明 |
|---|---|---|
| Redis Cluster | 哈希槽 16384 | CRC16(key) % 16384 |
| MySQL分库分表 | 范围/哈希 | 按user_id分库 |
| Kafka | Partition | key哈希/轮询 |
| ES | Shard | 哈希 |
2.1.4 批量处理 + 合并请求 #
思想:
普通: 1000次请求 → 1000次网络往返
批量: 1000次请求 → 合并1次 → 批量执行
**优势:减少网络IO,提升吞吐量
各中间件批量操作:
| 中间件 | 批量方式 |
|---|---|
| Redis | Pipeline、MGET/MSET |
| MySQL | 批量INSERT/UPDATE |
| Kafka | batch.size配置 |
| ES | Bulk API |
| RocketMQ | 批量发送 |
2.1.5 零拷贝,减少数据拷贝开销 #
零拷贝方式:
- sendfile: Linux系统调用
- mmap: 内存映射
各中间件零拷贝应用:
| 中间件 | 零拷贝方式 |
|---|---|
| Kafka | sendfile传输 |
| RocketMQ | mmap |
| Netty | FileRegion |
| Nginx | sendfile on |
2.1.6 连接池复用,减少频繁创建销毁 #
传统方式:
连接创建 → 使用 → 销毁 → 创建 → 开销大
连接池方式:
连接池[连接1, 连接2, 连接3...] → 复用
连接池核心参数:
- 最大连接数: maxTotal
- 最小空闲数: minIdle
- 获取超时时间: maxWaitMillis
各中间件连接池:
| 中间件 | 连接池实现 |
|---|---|
| Redis | JedisPool/Lettuce |
| MySQL | HikariCP/Druid |
| Kafka | 生产者池 |
| HTTP | HttpClient/OkHttp |
2.1.7 本地缓存兜底,减少远程调用 #
应用本地缓存(Caffeine/Guava Cache)
↓ 未命中
远程调用
↓
Redis
↓
更新本地缓存
适用场景:
- 配置数据、字典数据、不常变的数据
2.2 Redis高性能实践 #
2.2.1 单线程模型 + IO多路复用 #
为什么单线程还快?
- 纯内存操作,纳秒级
- 避免上下文切换开销
- 避免锁竞争
- IO多路复用处理网络
Redis 6.0 多线程IO:
- 网络读写:多线程
- 命令执行:还是单线程
- 提升网络处理能力
2.2.2 内存数据结构优化 #
| 数据结构 | 编码优化 | 场景 |
|---|---|---|
| String | int/embstr/raw | 小整数用int 短字符串embstr 长字符串raw |
| Hash | ziplist/hashtable | 元素少时用ziplist |
| List | quicklist | 压缩列表 + 双向链表 |
| Set | intset/hashtable | 整数集合 |
| ZSet | ziplist/skiplist | 元素少时ziplist |
2.2.3 Pipeline批量操作 #
// 普通方式:1000次RTT
for (int i = 0; i < 1000; i++) {
redis.set("key" + i, "value" + i);
}
// Pipeline方式:1次RTT
Pipeline pipeline = redis.pipelined();
for (int i = 0; i < 1000; i++) {
pipeline.set("key" + i, "value" + i);
}
pipeline.sync();
性能提升:10倍 ~ 100倍
2.2.4 分片集群(Redis Cluster) #
关键点:
- 16384个哈希槽
- 每个节点负责一部分槽
- 客户端直接连接节点(MOVED重定向)
2.3 MySQL高性能实践 #
2.3.1 索引优化 #
B+树索引:
索引设计原则:
- 最左前缀匹配
- 区分度高的列放前面
- 避免索引失效(函数、隐式转换、范围查询后列失效)
- 覆盖索引(避免回表)
2.3.2 读写分离 #
中间件:
- ShardingSphere
- MyCat
- Sharding-JDBC
2.3.3 分库分表(分片) #
分片策略:
- 垂直拆分: 按业务拆分库,订单库、用户库
- 水平拆分: 按数据量拆分,user_001、user_002
分片键选择:
- 查询条件多的列(user_id)
- 区分度高
分片算法:
- hash取模
- 范围分片
- 地理位置分片
2.3.4 连接池配置(HikariCP) #
spring:
datasource:
hikari:
maximum-pool-size: 20 # 最大连接数
minimum-idle: 10 # 最小空闲连接
connection-timeout: 30000 # 连接超时
idle-timeout: 600000 # 空闲连接超时
max-lifetime: 1800000 # 连接最大存活时间
2.4 Kafka/RocketMQ高性能实践 #
2.4.1 顺序写 + 零拷贝 #
顺序写: 文件系统优化:
- 只追加写,不修改
- 磁盘顺序写性能 ≈ 内存随机写
2.4.2 批量发送 + 压缩 #
// Kafka生产者配置
Properties props = new Properties();
props.put("batch.size", 16384); // 批量大小
props.put("linger.ms", 10); // 等待时间
props.put("compression.type", "lz4"); // 压缩
props.put("buffer.memory", 33554432); // 缓冲区大小
压缩算法对比:
| 算法 | 压缩率 | CPU | 推荐 |
|---|---|---|---|
| gzip | 高 | 高 | - |
| snappy | 中 | 中 | ✅ |
| lz4 | 低 | 低 | ✅✅ |
| zstd | 高 | 中 | ✅ |
2.4.3 分区并行消费 #
并行度:
- 分区数 = 最大并行消费数
- 消费者数 ≤ 分区数
2.4.4 内存消息队列 #
RocketMQ内存映射:
CommitLog → mmap内存映射
↑
直接操作文件
2.5 ElasticSearch高性能实践 #
2.5.1 分片设计 #
分片数规划:
- 每个分片数据量建议:20-40GB
- 分片数 ≈ (预计数据量 / 30GB)
- 主分片数创建后不能改,副本分片可以
路由策略:
- 默认:hash(id) % 主分片数
2.5.2 索引优化 #
| 优化项 | 方案 |
|---|---|
| 分片数 | 合理规划,不要太多 |
| 副本数 | 查询多副本提升读 |
| 刷新间隔 | refresh_interval: 30s |
| 分词器 | 选择合适的分词器 |
| 索引模板 | 冷热分离 |
| 批量操作 | Bulk API |
2.5.3 批量操作(Bulk API) #
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new IndexRequest("index").source(doc1));
bulkRequest.add(new IndexRequest("index").source(doc2));
bulkRequest.add(new IndexRequest("index").source(doc3));
bulkRequest.add(new IndexRequest("index").source(doc4));
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
2.5.4 缓存策略 #
- Filesystem Cache: 操作系统缓存
- Node Query Cache: 节点查询缓存
- Shard Request Cache: 分片请求缓存
- Field Data Cache: 字段数据缓存
2.6 Nacos高性能实践 #
2.6.1 集群分片 #
2.6.2 本地缓存 #
客户端本地缓存
↓
监听变更
↓
定时拉取
2.6.3 异步通知 #
配置变更 → 服务端 → UDP推送 → 客户端
三、高可用篇 #
3.1 通用高可用技术池 ⭐⭐⭐⭐⭐ #
3.1.1 集群化部署(多节点) #
集群类型:
- 主从集群: 一主多从
- 对等集群: 多主多从
- 分片集群: 数据分片 + 每个分片主从
3.1.2 主从/副本机制(数据备份) #
复制方式:
- 同步复制: 强一致,性能低
- 异步复制: 高性能,可能丢数据
- 半同步复制: 折中方案
3.1.3 心跳检测 + 健康检查 #
节点A →→→ 心跳 →→→ 节点B
↓
定时发送心跳
↓
超时 → 判断节点故障
检测方式:
- TCP端口检测
- HTTP接口检测
- 应用层心跳
3.1.4 领导者选举(选主) #
选举算法:
- Raft: 容易理解,应用广泛
- Paxos: 复杂,可靠
- ZAB: Zookeeper专用
- Raft应用: Nacos, Redis Sentinel, etcd
3.1.5 故障自动转移 #
关键指标:
- 自动发现故障
- 快速切换
- 客户端自动发现新地址
3.1.6 数据持久化 #
持久化方式:
- 快照: 全量
- 日志: 增量
- 混合: 快照 + 日志
3.1.7 降级兜底 #
请求 → 正常流程
↓ 故障
降级 → 降级返回默认值/缓存数据
3.2 Redis高可用实践 #
3.2.1 主从复制 #
复制流程:
- Slave发送SYNC
- Master执行BGSAVE生成RDB
- Master发送RDB给Slave
- Slave加载RDB
- 增量同步传播命令
3.2.2 Sentinel哨兵 ⭐⭐⭐⭐⭐ #
Sentinel功能:
- 监控:检查主从健康
- 通知:告警
- 故障转移:自动选主
- 配置中心:客户端获取主节点地址
**哨兵数量:建议3/5/7(奇数,防脑裂)
3.2.3 Redis Cluster集群 #
特点:
- 去中心化,每个节点负责部分槽
- 每个主节点有从节点
- 自动故障转移
3.2.4 持久化策略 #
| 策略 | 说明 | 适用场景 |
|---|---|---|
| RDB | 内存快照 | 备份、灾难恢复 |
| AOF | 追加日志 | 数据安全 |
| 混合 | RDB+AOF | 推荐✅ |
# 混合持久化配置
aof-use-rdb-preamble yes
3.3 MySQL高可用实践 #
3.3.1 主从复制 + 读写分离 #
复制方式:
- 异步复制: 默认
- 半同步复制: after_sync/after_commit
- 组复制MGR: Paxos
3.3.2 MGR(Group Replication) #
特点:
- 多主模式:任意节点写
- 单主模式:选主
- 自动故障检测和转移
- 基于Paxos
3.3.3 分库分表高可用 #
每个分库主从
↓
分库高可用
3.3.4 数据备份策略 #
| 备份类型 | 说明 | 频率 |
|---|---|---|
| 全量备份 | xtrabackup | 每天/每周 |
| 增量备份 | binlog | 实时 |
| 延时从库 | 延迟同步 | 误删恢复 |
3.4 Kafka/RocketMQ高可用实践 #
3.4.1 副本机制(ISR)⭐⭐⭐⭐⭐ #
ISR: In-Sync Replicas 同步副本列表
- Leader维护ISR列表
- 同步慢的Follower踢出ISR
- 只有ISR中的副本能被选为Leader
3.4.2 控制器选举 #
选举:
- 基于Zookeeper/KRaft
- 选举出1个Controller
- Controller负责管理分区和副本
3.4.3 故障转移 #
分区Leader故障
↓
Controller从ISR选新Leader
↓
客户端切换到新Leader
3.4.4 消息可靠性保证 #
| 级别 | 说明 | 性能 |
|---|---|---|
| 最多一次 | at most once | 高 |
| 至少一次 | at least once | 中 |
| 精确一次 | exactly once | 低 |
配置:
acks=all # 所有ISR确认
retries=3 # 重试
enable.idempotence=true # 幂等
3.5 ElasticSearch高可用实践 #
3.5.1 主分片 + 副本分片 #
P: Primary 主分片 R: Replica 副本分片
3.5.2 集群脑裂预防 #
discovery.zen.minimum_master_nodes: 2 # (master_eligible_nodes / 2) + 1
防止脑裂:
- 候选主节点 ≥ 3
- minimum_master_nodes设置为2
- 多数原则
3.5.3 自动发现 #
集群自动发现节点
↓
加入集群
3.6 Nacos高可用实践 #
3.6.1 集群部署 #
3.6.2 Raft选举 #
Raft一致性算法
↓
选Leader
↓
数据同步
3.6.3 数据持久化 #
- 嵌入式数据库: Derby
- 外置数据库: MySQL
3.6.4 健康检查 #
节点间健康检查
↓
故障踢出
四、高并发篇 ⭐⭐⭐⭐⭐ #
4.1 通用高并发技术池 #
4.1.1 异步化处理:削峰填谷 #
异步方式:
- MQ异步:Kafka、RocketMQ
- 线程池异步:CompletableFuture
- 事件驱动:Spring Event
4.1.2 线程池管理:资源可控 #
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, // 核心线程数
50, // 最大线程数
60L, TimeUnit.SECONDS, // 空闲线程存活时间
new LinkedBlockingQueue<>(200), // 等待队列
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
线程池参数设计:
| 参数 | 说明 | 建议值 |
|---|---|---|
| corePoolSize | 核心线程数 | CPU密集型:N+1 IO密集型:2N |
| maximumPoolSize | 最大线程数 | 核心数的2~5倍 |
| workQueue | 等待队列 | LinkedBlockingQueue、ArrayBlockingQueue |
| handler | 拒绝策略 | CallerRunsPolicy、AbortPolicy |
4.1.3 队列缓冲:削峰填谷 #
队列选型:
| 队列 | 适用场景 |
|---|---|
| Kafka/RocketMQ | 分布式、高吞吐、可靠 |
| Disruptor | 单机高性能、无锁 |
| ThreadPool Queue | 应用内缓冲 |
4.1.4 资源隔离:故障隔离 #
隔离方式:
- 线程池隔离:不同服务不同线程池
- 信号量隔离:Semaphore
- 队列隔离:不同队列不同业务
4.2 各中间件高并发实践 #
4.2.1 Kafka高并发消费 #
Partition-0 --> Consumer-1
Partition-1 --> Consumer-2
Partition-2 --> Consumer-3
并发度 = 分区数,一对一消费
4.2.2 Redis高并发设计 #
- Pipeline批量操作
- 无锁设计:单线程模型
- 热点Key打散:key1,key2,key3...
4.2.3 数据库连接池 #
HikariCP、Druid连接池管理
五、可扩展篇 ⭐⭐⭐ #
5.1 通用可扩展技术 #
5.1.1 无状态服务 #
请求 --> 负载均衡 --> N个无状态服务节点
每个节点完全对等,可随时扩缩容
状态外置:
- Session存Redis
- 配置存Nacos/Config
- 数据存DB/缓存
5.1.2 水平扩展 vs 垂直扩展 #
| 对比项 | 水平扩展 | 垂直扩展 |
|---|---|---|
| 方式 | 加机器 | 升级配置 |
| 成本 | 线性增长 | 指数增长 |
| 上限 | 高 | 低 |
| 推荐 | ✅ | ❌ |
5.1.3 微服务化:按业务拆分 #
单体应用 → 用户服务、商品服务、订单服务、支付服务
每个服务独立部署、独立扩展
5.2 各中间件扩展性设计 #
5.2.1 Redis Cluster 分片扩展 #
自动分片,槽迁移
5.2.2 Kafka 分区扩展 #
增加分区,提高并行度
5.2.3 ES 索引拆分 #
按时间、按业务拆分索引
六、容灾容错篇 ⭐⭐⭐ #
6.1 通用容灾容错技术 #
6.1.1 多活架构 #
6.1.2 备份策略 #
| 备份类型 | 说明 | 频率 |
|---|---|---|
| 全量备份 | xtrabackup | 每日 |
| 增量备份 | binlog | 实时 |
| 延时从库 | 延迟同步 | 误删恢复 |
6.1.3 故障演练 #
- 混沌工程:Kill Pod、模拟网络延迟
- 定期演练:每月一次
- 恢复时长目标:RTO、RPO
6.2 各中间件容灾方案 #
6.2.1 Redis 跨机房部署 #
主从跨机房、Sentinel跨机房
6.2.2 MySQL 异地灾备 #
主从异地、半同步复制
6.2.3 Kafka 多副本跨可用区 #
副本分布在不同AZ
七、安全可靠篇 ⭐⭐ #
7.1 通用安全技术 #
7.1.1 认证鉴权 #
请求 → Token验证 → 权限校验 → 通过/拒绝
> 🔒 账号信息已隐藏(仅本地笔记可见)
应用日志 --> ELK/Loki --> 检索分析
- 日志级别:ERROR、WARN、INFO、DEBUG
- 结构化日志:JSON格式
8.1.2 监控 Metrics #
关键指标:
- 应用:QPS、RT、错误率
- 系统:CPU、内存、磁盘、网络
- 中间件:Redis连接数、Kafka堆积、MySQL慢查询
8.1.3 链路追踪 Tracing #
- TraceID:唯一追踪整个链路
- Span:每个服务节点的处理
- Jaeger/Skywalking:分布式追踪工具
8.2 各中间件可观测性 #
8.2.1 Redis 监控 #
- INFO stats
- 慢查询日志 slowlog
- 连接数、命中率、key过期
8.2.2 MySQL 监控 #
- 慢查询 slow_log
- 连接数、QPS
- InnoDB状态
8.2.3 Kafka 监控 #
- 消息堆积量
- 生产/消费TPS
- 副本同步状态
九、限流熔断降级篇 ⭐⭐⭐⭐⭐ #
9.1 限流 #
9.1.1 限流算法 #
| 算法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 固定窗口 | 单位时间计数 | 简单 | 边界突刺 |
| 滑动窗口 | 窗口滑动 | 平滑 | 实现复杂 |
| 令牌桶 | 固定速率放令牌 | 允许突发 | 预热问题 |
| 漏桶 | 固定速率流出 | 强制平滑 | 突发流量处理差 |
9.1.2 Sentinel 限流 #
@SentinelResource(value = "resource", blockHandler = "handleBlock")
public void doSomething() {
// 业务逻辑
}
public void handleBlock(BlockException e) {
// 限流处理
}
限流规则配置:
- QPS限流
- 并发数限流
- 热点参数限流
9.2 熔断器 #
9.2.1 熔断器三种状态 #
9.2.2 Sentinel 熔断降级 #
@SentinelResource(fallback = "handleFallback")
public String doSomething() {
// 可能会失败的调用
}
public String handleFallback(Throwable e) {
// 降级逻辑
}
9.3 降级 #
9.3.1 降级策略 #
| 策略 | 说明 |
|---|---|
| 快速失败 | 直接返回错误 |
| 返回默认值 | 返回默认数据 |
| 返回缓存 | 读本地缓存 |
| 降级处理 | 走简化流程 |
9.4 各中间件限流保护 #
9.4.1 Redis 热点Key防护 #
- 本地缓存
- Key打散
- 互斥锁
9.4.2 Nginx 限流 #
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
9.4.3 网关限流 #
Spring Cloud Gateway + Sentinel
十、分布式三板斧综合应用 ⭐⭐⭐⭐⭐ #
4.1 分片(提升性能) #
4.1.1 各中间件分片对比 #
| 中间件 | 分片名称 | 分片方式 |
|---|---|---|
| Redis Cluster | 槽Slot | CRC16(key)%16384 |
| MySQL | 分库分表 | hash/范围 |
| Kafka | Partition | hash/轮询 |
| ES | Shard | hash(id) |
| Nacos | 数据分片 | 一致性哈希 |
4.1.2 Redis Cluster槽分片 #
重平衡: 自动迁移槽,负载均衡
4.1.3 MySQL分库分表 #
分片键: user_id
4.1.4 Kafka分区 #
4.1.5 ES分片 #
4.2 副本(保证可用) #
4.2.1 各中间件副本对比 #
| 中间件 | 副本名称 | 副本作用 |
|---|---|---|
| Redis | 主从复制 | 读写分离、容灾 |
| MySQL | 主从复制 | 读写分离、容灾 |
| Kafka | ISR副本 | 高可用、消息可靠 |
| ES | Replica Shard | 高可用、读扩展 |
4.2.2 Redis主从 #
4.2.3 MySQL主从 #
4.2.4 Kafka ISR副本 #
4.2.5 ES副本 #
P0(主) + R0(副)
4.3 选举(故障自愈) #
4.3.1 各中间件选举对比 #
| 中间件 | 选举算法 | 选举场景 |
|---|---|---|
| Redis Sentinel | Raft-like | 主从故障 |
| Redis Cluster | Gossip | 主从故障 |
| Kafka | KRaft/ZK | Controller选举、Leader选举 |
| ES | Zen Discovery | Master选举 |
| Nacos | Raft | Leader选举 |
| Zookeeper | ZAB | Leader选举 |
4.3.2 Redis Sentinel #
Sentinel集群
↓
监控Master
↓
Master故障
↓
Sentinel投票选Leader Sentinel
↓
选最优Slave升Master
4.3.3 Kafka控制器 #
Broker启动
↓
竞争Controller
↓
选出1个Controller
↓
管理分区副本
4.3.4 ES主节点 #
候选主节点
↓
选举Master
↓
管理集群元数据
4.3.5 Nacos Raft #
Nacos集群
↓
Raft选Leader
↓
Leader处理写
↓
Follower同步
十、实战案例 #
10.1 秒杀系统:八大维度全覆盖 ⭐⭐⭐⭐⭐ #
八大维度整体设计 #
八大维度全覆盖方案 #
| 维度 | 方案 |
|---|---|
| 高性能 | Redis预扣库存、Lua脚本、批量操作 |
| 高可用 | Redis主从哨兵、MySQL主从、MQ集群 |
| 高并发 | MQ异步削峰、线程池、资源隔离 |
| 可扩展 | 无状态服务、可水平扩容 |
| 容灾容错 | 多机房部署、数据备份 |
| 安全可靠 | WAF、鉴权、防刷 |
| 可观测性 | 全链路监控、日志、告警 |
| 限流熔断降级 | 网关限流、Sentinel熔断降级 |
10.2 实时计算平台:Kafka + Flink #
架构 #
高性能 & 高可用 #
- Kafka分区并行、副本机制
- Flink算子链、Checkpoint、Exactly-Once
10.3 多活机房架构设计 #
方案要点(容灾容错) #
- 单元化架构
- 数据双向同步
- 流量路由
- 故障切换
10.4 限流熔断降级实战 #
限流降级方案 #
| 限流算法 | 说明 |
|---|---|
| 固定窗口 | 简单,突刺 |
| 滑动窗口 | 平滑 |
| 令牌桶 | 允许突发 |
| 漏桶 | 强制平滑 |
Sentinel配置示例 #
@SentinelResource(
value = "seckill",
blockHandler = "handleBlock",
fallback = "handleFallback"
)
public String seckill(Long productId) {
// 秒杀逻辑
}
public String handleBlock(Long productId, BlockException e) {
return "限流了,请稍后再试";
}
public String handleFallback(Long productId, Throwable e) {
return "降级了,返回默认值";
}
十一、面试题汇总与答案 #
通用原理题 #
1. 互联网架构八大维度是什么?核心思想是什么? #
答案:
| 维度 | 核心目标 | 说明 |
|---|---|---|
| 高性能 | 快响应、高吞吐 | IO多路复用、缓存、分片 |
| 高可用 | 少宕机、自动恢复 | 集群、副本、故障转移 |
| 高并发 | 扛流量、不崩溃 | 异步、线程池、队列 |
| 可扩展 | 易扩容、弹性伸缩 | 无状态、水平扩展 |
| 容灾容错 | 灾难恢复、故障隔离 | 多活、备份、降级 |
| 安全可靠 | 安全合规、数据可信 | 鉴权、加密、防攻击 |
| 可观测性 | 可监控、可排查 | 日志、监控、链路追踪 |
| 限流熔断降级 | 保护系统、防雪崩 | 限流、熔断、降级 |
核心思想:所有中间件做这八大维度,本质都是同一套通用技术池!
2. 什么是分布式三板斧?分别解决什么问题? #
答案:
| 三板斧 | 解决问题 | 说明 |
|---|---|---|
| 分片 | 性能 | 数据拆分压力,水平扩展 |
| 副本 | 可用性 | 数据备份,高可用 |
| 选举 | 自愈 | 故障自动转移 |
Redis面试题 #
3. Redis为什么这么快? #
答案:
| 原因 | 说明 |
|---|---|
| 纯内存 | 纳秒级访问 |
| 单线程 | 避免上下文切换和锁 |
| IO多路复用 | epoll处理网络 |
| 高效数据结构 | 跳表、SDS等 |
| Redis 6.0 | 多线程IO提升网络 |
4. Redis高可用方案有哪些? #
答案:
| 方案 | 说明 | 适用场景 |
|---|---|---|
| 主从复制 | 一主多从,读写分离 | 备份、读扩展 |
| Sentinel哨兵 | 监控 + 故障转移 | 高可用 |
| Redis Cluster | 分片 + 高可用 | 大规模 |
MySQL面试题 #
5. MySQL高性能优化有哪些方案? #
答案:
| 层级 | 方案 |
|---|---|
| 索引 | B+树索引、覆盖索引、最左前缀 |
| 架构 | 读写分离、分库分表 |
| SQL | 慢查询优化、批量操作 |
| 配置 | Buffer Pool、连接池 |
6. MySQL高可用方案有哪些? #
答案:
| 方案 | 说明 |
|---|---|
| 主从复制 | 读写分离、备份 |
| 半同步复制 | 数据更可靠 |
| MGR组复制 | 多主、自动故障转移 |
MQ面试题 #
7. Kafka为什么这么快? #
答案:
| 原因 | 说明 |
|---|---|
| 顺序写 | 磁盘顺序写 ≈ 内存 |
| 零拷贝 | sendfile |
| 批量发送 | 减少网络 |
| 分区并行 | 提高并行度 |
| Page Cache | 利用系统缓存 |
8. Kafka如何保证消息可靠性? #
答案:
| 级别 | 配置 |
|---|---|
| 最多一次 | acks=0 |
| 至少一次 | acks=all + 重试 |
| 精确一次 | 幂等 + 事务 |
ES面试题 #
9. ES如何保证高可用? #
答案:
- 主分片 + 副本分片
- 副本不与主分片同节点
- 集群脑裂预防
minimum_master_nodes - 自动发现
Nacos面试题 #
10. Nacos高可用原理? #
答案:
- 集群部署(3/5/7节点)
- Raft一致性算法选Leader
- 数据持久化(Derby/MySQL)
- 健康检查,故障自动剔除
高并发面试题 #
11. 如何设计高并发系统? #
答案:
| 维度 | 方案 |
|---|---|
| 异步化 | MQ削峰填谷 |
| 线程池 | 资源隔离 |
| 缓存 | 减少DB/网络访问 |
| 队列 | 缓冲突发流量 |
| 分片 | 分散压力 |
12. 线程池参数如何设置?拒绝策略有哪些? #
答案:
核心参数:
| 参数 | 说明 | 建议值 |
|---|---|---|
| corePoolSize | 核心线程数 | CPU密集型:N+1 IO密集型:2N |
| maximumPoolSize | 最大线程数 | 核心数的2~5倍 |
拒绝策略:
| 策略 | 说明 |
|---|---|
| AbortPolicy | 直接抛异常 |
| CallerRunsPolicy | 调用者线程执行 |
| DiscardPolicy | 直接丢弃 |
| DiscardOldestPolicy | 丢弃队列里最老的 |
可扩展面试题 #
13. 水平扩展 vs 垂直扩展? #
答案:
| 对比项 | 水平扩展 | 垂直扩展 |
|---|---|---|
| 方式 | 加机器 | 升级配置 |
| 成本 | 线性增长 | 指数增长 |
| 上限 | 高 | 低 |
| 推荐 | ✅ | ❌ |
14. 如何设计无状态服务? #
答案:
- Session外置Redis
- 配置存Nacos/Config
- 数据存DB/缓存
- 每个节点完全对等,可随时扩缩容
容灾容错面试题 #
15. 什么是RTO和RPO? #
答案:
- RTO (Recovery Time Objective):恢复时间目标,灾难后业务恢复的时间
- RPO (Recovery Point Objective):恢复点目标,灾难后丢失的数据量
16. 多活架构怎么设计? #
答案:
- 单元化架构,每个单元独立可用
- 数据双向同步
- 流量按地区/用户路由
- 故障时快速切换
安全可靠面试题 #
17. 如何保证数据传输安全? #
答案:
- 传输层:HTTPS/TLS加密
- 应用层:敏感数据AES加密
- 存储层:数据库加密、磁盘加密
18. 如何防刷限流? #
答案:
- 网关层:IP限流、用户限流
- 应用层:Sentinel限流
- 验证码:防机器刷
- 黑白名单
可观测性面试题 #
19. 可观测性三大支柱是什么? #
答案:
| 支柱 | 说明 | 工具 |
|---|---|---|
| Logging | 日志记录 | ELK、Loki |
| Metrics | 指标监控 | Prometheus + Grafana |
| Tracing | 链路追踪 | Jaeger、Skywalking |
20. 全链路追踪的原理? #
答案:
- TraceID:整个链路唯一标识
- Span:每个服务节点的处理
- Context传播:跨进程传递TraceID
限流熔断降级面试题 #
21. 常见限流算法有哪些?对比? #
答案:
| 算法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 固定窗口 | 单位时间计数 | 简单 | 边界突刺 |
| 滑动窗口 | 窗口滑动 | 平滑 | 实现复杂 |
| 令牌桶 | 固定速率放令牌 | 允许突发 | 预热问题 |
| 漏桶 | 固定速率流出 | 强制平滑 | 突发流量处理差 |
22. 熔断器三种状态是什么? #
答案:
Closed → Open → HalfOpen → Closed
- Closed:正常状态,请求放行
- Open:熔断状态,快速失败
- HalfOpen:半开状态,尝试放行少量请求验证
23. 降级策略有哪些? #
答案:
- 快速失败:直接返回错误
- 返回默认值:返回默认数据
- 返回缓存:读本地缓存
- 降级处理:走简化流程
🔗 相关笔记 #
*最后更新: 2026-05-05