架构师高频追问题库
1. 使用方式
本文件用于架构师面试前快速自测。每个问题都建议按下面结构回答:
结论 -> 背景 -> 方案 -> 取舍 -> 风险 -> 兜底 -> 项目例子2. 架构思维类
2.1 你怎么理解架构师职责?
- 考点:业务目标、系统边界、技术取舍、落地推进。
- 回答思路:架构师不是只画图,而是把业务目标转成可落地的技术方案,控制复杂度、风险、成本和演进路径。
- 进阶追问:架构师如何平衡短期交付和长期架构?
2.2 你如何判断一个架构是否合理?
- 考点:质量属性、约束匹配、可演进。
- 回答思路:看是否满足业务目标,是否匹配规模和团队能力,是否有异常链路和可观测性,是否能分阶段演进。
- 进阶追问:如果方案上线后效果不好,如何复盘?
2.3 你如何避免过度设计?
- 考点:YAGNI(你不会需要它原则)、阶段性架构、成本。
- 回答思路:按当前业务规模和未来可预见增长设计,不为不确定需求引入过重组件;保留演进接口。
- 进阶追问:什么时候应该提前设计扩展点?
3. 技术选型类
3.1 MySQL(关系型数据库)和 MongoDB(文档数据库)怎么选?
- 回答思路:强事务、结构化关系、审计选 MySQL(关系型数据库);文档结构变化快、弱事务查询选 MongoDB(文档数据库)。
- 项目例子:订单和支付主数据放 MySQL(关系型数据库),物流轨迹扩展字段可考虑文档存储或搜索侧同步。
3.2 Redis(远程字典服务)缓存和本地缓存怎么选?
- 回答思路:本地缓存延迟低但多实例一致性差,适合配置和低频热点;Redis(远程字典服务)适合跨实例共享和集中治理。
- 追问:缓存击穿、热点 key(键)、一致性如何处理?
3.3 Kafka(分布式日志消息系统)、RocketMQ(分布式消息队列)、RabbitMQ(消息队列)怎么选?
- 回答思路:Kafka(分布式日志消息系统)偏高吞吐日志流,RocketMQ(分布式消息队列)偏交易消息和事务消息,RabbitMQ(消息队列)偏灵活路由和传统集成。
- 追问:顺序消息、重复消费、消息丢失怎么处理?
4. 高并发与高可用类
4.1 如何设计一个秒杀系统?
- 回答结构:
- 前端限流和按钮防抖。
- Gateway(网关)限流和黑名单。
- Redis(远程字典服务)预扣库存。
- MQ(消息队列)削峰异步下单。
- MySQL(关系型数据库)条件更新兜底。
- 幂等、补偿、对账。
- 追问:Redis(远程字典服务)库存和数据库库存不一致怎么办?
4.2 如何防止系统雪崩?
- 回答结构:超时、限流、熔断、降级、隔离、重试退避、缓存兜底、监控告警。
- 追问:为什么重试可能放大故障?
4.3 如何做多活架构?
- 回答结构:先区分同城双活、异地多活;核心难点是数据一致性、流量调度、故障切换、冲突处理。
- 追问:支付系统适合直接异地多写吗?
5. 数据一致性类
5.1 分布式事务怎么选?
- 回答结构:
- 本地事务优先。
- 跨服务可用可靠消息最终一致性。
- 强一致业务可考虑 TCC(Try Confirm Cancel,尝试确认取消)。
- 外部通道用最大努力通知和对账。
- 追问:Seata(分布式事务框架)适合所有场景吗?
5.2 支付回调如何保证幂等?
- 回答结构:验签、防重放、通道事件 ID(标识)唯一、状态机、数据库唯一索引、重复请求直接返回成功。
- 追问:回调先到、主动查询后到,状态如何合并?
5.3 库存扣减如何保证不超卖?
- 回答结构:幂等请求、Redis(远程字典服务)预扣、数据库条件更新、冻结库存、超时释放、对账补偿。
- 追问:库存冻结成功但支付失败怎么办?
6. 服务治理类
6.1 微服务拆分依据是什么?
- 回答结构:业务边界、数据所有权、变化频率、团队协作、扩展需求。
- 追问:服务拆太细怎么办?
6.2 如何做灰度发布?
- 回答结构:按用户/租户/仓库/版本灰度,网关路由,配置开关,指标观察,异常自动回滚。
- 追问:灰度期间数据结构变化怎么兼容?
6.3 如何排查微服务慢请求?
- 回答结构:TraceId(链路标识)串联 Gateway(网关)、服务、数据库、缓存、外部接口;结合 Metrics(指标)定位瓶颈。
- 追问:如果没有 Trace(链路追踪)怎么办?
7. 团队与治理类
7.1 架构师如何推动规范落地?
- 回答结构:制定规范、沉淀模板、代码评审、脚手架、治理平台、指标验证。
- 追问:团队不愿意遵守规范怎么办?
7.2 如何治理技术债?
- 回答结构:识别影响面、分级排序、业务价值绑定、渐进式重构、监控收益。
- 追问:重构和业务需求冲突怎么办?
7.3 如何做架构复盘?
- 回答结构:事实时间线、影响范围、根因、短期止血、长期修复、机制改进。
- 追问:如何避免复盘变成追责?
8. 必背 20 题清单
- 如何从 0 设计一个订单系统?
- 如何设计库存防超卖?
- 如何设计支付资金一致性?
- 如何设计跨境物流履约系统?
- 如何设计 IoT(物联网)报警治理系统?
- 如何做技术选型?
- 如何设计高可用系统?
- 如何处理分布式事务?
- 如何设计幂等?
- 如何设计补偿机制?
- 如何防止雪崩?
- 如何做灰度发布?
- 如何治理慢 SQL(结构化查询语言)?
- 如何治理消息堆积?
- 如何做分库分表迁移?
- 如何做缓存一致性?
- 如何做链路追踪?
- 如何评估架构成本?
- 如何推动技术方案落地?
- 如何证明你具备架构师思维?
9. 核心 10 题口述答案
9.1 如何从 0 设计一个订单系统?
30 秒简答版
我会先澄清业务边界和规模,再设计订单主链路。订单系统核心不是简单保存订单,而是要管理订单状态、库存、支付、履约、取消、退款和售后。架构上我会用订单服务作为主状态入口,库存、支付、物流等能力通过领域服务或事件解耦,核心状态落 MySQL(关系型数据库),热点查询走缓存,跨服务协作用 MQ(消息队列)和补偿保证最终一致性。
2 分钟标准版
如果从 0 设计订单系统,我会先问清楚几个问题:订单类型是什么,是普通电商订单、WMS(仓储管理系统)出入库订单,还是跨境物流履约订单;峰值 QPS(每秒查询率)是多少;是否要求强库存一致;支付是否接第三方通道;订单状态是否复杂。
核心设计上,我会先把订单作为主聚合,订单服务负责订单创建、状态流转和对外查询。库存扣减不直接写库存表,而是调用库存服务冻结库存;支付走支付服务,支付成功后通过 MQ(消息队列)通知订单服务推进状态;物流履约可以异步创建履约任务。这样订单服务不直接承担所有外部系统耦合。
数据层面,订单主表用 MySQL(关系型数据库)承载,因为订单需要事务、状态机、审计和查询。订单明细、支付流水、操作日志分表存储。高频查询可以使用 Redis(远程字典服务)缓存订单摘要,但缓存不是事实来源。订单状态流转必须有状态机限制,比如待支付只能变成已支付或已取消,不能直接变成已签收。
异常处理上,要考虑重复下单、库存冻结失败、支付回调重复、MQ(消息队列)消息延迟、物流创建失败等情况。所以必须有幂等键、唯一索引、状态机、补偿任务、对账任务和 TraceId(链路标识)贯穿链路。
5 分钟深挖版
更完整地讲,我会分阶段设计。
第一阶段是业务建模。订单系统至少包含订单主数据、订单明细、订单状态、支付信息、库存冻结记录、履约记录和操作日志。这里最重要的是识别谁是事实来源:订单状态以订单服务为准,支付结果以支付流水和通道回调为准,库存可售数量以库存服务和数据库条件更新为准。
第二阶段是主链路。创建订单时,先做请求幂等,防止用户重复提交。然后校验商品、价格、地址等信息,再冻结库存。库存冻结成功后创建订单并生成待支付状态。支付成功后,订单状态从待支付流转到已支付,再触发履约或出库。每一步都要有状态机约束,避免乱序事件把订单推进到非法状态。
第三阶段是一致性设计。单体阶段可以用本地事务覆盖订单和库存,但微服务后不能跨服务随便用强事务。我的倾向是库存冻结和订单创建保持短事务,跨服务用可靠消息最终一致性。支付成功后发送领域事件,下游库存、履约、通知各自消费。消费者必须幂等,失败进入重试和死信。
第四阶段是性能和可用性。订单主链路要短,外部物流、短信、邮件这类调用不能阻塞主链路。读多的订单列表可以做缓存或读模型,但订单详情和资金相关字段要回源数据库。高峰期用 Gateway(网关)限流、线程池隔离、MQ(消息队列)削峰,保护订单核心写链路。
第五阶段是可观测和运维。每笔订单必须能按 orderNo(订单号)和 TraceId(链路标识)追踪完整链路。指标上看下单成功率、库存冻结失败率、支付回调延迟、履约创建失败率、MQ(消息队列)积压量。出现故障时,可以通过补偿任务重新推进状态。
项目结合版
结合 WMS(仓储管理系统)和跨境物流,我会把订单链路拆成订单、库存、履约、物流、支付几个边界。比如跨境订单支付成功后,不是同步调用所有物流渠道,而是先落订单状态,再发履约事件。面单拉取、轨迹同步、清关状态回传都走异步任务和 MQ(消息队列),避免第三方接口慢导致订单主链路超时。库存侧通过冻结库存和超时释放保证不超卖,支付侧通过 Webhook(回调通知)幂等和对账保证资金正确。
防守追问
追问:为什么不用一个大事务把订单、库存、支付都包起来? 因为支付通道和物流系统是外部系统,不受本地事务控制。强行包大事务会导致长事务、锁等待和可用性下降。更合理的是核心状态本地事务保证,跨服务通过可靠消息、幂等和补偿保证最终一致。
追问:订单状态乱序怎么办? 用状态机限制流转,事件里带版本号或状态前置条件。比如已取消订单收到支付成功事件时不能直接改为已支付,需要进入异常补偿或人工处理。
追问:订单查询很慢怎么办? 先看 SQL(结构化查询语言)和索引,再看分页方式、冷热数据、读写分离和搜索读模型。不能一上来就分库分表。
9.2 如何设计库存防超卖?
30 秒简答版
库存防超卖我会分成性能层和正确性层。Redis(远程字典服务)可以做热点库存预扣和削峰,但 MySQL(关系型数据库)条件更新必须作为最终兜底,保证库存不会扣成负数。同时要有请求幂等、库存冻结、支付超时释放、MQ(消息队列)补偿和库存对账。
2 分钟标准版
库存防超卖的核心目标有三个:不超卖、扛峰值、可恢复。单纯用 synchronized(同步锁)或 Redis(远程字典服务)锁都不够,因为系统可能多实例部署,锁可能过期,服务可能重启,消息可能延迟。
我的设计通常是:入口层先做限流和幂等,避免重复提交。库存热点比较明显时,可以用 Redis(远程字典服务)做预扣,利用 Lua(脚本语言)脚本保证判断和扣减的原子性。但 Redis(远程字典服务)不是最终事实来源,真正落库时,MySQL(关系型数据库)要使用条件更新,比如 available_stock >= count 才允许冻结库存。
下单时不是直接扣真实库存,而是冻结库存。支付成功后确认扣减,支付超时或订单取消后释放冻结库存。这样可以把下单和支付之间的不确定性管理起来。
异常方面,如果 Redis(远程字典服务)扣成功但数据库冻结失败,要回滚 Redis(远程字典服务)预扣或进入补偿;如果订单创建成功但支付超时,要释放冻结;如果 MQ(消息队列)通知失败,要靠本地消息表或补偿任务重发。最后通过库存对账校验 Redis(远程字典服务)库存、数据库可售库存、冻结库存和订单状态是否一致。
5 分钟深挖版
库存防超卖不能只看扣减那一行代码,要看完整生命周期。
第一,库存模型要清楚。通常至少有总库存、可售库存、冻结库存、已售库存。下单时从可售转冻结,支付成功从冻结转已售,取消或超时从冻结退回可售。这样状态清楚,异常可补偿。
第二,并发扣减要有底线。数据库层用条件更新是最后防线,例如 update stock set available = available - ?, frozen = frozen + ? where sku_id = ? and available >= ?。这能保证即使上层缓存或锁失效,数据库也不会扣成负数。
第三,Redis(远程字典服务)解决的是性能问题,不是唯一正确性来源。热点 SKU(库存单位)下,所有请求直接打数据库会造成锁竞争,所以用 Redis(远程字典服务)预扣削峰。但要考虑 Redis(远程字典服务)和数据库不一致,所以必须有对账和补偿。
第四,幂等非常重要。用户重复点击、接口重试、MQ(消息队列)重复消费都会导致重复扣减风险。每个库存冻结请求要有业务唯一键,比如 orderNo(订单号)和 skuId(库存单位标识)组合,重复请求直接返回已有结果。
第五,失败路径要完整。库存冻结成功但订单创建失败,要释放冻结;订单创建成功但支付失败,要超时释放;支付成功但库存确认失败,要进入异常状态并告警;补偿任务必须可重入,不能补偿一次失败就丢。
项目结合版
在 WMS(仓储管理系统)里,多仓库存比单仓更复杂。架构上我会以 skuId(库存单位标识) + warehouseId(仓库标识) 作为库存维度,库存服务统一对外提供冻结、确认、释放接口。跨境物流订单如果涉及多个仓库,还要在订单层先确定履约仓,再冻结对应仓库库存。库存变更都写操作流水,方便对账和问题追踪。
防守追问
追问:只用 Redis(远程字典服务)扣库存可以吗? 不建议。Redis(远程字典服务)适合挡流量,但核心库存要可审计、可恢复,最终事实来源应在数据库或库存中心。
追问:数据库条件更新会不会扛不住? 热点场景会有压力,所以用 Redis(远程字典服务)预扣、限流、队列削峰减少数据库写压力。但数据库条件更新仍然是最终正确性兜底。
追问:如何发现库存不一致? 通过库存流水、订单状态、冻结记录、Redis(远程字典服务)缓存和数据库库存做定时对账,发现差异后自动补偿或人工介入。
9.3 如何设计支付资金一致性?
30 秒简答版
支付系统我会把资金正确性放在第一优先级。核心设计是支付流水唯一、Webhook(回调通知)验签、防重放、通道事件 ID(标识)幂等、状态机流转、MQ(消息队列)通知下游,以及对账和补偿兜底。
2 分钟标准版
支付一致性不能只依赖第三方回调成功。第三方支付通道可能重复回调、延迟回调、乱序回调,也可能主动查询和回调结果同时到达。所以我会先设计支付流水表,每次支付请求生成唯一支付流水号,记录订单号、金额、币种、通道、状态和请求响应。
回调进来后,第一步验签,确认消息确实来自支付通道;第二步防重放,检查时间戳和随机串;第三步做幂等,用通道事件 ID(标识)或支付流水号加唯一索引,重复回调直接返回成功;第四步按状态机推进支付状态,比如待支付只能变为支付成功或支付失败。
支付成功后,不建议同步调用库存、订单、账务所有系统,而是先在本地事务里更新支付流水和订单支付状态,再发 MQ(消息队列)事件,下游各自消费。消费者必须幂等,失败进入重试和死信。
最后一定要有对账。因为外部支付通道不可控,回调丢失或延迟时,只靠回调会漏单。每日或定时拉取通道账单,对比本地支付流水,发现差异后生成补偿任务。
5 分钟深挖版
支付资金一致性可以分成三层。
第一层是请求一致性。支付发起时要保证同一订单不会重复创建多个有效支付单。可以通过订单号和支付场景生成幂等键,如果用户重复点击支付,返回同一笔待支付流水,而不是重复下单。
第二层是回调一致性。Webhook(回调通知)必须验签、防重放和幂等。验签保证来源可信,防重放避免旧消息被再次提交,幂等保证重复回调不会重复推进业务。状态机是关键,比如已成功的支付不能被失败回调覆盖,退款状态也不能随意回退。
第三层是跨系统一致性。支付成功后,订单、库存、账务、通知都要感知。但这里不适合长事务。更合理的是本地事务更新支付状态,并写本地消息表或发送可靠消息。下游消费时按业务键幂等,失败重试,超过次数进入死信和人工处理。
对账是最终防线。资金系统一定要承认“回调不可靠”。对账会比较通道账单、本地支付流水、订单状态和账务记录。差异分几类:通道成功本地失败、本地成功通道失败、金额不一致、重复记录。每类差异都有补偿策略和审计记录。
项目结合版
如果是跨境支付,还会有 Stripe(国际支付网关)、PayPal(国际支付平台)、Airwallex(空中云汇)等多个通道。架构上我会抽象统一支付单和通道适配层,每个通道的 Webhook(回调通知)验签逻辑独立,但最终都转换成统一支付事件。账务侧不直接相信回调,而是以支付流水和对账结果为准。
防守追问
追问:为什么重复回调要返回成功? 因为对支付通道来说,只要我们已经处理过这条事件,就应该返回成功,避免通道继续重试造成压力。但内部不能重复执行业务。
追问:回调成功但 MQ(消息队列)发送失败怎么办? 用本地消息表或 Outbox Pattern(发件箱模式),本地事务先保存待发送事件,再由后台任务可靠投递。
追问:对账发现通道成功但本地失败怎么办? 生成补偿任务,重新推进本地支付状态和下游事件,同时保留审计日志。
9.4 如何设计跨境物流履约系统?
30 秒简答版
跨境物流履约系统要把外部不稳定性隔离出去。订单主链路只创建履约任务,面单拉取、轨迹同步、清关状态、签收回传都异步处理。核心是状态机、幂等、重试退避、死信补偿和全链路 TraceId(链路标识)。
2 分钟标准版
跨境物流的特点是链路长、外部系统多、接口不稳定、状态延迟明显。所以我不会把物流接口都同步放在订单主链路里。订单支付成功后,订单服务发送履约事件,履约服务创建履约单,再异步调用物流渠道生成面单。
面单拉取这种外部调用要有独立线程池、超时、限流和重试退避,避免某个物流渠道慢把整个系统拖垮。轨迹同步可以接收外部推送,也可以定时拉取,进入 MQ(消息队列)后由消费者幂等写入。轨迹状态必须有状态机,比如已签收后不能再回到运输中,乱序轨迹要能合并。
查询侧可以把物流轨迹同步到 Elasticsearch(搜索引擎)提升搜索体验,但物流主状态还是以数据库记录为准。异常件、清关失败、面单失败要进入可视化补偿队列,让运营可以介入。
5 分钟深挖版
我会把跨境物流履约拆成几个子域:履约单、面单、轨迹、异常件、渠道适配、通知。
履约单是内部状态核心,记录订单、仓库、物流渠道、履约状态和异常原因。面单服务负责和外部渠道交互,但通过适配器隔离不同渠道差异。轨迹服务负责接收推送、拉取轨迹、去重和状态合并。异常件服务负责清关失败、地址异常、退件等人工介入流程。
数据一致性上,订单支付成功到履约创建可以用 MQ(消息队列)最终一致性,履约创建失败可以重试。面单生成失败不能让订单状态丢失,而是让履约单进入待重试或异常状态。轨迹重复和乱序通过业务唯一键和状态机解决。
稳定性上,每个物流渠道都要单独限流、熔断和降级。比如某渠道 RT(响应时间)突然变高,只影响该渠道任务,不影响其他渠道。线程池也按渠道或任务类型隔离。
可观测性上,每个履约单要能看到订单、面单请求、渠道响应、轨迹节点、失败重试和人工处理记录。否则跨境物流问题排查会非常困难。
项目结合版
结合跨境物流项目,我会强调“外部系统不可靠是常态”。所以方案不是追求一次调用成功,而是设计可重试、可补偿、可追踪的履约链路。面单拉取失败不影响订单主状态,轨迹延迟不影响支付状态,清关异常进入运营处理队列。
防守追问
追问:物流轨迹乱序怎么办? 用状态机和轨迹时间排序,低优先级旧状态不能覆盖高优先级新状态,同时保留原始轨迹用于审计。
追问:某个物流渠道大面积超时怎么办? 对该渠道熔断和限流,任务进入延迟重试,必要时切换备用渠道或人工处理,不让它拖垮全局线程池。
追问:为什么要引入 MQ(消息队列)? 因为履约链路长且外部不稳定,MQ(消息队列)可以削峰、解耦、重试和承载最终一致性。
9.5 如何设计 IoT(物联网)报警治理系统?
30 秒简答版
IoT(物联网)报警治理的核心不是简单限流,而是降噪同时保留重要报警。架构上接入层限流,MQ(消息队列)削峰,处理层按设备、报警类型和时间窗口聚合,Redis(远程字典服务)做短期计数和去重,严重报警穿透通知,普通重复报警降噪。
2 分钟标准版
IoT(物联网)报警风暴一般发生在设备异常、网络抖动或规则配置错误时,短时间内大量重复报警会打爆消息队列和通知渠道。设计时我会先区分报警等级:严重报警不能丢,普通报警可以聚合和降噪。
接入层做基础限流和格式校验,避免脏数据进入系统。然后通过 MQ(消息队列)削峰,让处理服务按能力消费。处理层按 deviceId(设备标识) + alarmCode(报警编码) + window(时间窗口) 做聚合 key(键),Redis(远程字典服务)保存窗口计数、首次报警时间和最近报警时间。
通知层按等级路由。严重报警可以短信、电话或企业微信多渠道通知;普通重复报警只更新计数,不重复刷屏。数据库保存最终报警事件和聚合结果,便于后续复盘。
5 分钟深挖版
报警治理要同时解决实时性、准确性和噪声控制。
第一,接入层要做限流和鉴权,防止单设备或异常网关打爆系统。限流不能一刀切,严重报警要有更高优先级。
第二,处理层要有聚合模型。单条报警事件是原始事实,聚合报警是面向人的处理对象。比如 1 分钟内同一设备同一报警上报 100 次,系统不应该通知 100 次,而是生成一个聚合报警,记录次数、首次时间、最后时间和影响范围。
第三,规则层要支持分级和抑制。比如同一设备离线后,后续传感器异常可能都是派生报警,可以被抑制或合并,避免报警风暴。
第四,存储层要区分热数据和历史数据。近期报警用于实时处置,历史报警用于报表和模型优化。
第五,可观测性非常重要。要监控报警接入量、丢弃量、聚合率、通知成功率、MQ(消息队列)积压、Redis(远程字典服务)命中和处理延迟。
项目结合版
结合 IoT(物联网)报警风暴治理,我会说重点不是“把报警挡掉”,而是保证关键报警到人、重复报警降噪、异常高峰系统不崩。架构上用 MQ(消息队列)削峰,用 Redis(远程字典服务)做窗口聚合,用规则引擎做分级抑制,用告警指标判断是否发生风暴。
防守追问
追问:限流会不会丢掉重要报警? 所以要分级限流。高等级报警走优先通道,低等级重复报警才聚合或降噪。
追问:Redis(远程字典服务)宕机怎么办? Redis(远程字典服务)用于短期聚合状态,不是最终事实来源。宕机时可以退化为直接落库和降低通知频率,恢复后继续聚合。
追问:如何衡量治理效果? 看报警聚合率、重复通知下降比例、严重报警到达率、处理时延和人工误报反馈。
9.6 如何做技术选型?
30 秒简答版
技术选型我不会从技术偏好出发,而是从业务目标、数据规模、一致性、性能、可用性、成本、团队能力和演进风险做判断。好的选型不是最先进,而是当前阶段最合适、团队能掌控、未来能演进。
2 分钟标准版
我做技术选型会先明确业务问题。比如是交易一致性问题、查询性能问题、削峰解耦问题,还是可观测性问题。然后看规模和约束:数据量多大、峰值多少、是否强一致、团队是否有运维经验、上线周期多紧。
然后列候选方案做对比。比如订单主数据,MySQL(关系型数据库)适合,因为有事务、约束和审计;Elasticsearch(搜索引擎)适合搜索,但不适合做交易主库。再比如消息队列,Kafka(分布式日志消息系统)适合高吞吐日志流,RocketMQ(分布式消息队列)更适合交易消息和事务消息。
最后我会给出阶段性方案。早期不要过度设计,先用简单可靠方案;等规模和复杂度上来,再演进到分库分表、搜索读模型或事件驱动架构。
5 分钟深挖版
技术选型本质是约束下的决策。
第一维是业务匹配。比如支付资金状态必须可审计,所以优先数据库事务和对账,而不是只放缓存。
第二维是数据规模。百万级数据和百亿级数据的存储方案不同,日写入 1 万和日写入 1 亿的消息系统也不同。
第三维是一致性。强一致场景要谨慎引入异步,最终一致场景可以用 MQ(消息队列)提高可用性和吞吐。
第四维是团队能力。团队没有 Kubernetes(容器编排平台)经验时,不一定要一上来做复杂云原生架构;否则故障时没人能救。
第五维是迁移风险。架构师要考虑从当前方案迁移到未来方案的路径,比如先单库,后续按租户或订单号分片;先 MySQL(关系型数据库)查询,后续同步 Elasticsearch(搜索引擎)做搜索。
项目结合版
在跨境物流系统里,我不会把所有轨迹都塞进订单表。订单主状态用 MySQL(关系型数据库),轨迹检索可以同步 Elasticsearch(搜索引擎),大规模报表可以进 ClickHouse(列式数据库)。这不是为了堆技术,而是因为主交易、搜索、分析的访问模式不同。
防守追问
追问:为什么不用最新技术? 技术新不等于适合。架构师要对稳定性、团队能力和运维成本负责。
追问:选型错了怎么办? 先控制影响范围,保留数据迁移和接口抽象,分阶段切换,用灰度验证新方案。
追问:如何说服团队接受选型? 用数据和对比矩阵说明收益、风险和落地成本,而不是靠个人偏好。
9.7 如何设计高可用系统?
30 秒简答版
高可用不是只做多副本,而是从入口限流、服务隔离、超时重试、熔断降级、数据容灾、消息削峰、监控告警和应急预案形成体系。核心目标是局部失败不扩散,关键链路可恢复。
2 分钟标准版
设计高可用系统,我会先识别核心链路和非核心链路。比如订单创建、库存扣减、支付状态是核心链路,通知、报表、推荐可以降级。然后在入口层做限流和鉴权,服务层做线程池隔离和熔断,调用层设置超时和重试退避,数据层做主从、备份和容量治理,异步层用 MQ(消息队列)削峰。
高可用还要设计失败路径。下游接口慢时不能无限等待,缓存不可用时要能回源或降级,MQ(消息队列)积压时要限速和扩容,数据库压力高时要保护核心写链路。
最后必须有可观测性。没有 Log(日志)、Metrics(指标)、Trace(链路追踪)和告警,高可用只停留在架构图上。
5 分钟深挖版
高可用可以分为预防、隔离、恢复三个层次。
预防层包括容量评估、压测、限流、缓存、异步化和代码质量。比如上线前要知道核心接口峰值 QPS(每秒查询率)、线程池容量、数据库连接池上限。
隔离层包括服务隔离、线程池隔离、数据隔离和故障域隔离。一个物流渠道慢,不应该拖垮所有渠道;一个报表任务慢,不应该影响支付回调。
恢复层包括熔断、降级、重试退避、补偿、灰度回滚和应急开关。重试要谨慎,立即重试可能放大故障,所以要指数退避和最大次数。
数据层高可用还要看一致性。读多场景可以读写分离,但支付和库存的核心写必须保证正确性。跨机房多活更复杂,要考虑数据冲突和流量切换。
项目结合版
在 WMS(仓储管理系统)和跨境物流里,我会把订单、支付、库存放在核心保护层;轨迹同步、通知、报表放在可降级层。外部物流渠道用独立线程池和熔断策略,失败任务进入补偿队列。这样外部系统故障不会拖垮核心交易链路。
防守追问
追问:多副本是不是就高可用? 不是。多副本解决实例故障,但不能解决慢依赖、重试风暴、数据库瓶颈和数据不一致。
追问:降级会不会影响用户体验? 会影响部分体验,但比全站不可用更好。关键是明确哪些可降级,哪些不能降级。
追问:如何验证高可用设计有效? 通过压测、故障演练、灰度发布、监控指标和复盘验证。
9.8 如何处理分布式事务?
30 秒简答版
分布式事务我会先判断是否真的需要强一致。单服务优先本地事务;跨服务但能接受最终一致,用可靠消息和补偿;强一致且业务允许复杂度时,才考虑 TCC(Try Confirm Cancel,尝试确认取消)或事务框架;外部支付这类不可控系统最终靠对账兜底。
2 分钟标准版
处理分布式事务不能只说用 Seata(分布式事务框架)。我会先看业务一致性要求。如果订单和订单明细在同一个服务内,用本地事务最简单可靠。如果订单、库存、支付拆成多个服务,就要避免长事务。
常见方案有几类:可靠消息最终一致性适合订单支付成功后通知库存、履约、积分;TCC(Try Confirm Cancel,尝试确认取消)适合强一致资源预留,比如库存冻结;最大努力通知适合外部支付回调;SAGA(长事务模式)适合长流程业务,每一步都有补偿。
我更关注失败路径。消息发送失败怎么办,消费者重复消费怎么办,Confirm(确认)成功 Cancel(取消)又来了怎么办,补偿失败怎么办。这些问题不解决,选什么框架都不稳。
5 分钟深挖版
分布式事务的核心是跨边界状态一致。越过服务、数据库或外部系统边界后,本地 ACID(原子性、一致性、隔离性、持久性)事务就不够了。
可靠消息最终一致性的关键是本地事务和消息投递绑定。可以用本地消息表或 Outbox Pattern(发件箱模式):业务数据和待发送消息在同一个本地事务里落库,后台任务再可靠投递 MQ(消息队列)。消费者幂等处理,失败重试,最终通过死信和补偿兜底。
TCC(Try Confirm Cancel,尝试确认取消)的关键是资源预留。Try(尝试)阶段冻结资源,Confirm(确认)阶段确认使用,Cancel(取消)阶段释放资源。它一致性强,但开发成本高,每个参与方都要实现三套接口,还要处理空回滚、悬挂和幂等。
SAGA(长事务模式)适合长链路流程,比如跨境物流履约,每一步完成后提交,失败后按反向补偿。但它是业务补偿,不是数据库回滚。
外部支付系统无法纳入本地事务,因此必须用回调幂等、主动查询、对账和补偿保证最终正确。
项目结合版
在支付资金一致性里,我不会把支付通道、订单、库存放进一个强事务。支付流水本地事务先保证正确,支付成功事件通过 MQ(消息队列)通知订单和库存。库存冻结适合 TCC(Try Confirm Cancel,尝试确认取消)的思想,支付通道适合最大努力通知和对账。
防守追问
追问:Seata(分布式事务框架)能解决所有问题吗? 不能。它有适用边界,引入后也有性能、锁、回滚和运维复杂度。外部支付通道这类系统也不受它控制。
追问:最终一致性会不会丢数据? 设计正确不会。关键是本地消息表、消费者幂等、重试死信、补偿和对账。
追问:如何处理补偿失败? 补偿任务要有状态、重试次数、告警和人工介入入口,不能静默失败。
9.9 如何做灰度发布?
30 秒简答版
灰度发布的核心是控制影响范围。可以按用户、租户、仓库、版本或流量比例灰度,通过 Gateway(网关)、配置中心和服务路由控制入口,同时观察错误率、RT(响应时间)、QPS(每秒查询率)和业务指标,异常时快速回滚。
2 分钟标准版
我做灰度发布会先明确灰度对象和回滚策略。比如按内部账号、指定租户、指定仓库或 1% 流量开始。入口层可以通过 Gateway(网关)识别用户或租户标签,把流量路由到新版本。配置类功能可以通过 Config Center(配置中心)开关控制。
灰度期间要重点看技术指标和业务指标。技术指标包括错误率、RT(响应时间)、CPU(中央处理器)、内存、线程池、数据库慢 SQL(结构化查询语言)。业务指标包括下单成功率、支付成功率、库存冻结失败率、履约任务失败率。
数据库变更要特别谨慎。涉及表结构变化时,要兼容新老版本,通常先加字段、双写或兼容读,再切流量,最后清理旧逻辑,不能让新老版本互相不兼容。
5 分钟深挖版
灰度发布可以分为发布前、发布中、发布后三个阶段。
发布前,要做风险评估和回滚预案。哪些接口受影响,是否有数据库变更,是否有消息格式变更,是否影响第三方接口。高风险变更要加开关。
发布中,先小范围验证。比如内部用户、单个租户、单个仓库或少量流量。灰度规则要可配置,不能写死在代码里。监控要实时看,发现异常自动或人工暂停。
发布后,不是马上全量,而是逐步扩大范围。每一步都要观察一段时间。全量后仍要保留回滚窗口。
最难的是有状态变更,比如订单状态机、支付流程、消息格式和数据库结构。这类变更要遵循向前兼容和向后兼容。比如先发布兼容旧字段和新字段的代码,再做数据迁移,最后移除旧字段。
项目结合版
在 WMS(仓储管理系统)里,灰度可以按仓库维度做,比如先让一个非核心仓库使用新的库存冻结逻辑,观察库存冻结成功率、订单取消率、人工补偿数量。跨境物流可以按渠道灰度,先切一个物流渠道或一个国家线路,避免影响全部订单。
防守追问
追问:灰度期间数据结构不兼容怎么办? 做双版本兼容。先加字段,不删字段;新老代码都能读写;确认稳定后再清理。
追问:如何自动判断要不要回滚? 设定错误率、RT(响应时间)、核心业务成功率阈值,超过阈值自动暂停或回滚。
追问:配置灰度和流量灰度有什么区别? 配置灰度控制功能开关,流量灰度控制请求路由,实际项目常组合使用。
9.10 如何证明你具备架构师思维?
30 秒简答版
我会从三个方面证明:第一,我能从业务目标和约束出发设计方案;第二,我能讲清技术取舍、风险和兜底;第三,我能推动方案落地,并通过指标、灰度和复盘持续演进。
2 分钟标准版
我理解架构师思维不是会很多技术名词,而是能把复杂业务问题拆成可落地的技术方案。比如面对库存防超卖,我不会只说用 Redis(远程字典服务)锁,而是先明确目标是不超卖、扛峰值、可恢复,然后设计 Redis(远程字典服务)预扣、MySQL(关系型数据库)条件更新、库存冻结、幂等、补偿和对账。
第二,我会主动讲取舍。比如微服务能提升独立部署和扩展能力,但会带来分布式事务、链路追踪和运维复杂度;MQ(消息队列)能削峰解耦,但会带来重复消费、顺序和积压问题。
第三,我会考虑落地。方案不只是图,还包括阶段计划、接口契约、监控指标、灰度发布、回滚预案和复盘机制。
5 分钟深挖版
架构师思维可以体现在四个层次。
第一是问题定义能力。很多技术问题表面上是性能或并发,背后可能是业务流程、数据模型或团队协作问题。架构师要先把问题定义清楚。
第二是系统性设计能力。方案要覆盖主链路、异常链路、补偿链路和运维链路。比如支付系统不仅要处理成功,还要处理重复回调、延迟回调、退款、对账差异和人工补偿。
第三是取舍能力。没有绝对完美方案。强一致会增加复杂度,高可用可能牺牲一致性,低成本可能限制扩展性。架构师要讲清为什么当前阶段这么选,以及未来怎么演进。
第四是落地和治理能力。架构师要能推动团队执行,通过规范、评审、监控、灰度和复盘让方案持续有效,而不是写完设计文档就结束。
项目结合版
我可以用三个项目证明:库存防超卖体现一致性和高并发取舍;支付资金一致性体现幂等、状态机、对账和审计;IoT(物联网)报警风暴治理体现削峰、降噪、分级和可观测性。这些不是单点技术,而是从业务风险出发设计完整闭环。
防守追问
追问:你是不是只是高级开发,还不是架构师? 我会承认架构师能力是持续演进的,但我已经在项目中承担过方案设计、技术选型、风险兜底和跨模块协作,不只是完成单个功能开发。
追问:你做过最大的架构取舍是什么? 可以回答库存或支付场景:没有追求全链路强一致,而是把核心正确性放在数据库和状态机,其他链路用最终一致和补偿,平衡了性能和可靠性。
追问:如何衡量架构方案成功? 看业务指标和技术指标是否改善,比如成功率、故障率、RT(响应时间)、人工补偿量、成本和交付效率。
10. 精通级分册入口与学习路线
本节为新增导航入口,旧根上方内容完整保留。新增分册负责把旧题扩展为“约束、反例、容量、成本、恢复、组织治理”的深度追问,不替代旧根快速复习。
10.1 分册索引
| 顺序 | 分册 | 核心训练 | 正式图 |
|---|---|---|---|
| 00 | 旧资产映射与架构追问路线 | 映射旧根题目、事实等级、追问路线和学习顺序 | PlantUML(开源建模工具) / PNG(便携式网络图形) |
| 01 | 需求约束边界与反例追问 | 把模糊需求拆成对象、动作、范围、量级、不变量和反例 | PlantUML(开源建模工具) / PNG(便携式网络图形) |
| 02 | 一致性、可用性、容量与成本权衡追问 | 训练 CAP(一致性、可用性、分区容错)、BASE(基本可用、软状态、最终一致)、容量、预算和失败成本 | PlantUML(开源建模工具) / PNG(便携式网络图形) |
| 03 | 故障域恢复演练与演进追问 | 训练 RPO(恢复点目标)、RTO(恢复时间目标)、容灾、恢复门禁和事故复盘 | PlantUML(开源建模工具) / PNG(便携式网络图形) |
| 04 | 项目架构评审口述与交叉追问 | 把 WMS(仓储管理系统)、支付、履约、导出、Runner(执行器)、IoT(物联网)和跨境物流串成评审口述 | PlantUML(开源建模工具) / PNG(便携式网络图形) |
10.2 使用顺序
第一轮按 00 -> 01 -> 02 -> 03 -> 04 学习:先建立旧题映射和事实边界,再训练需求反例,然后进入一致性、容量、成本、故障恢复,最后把项目串讲成架构评审表达。
第二轮按面试题倒推:
- 问“怎么做架构设计”:读
01和04。 - 问“为什么这样取舍”:读
02。 - 问“出故障怎么恢复”:读
03。 - 问“你是否真做过”:先回到 90/00 事实卡,再选项目分册。
10.3 事实边界
回答时统一使用 E1(直接证据)、E2(已有材料映射)、E3(演练设计)、E0(待核对)标注事实强度。没有源码、监控、账单、工单或简历直接证据时,不把容量、收益、事故结果和上线范围说成生产事实。
10.4 自检清单
- 能把每个架构题拆成业务目标、硬约束、软约束、偏好和不可做清单。
- 能用反例验证方案,而不是只画正常链路。
- 能同时比较建设成本、运行成本、失败成本和退出成本。
- 能说明何时回滚、何时前向修复、何时停止演进。
- 能把项目事实和 E3(演练设计)数字分开表达。
