
架构设计这个词几乎每个技术方案评审会说每个资深开发都能聊两句但真正动手去拆解它的时候很多人给出来的答案又不太一样。我这些年看过的架构评审材料少说也有上百份我自己也带队做过几个从零到一的项目慢慢发现一个共识度比较高的划分方式架构设计最核心的东西其实可以收敛成五大要素——性能、可用性、伸缩性、扩展性、安全性。你去看那些做得好的系统往往不是某一个点特别惊艳而是这五个维度恰好适合它当下的业务阶段。这篇文章我想把这五个要素掰开揉碎地讲一遍包括每个要素到底在解决什么问题、落地时有哪些关键手段、以及它们之间怎么取舍。适合正在做架构选型的团队负责人、刚接触系统设计的中级开发也可以给那些准备做技术方案但总觉得“差了点什么”的同学当个自检清单。1. 架构设计为什么绕不开这五要素1.1 五要素的起源与定位架构设计解决的核心问题从来不是“用哪个框架更潮”而是“系统在真实环境下能不能活得好、改得起、扛得住”。业内讨论架构时普遍把非功能性需求收敛为性能Performance、可用性Availability、伸缩性Scalability、扩展性Extensibility、安全性Security。你可以在各大云厂商的白皮书、企业架构方法论、甚至技术岗位面试题里反复看到这套框架它基本成了软件工程里的一种“通用语言”。为什么是这五个因为它们分别对应了一个系统在生命周期里最容易被挑战的五个方向用户变多了怎么办伸缩性、需求变多了怎么办扩展性、请求量变大了怎么办性能、机器挂了怎么办可用性、有人攻击你怎么办安全性。举个例子你做一个内部管理系统可能性能没那么苛刻但扩展性很重要因为业务同事每周都会提新需求你做一个支付系统可用性和安全性就是红线性能也不能太差你做一个活动页面伸缩性最关键因为流量洪峰就那几天。五要素并不是一套固定模版而是帮你判断“系统应该往哪个方向多投入”的分类框架。1.2 五要素之间的制约关系真正做过架构的人都知道这五个要素不是独立存在的它们之间存在着明显的相互制约。你想把性能做到极致往往要牺牲一部分安全性比如省掉加密环节减少网络开销但数据就等于在裸奔你想把可用性做得很高就得加副本、加机房、加自动切换这会抬高成本也可能因为数据同步带来额外延迟你想把扩展性做得很灵活就得多做抽象层、多拆服务系统复杂度上去之后性能排查和运维难度都会变大。我举个实实在在的例子。有一年我们做一个电商订单系统技术团队为了追求“高可用架构”把所有服务都做成多机房双活结果发现订单状态一致性问题非常难处理跨机房数据同步延迟导致用户重复下单。最后只能在“性能指标”和“一致性保障”之间反复调整花了两周时间才稳定下来。这种牵一发动全身的现象就是架构设计里最常见的日常。所以说五要素的价值不在于让你“五样全占”而在于让你在方案评审时能明确说出当前这个阶段我们优先保证什么哪些可以暂时牺牲哪些是红线。有了这个前提团队内部讨论才不会变成鸡同鸭讲。2. 性能与可用性最容易被拿来“背锅”的两个指标2.1 性能设计先定义清楚指标再谈优化手段性能是所有技术团队最先感知到的要素用户说系统卡、老板说页面慢、运维说CPU飙高归根到底都在性能范畴。但一个常见的误区是还没定义清楚“慢”的标准就开始盲目优化。我一般建议先确定三个层次的性能指标。第一层是响应时间RT用户发起一个请求到收到完整响应的时间这里面要区分平均耗时和TP99/TP95分位值。平均耗时很有欺骗性比如100个请求里有99个都是20ms有1个是3秒平均值仍然不高但那个3秒的请求可能是关键链路。第二层是吞吐量QPS/TPS也就是系统每秒能处理多少请求这个指标决定了系统能不能在峰值流量下扛得住。第三层是资源利用率CPU、内存、磁盘IO、带宽、连接数任何一个成为瓶颈都会影响前两个指标。指标定下来之后优化才有方向。常规的性能优化链路从用户端到服务端大概分这么几层浏览器或APP端的请求合并与缓存、CDN加速静态资源、API网关层面的限流与缓存、应用层的连接池与线程池调优、缓存层Redis的命中率优化、数据库层的索引优化与SQL慢查询治理。我记得之前做过一个商品搜索页线上P95响应时间一直在800ms左右用户体感明显偏慢。我们先做了链路追踪把耗时打点拆开看发现50%的时间花在数据库SQL上——一个关联了6张表的模糊查询走了全表扫描。后来改成ES索引再把商品信息缓存到RedisP95直接降到150ms。这次经验让我很深刻性能优化不是均匀用力而是先用监控定位热点再集中解决那个占了大头的问题。2.2 可用性设计朝着“故障一定会发生”去设计可用性衡量的是系统在一段时间内正常服务的时间比例通常用SLA来表示。这里有一组数据经常被我拿来给团队讲99.9%的可用性意味着一年下来系统有大约8.76小时不可用99.99%一年只能不能服务52.6分钟99.999%也就是俗称的五个9一年只能有5.26分钟的停机窗口。很多团队觉得“我们系统出不了大问题”但现实是硬件会老化、依赖会超时、上线会出bug、流量会突增、运维会误操作。所以可用性架构设计的核心不是“努力不出故障”而是“出了故障之后用户无感知或者感知很小”。具体手段上常见的套路是冗余、故障转移、限流熔断降级、备份恢复这几板斧。冗余就是加副本服务部署多个实例、数据库做主从、缓存做哨兵集群目的是不让单点故障变成系统瘫痪。故障转移是在主节点挂掉之后自动把流量切到备用节点这个过程要求切换时间越短越好。限流熔断降级则是保护系统本身当上游或者下游出现异常时不让雪崩效应蔓延。这里有个特别值得注意的细节。很多团队在做重试机制时踩过坑下游服务超时后上游拼命重试结果下游本来已经快不行了被这一波重试直接打挂。正确的做法是重试必须限制次数、增加退避时间并且保证接口的幂等性。类似这种“看起来简单做起来全是细节”的地方恰恰决定了可用性的真实水平。3. 伸缩性与扩展性一字之差思路完全不同3.1 伸缩性应对流量规模的变化伸缩性是系统在处理能力上的“弹性”说白了就是流量涨了我把机器加进去系统吞吐量就能跟着涨流量降了机器减下来成本也能跟着降。这种能力在互联网业务里几乎是刚需因为流量周期波动实在太明显了——白天高峰、晚上低谷、月底促销、节假日暴涨。伸缩性分垂直伸缩和水平伸缩。垂直伸缩是升级单机配置比如4核8G变32核64G简单有效但天花板很低而且贵。水平伸缩是加机器一台不够两台两台不够四台理论上没有上限。所以现代互联网架构基本默认走水平伸缩路线。但水平伸缩有个前提服务必须无状态化。什么叫无状态就是任何一台服务器处理请求时都不依赖本机保存的“回忆”用户Session、临时数据、本地缓存都不能绑在某个实例里。Session要放到Redis或独立存储里文件要放到OSS或分布式存储里。很多传统系统改造起来困难最大的坑就在这——代码里到处是本地文件缓存和Session操作改了session存储又冒出来一个本地队列的问题。数据层的伸缩是另一个难点。先做读写分离一主多从把读压力分摊掉再做分库分表把数据按业务维度拆开比如按用户ID取模分到不同的库再往上就是中间件方案的引入比如MyCat、ShardingSphere这类分片中间件。我见过不少团队在分库分表之后被跨库查询和分布式事务折磨所以这里也给个建议分库分表是最后手段不是首选方案能用缓存扛住的热点数据就不要过早拆库。3.2 扩展性应对业务需求的变化扩展性和伸缩性容易混实际上它们的关注点完全不同。伸缩性解决的是“量”的问题——请求变多了扩展性解决的是“质”的问题——业务变复杂了、需求变多了系统加功能的时候要不要改动原来的代码。扩展性的好坏可以用一个场景来感受假设你是做电商系统的现在要新增一种支付方式、一个新的营销活动类型、或者一种新的商品形态。如果改动只需要新增代码、不需要改动已有核心模块那扩展性就是好的如果每次加需求都要把好几个老模块翻个底朝天那说明架构的扩展性堪忧。提升扩展性的核心手段在设计层面主要是三个开闭原则对扩展开放、对修改关闭、依赖倒置面向接口编程而不是面向具体实现、低耦合高内聚模块之间通过稳定接口交互。在系统层面往往通过事件驱动、插件化、微服务化来落地。举个很典型的例子。很多老系统会在订单状态变更时写if-else每加一种业务动作就多一个分支代码越来越长、越来越乱。换成事件驱动之后订单状态变化只负责发布事件不同的业务方自己去订阅下单消息可以被库存服务、通知服务、积分服务分别监听相互无感知。这样加新的订阅方老代码一行都不用动。不过这地方我特别想说一句话微服务不等于扩展性好反而经常是过度设计的温床。如果团队只有十几个人业务逻辑没那么复杂强行拆微服务只会把分布式事务、链路追踪、服务治理这些复杂度都背到身上结果反而是每次改需求都要跨服务协调扩展性更差。架构上扩展性好的团队往往不是微服务用得最多的而是模块边界划得最清楚的。4. 安全性架构评审时最容易被一带而过出事时最措手不及4.1 安全架构的基本盘纵深防御思维安全性在架构设计的五要素里属于“平时看不见、出事要命”的那种。很多技术方案在评审时安全性只被当成一个“等上线前做个扫描”的收尾事项。但真正的安全架构必须内嵌在系统设计里而不是事后补丁。一个基本思路是纵深防御即使攻击者突破了第一层防线后面还有第二层、第三层等着。网络层面有防火墙、WAF、安全组规则限制不必要的端口和流量应用层面有身份认证登录验证、授权控制权限校验、参数校验、防SQL注入和XSS的过滤逻辑数据层面有传输加密TLS、存储加密比如数据库落盘时对敏感字段做加密、敏感数据脱敏比如手机号、身份证、银行卡号在日志和界面上的打码展示运维层面还有堡垒机、审计日志、权限回收机制。这里说几个我实际见过的问题。有一个项目使用了开源的后台管理系统默认密码没改被脚本扫描器直接扫到管理后台半个小时的功夫数据库就被拖走了。这是运维层面的安全缺失。另一个项目在接口设计时只做了登录校验没做越权防护——用户可以登录后把请求里的用户ID改成别人的绕过前端限制直接查看别人的订单数据。这是应用层授权设计缺失属于OWASP Top 10里排在靠前位置的“越权访问”。4.2 安全与性能、体验的平衡问题安全设计和性能经常正面冲突。全链路HTTPS加密会增加握手和加解密的开销数据落盘加密会增加数据库CPU负担每次请求都做细粒度的权限校验会让接口变慢。但这些成本是必须付的关键是付得聪明。比如HTTPS的性能损耗可以在网关层做TLS终止内部服务之间走明文内网链路当然敏感场景内部也必须TLS数据库加密如果代价高就只加密真正敏感的字段而不是整库加密权限校验可以做到“网关层做粗粒度校验服务层做细粒度校验”不要每个请求都层层重复。安全设计另一个让团队头疼的问题是木桶效应。系统的安全性取决于最薄弱的那一环哪怕服务代码写得再安全如果运维把数据库密码写在代码仓库里、或者云平台的对象存储桶权限设成了公开读写那前面做的全白搭。所以安全架构不能只让“安全团队”或“后端开发”来扛运维、前端、移动端都得纳入同一个安全基线。5. 五要素如何落地与权衡一套可复用的取舍模型5.1 根据业务场景确定要素优先级如果五要素是并列关系架构决策就很难做如果搞清楚当前业务的核心矛盾优先级自然就浮出水面。我给自己团队设计过一个简单的“要素优先级判断法”一共三步第一步明确系统的核心用户和核心价值。如果你是做在线交易的核心价值是“把钱安全地收下来”那么可用性和安全性天然排在前面如果你是做内容社区的核心价值是“内容量大、更新快、分发广”伸缩性和性能排在前面如果你是做企业内部流程系统的核心价值是“业务逻辑复杂但变更频繁”扩展性必须优先。第二步基于现状做一次容量和变化的预估。未来半年预计QPS增长几倍业务线会新增到什么程度团队规模会翻几倍这些判断决定了伸缩性和扩展性要预留多大的主动设计空间。我见过很多初创团队一上来就照着大厂规格设计微服务和多机房结果资源闲置、开发效率低反过来也有团队业务已经十倍增长还在单机扛着天天宕机救火——这两种极端的本质是一样的就是没有做自己的“第二步”。第三步把五要素拉成一个二维表格给当前项目打优先级分。比如业务类型最高优先级次优先级可以暂缓典型红线电商大促活动伸缩性、性能可用性扩展性不能超额扣库存支付/金融系统可用性、安全性性能扩展性资金不能错账企业内部管理系统扩展性可用性性能权限不能混乱初创MVP产品扩展性、可用性性能安全性基本达标即可数据不丢失这张表不用特别复杂但生成它的过程极其有价值因为它逼着团队说出“什么最重要”然后围绕这个答案做技术选型和资源投入。5.2 架构权衡时的兜底设计无论优先级怎么定架构评审时我都要求方案里必须包含三样“兜底设计”降级开关、灰度发布、快速回滚。降级开关是在依赖的第三方系统异常时主动切换到本地默认逻辑或缓存数据保证主流程不中断。灰度发布是新功能先放给5%的用户观察日志和报错没问题再逐步放量。快速回滚是发布后出问题能在几分钟内回到上个稳定的版本这听起来基础但很多团队在容器化改造前根本做不到——发布靠手改文件回滚相当于重来。这三样东西本质上是给五要素的取舍留一个“后悔药”。你可以在评审时倾向于性能和扩展性但如果出了架构性风险降级、灰度和回滚能让你有空间快速纠正。架构设计永远不是一次性决策而是一系列可以在运行中修正的决策。6. 常见架构设计问题与排查技巧实录6.1 五个高频踩坑现场架构设计领域的坑说来说去反反复复出现的就那么几个第一个坑是过度设计。团队只有十来个人业务还在验证期就已经搞了十几个微服务加分布式事务加多机房。代价是开发效率断崖式下降——改一个接口要跨三个服务发四轮评审。过犹不及这个成语就是在描述这种现象。第二个坑是重试风暴。前面提到过某个下游服务出现超时上游服务每层都加超时重试流量被放大好几倍把整个链路拖垮。问题本质是团队只看到了“重试可以增加成功概率”没看到“无限制重试会放大故障”。第三个坑是缓存踩踏。高并发场景下缓存key失效的一瞬间大量请求同时打到数据库数据库直接被打挂。解决方式包括互斥锁重建缓存、逻辑过期、缓存预热、多级缓存但很多团队是在缓存雪崩发生之后才开始研究这些。第四个坑是忽略数据层架构。服务层的伸缩性做得不错但数据库还是单点连接数一打满就全站瘫痪。数据层永远是架构伸缩的硬瓶颈单库变分库、主从变多活的每一步都伴随着巨大的重构成本必须早做规划。第五个坑是安全只做表面。登录接口做了密码加密就觉得安全没问题了实际上越权、批量拉取、日志泄露这些更深的问题完全没覆盖。安全不是某个点而是贯穿全链路的一条线。6.2 排查问题的思路与工具架构问题排查最重要的不是工具而是定位的思路。用户反映系统慢不要急着去翻代码先从链路角度分层检查用户网络是否正常、CDN是否命中、网关有没有超时、服务CPU是否高、数据库有没有慢SQL、缓存有没有穿透。每一层消耗了多少时间用数据说话。工具层面一套完整的链路追踪系统比如SkyWalking、Zipkin、Jaeger或云上的APM服务几乎是现代架构的标配。它能把一个请求经过的所有服务节点串起来显示每个节点的耗时这样定位瓶颈就不是靠猜而是直接看时间瀑布图。日志系统方面ELKElasticsearch、Logstash、Kibana或Loki这类工具可以让你在海量日志中快速检索错误堆栈。监控告警方面Prometheus加Grafana基本是社区的标准组合了。再分享一个实战中总结出来的排查习惯每次故障处理完都要补一份“半小时复盘”。不用写长篇报告就问三个问题故障的直接原因是什么系统哪个环节的防御没起作用架构上能怎么改下次就不会再犯这个习惯坚持下来比任何监控工具都管用因为大部分故障的根本原因最后都指向了架构设计时某个没有想清楚的决定。6.3 最后的几点个人体会架构设计做了这些年我自己的感受是五要素不是一道算术题没有“最优解”只有“最合适当前阶段的解”。团队刚起步时我甚至没花太多精力在伸缩性上因为用户量就那么多但对扩展性的投入始终没省因为业务迭代太快不改就得返工。后来业务量上来了才花大力气补伸缩性、做容器化、做自动扩缩容。另外架构评审时我会格外警惕一种“神话思维”——只要用了某个新框架、某种微服务模式、某个云厂商托管产品就默认系统具备了高性能、高可用。架构设计的能力恰恰体现在你能识别出那些被神话包装掩盖的真实短板。技术选型只是开始后面源源不断的压测、调优、演练、复盘才是架构真正走向成熟的路径。最后给大家一个行动建议下一次做架构设计或方案评审时不要只画框图、聊技术栈先把五要素的优先级表拿出来让团队每个人都填一版“我认为哪些最重要、哪些可以放弃”开会时对照讨论。这个动作我试过多次几乎每次都会发现团队对架构目标的认知分歧——而这些分歧如果不解决后面所有设计细节都会埋雷。