十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

电商系统高并发架构演进:从单机到千万级QPS的完整路径

电商系统高并发架构演进:从单机到千万级QPS的完整路径 做过电商后端的人应该都有这种感觉一个系统从单机跑到千万级并发中间不是某一次大改造的结果而是一连串“被业务逼着走”的架构演进。我刚入行时维护过一个典型的单机电商系统一台服务器扛着应用、数据库、图片存储最夸张的时候每天下午高峰CPU跑满用户点个结算要转三秒。后来一路做到日订单量百万级、大促峰值几十万QPS的系统中间踩过很多坑也积累了不少经验。这篇文章不绕弯子直接讲清楚电商系统从单机到千万级并发要经历哪些阶段、每个阶段该选什么技术、为什么做这个选择以及实际落地时最容易翻车的地方。文章后面会给出不同业务量级下的技术选型对照表和场景适配思路供你直接参考。不管你是刚接手一个小电商项目还是在规划下一个大促的容量方案这篇内容都值得认真看一遍。1. 内容整体设计与思路拆解1.1 从单机到千万级并发的本质是什么先说一个核心认知千万级并发从来不是一个“点”的问题而是一条“链路”的问题。单机系统之所以撑不住不是因为某一台机器不够强而是因为所有请求都挤在同一条窄路上应用逻辑占CPU、数据库占磁盘IO、静态资源占带宽三者互相抢资源。把这条链路拆开看核心瓶颈就那几个。数据库往往是第一个被打垮的因为关系型数据库的处理能力天然有限一台普通物理机跑MySQL撑死也就几千QPS应用服务器本身弹性不错但一旦有慢SQL拖住连接池整个服务就跟着雪崩带宽和磁盘IO在大流量图片、商品详情页面前也是硬伤。所以架构演进这件事本质上是不断把“原来挤在一起的东西”拆开、分流、加缓冲。每到一个新量级就要解决一个主要矛盾。单机时代解决的是“能不能跑起来”读写分离解决的是“数据库别死”缓存解决的是“热数据别老查库”服务化解决的是“团队协作和故障隔离”到了千万级并发阶段还要考虑多机房、多活、全链路压测这些系统性工程。1.2 我给这篇文章设计的路线图我把整个演进过程分成五个阶段每个阶段对应一个核心问题和一套配套技术栈单机阶段应用数据库存储都在一起解决“从0到1”的问题。读写分离阶段应用与数据库分离主从复制解决“读多写少”的问题。缓存与消息队列阶段引入Redis和MQ解决“热点数据”和“峰值流量”的问题。服务化与微服务阶段按业务域拆服务解决“团队协作”和“故障隔离”的问题。最终高并发阶段分层架构多活全链路监控解决“高可用”和“大规模流量调度”的问题。后面每一章都会详细讲该阶段的架构形态、关键选型和落地细节。有基础的读者可以直接跳到第5章看千万级架构全貌新手建议从头按顺序读因为每一层都是下一层的前提。2. 单机阶段一切从简单开始但别把简单做成简陋2.1 单机电商的典型拓扑与容量天花板电商系统刚起步时最典型的就是一台服务器搞定所有事Nginx部署在同一台机器上Tomcat跑应用MySQL存数据图片直接放本地磁盘。这种架构的好处是部署简单、运维成本几乎为零适合验证商业模式、跑通核心流程。但单机系统的容量天花板非常低而且不是线性增长的。我实测过的数据是一台4核8G的云主机Tomcat默认配置下去掉静态资源请求后动态接口的QPS大概在300到800之间MySQL在同一台机器上简单查询大概能支撑2000 QPS一旦出现多表关联或者深度分页直接掉到几百。最关键的是应用和数据库互相挤占资源CPU满的时候数据库也快不了数据库慢的时候应用也等着整个系统处于一种“怎么调都不爽”的状态。单机阶段还需要特别注意磁盘和带宽的问题。商品图片如果是本地存储一张图几百KB1000个并发请求就能把带宽打满这比CPU和数据库更早成为瓶颈。我当时第一次遇到线上事故就是因为大促海报图放本地结果带宽被图片请求占满接口全部超时。2.2 单机阶段该做什么、不该做什么虽然单机很简单但很多团队恰恰在这个阶段埋下了后来的大坑。我的建议是代码层面的规范从第一天就要立好但架构层面的过度设计完全没必要。要做接口做好参数校验和异常处理数据库建好索引关键业务埋好日志和监控指标静态资源走CDN或者至少用独立域名。不要做不要一上来就拆微服务不要为了“以后扩展”引入一整套分布式框架不要用消息队列解耦两个根本不存在流量压力的内部模块。这个阶段的“技术选型”其实就一句话用你最熟、社区最稳的方案。Java生态就用Spring Boot MySQL RedisRedis哪怕只做缓存也是值得的PHP就用LNMPGo就用Gin PostgreSQL。不要在小流量阶段为了简历好看引入一堆自己都搞不定的组件。注意单机阶段最容易忽视的是“日志和监控”。很多团队觉得量小不需要监控等量上来再补。但实际上量一起来日志格式不统一、没有全链路TraceID排查问题会痛苦到怀疑人生。哪怕只有一个节点也建议从第一天就打上TraceID后面所有框架演进都建立在日志规范的基础之上。3. 应用与数据库分离第一次质的飞跃3.1 为什么先拆数据库而不是先拆应用业务量上来之后第一个撑不住的一定是数据库。应用服务器是无状态的大不了多部署几台挂在Nginx后面但数据库是有状态的数据要一致、事务要保证没法简单横向扩展。所以我建议的演进路线是先把数据库和应用物理分离用独立的数据库服务器同时把图片等静态资源迁到OSS或CDN然后才是读写分离。数据库独立之后应用服务器可以横向扩容到多台Nginx做负载均衡数据库的压力不再受应用CPU影响。这一步做下来动态接口QPS通常可以从几百提升到两三千数据库也可以单独调优配置更适合自己的参数。但要注意一个问题数据库和应用分离之后网络延迟会从原来的毫秒级变成零点几毫秒到几毫秒连接管理变得更重要。原来直连数据库的连接池配置在多应用实例下要重新规划不然每个实例都开一堆连接数据库连接数很快被打满。我见过最夸张的情况是20个应用实例每个连接池配了200个连接直接把MySQL的连接数打爆。3.2 读写分离的落地细节与踩坑经验当系统呈现出明显的“读多写少”特征时电商场景下读写比例轻松超过10:1读写分离就该上线了。主库负责写从库负责读通过MySQL主从复制同步数据。读写分离的落地有几个关键细节很多人第一次做都会忽略主从延迟问题的处理。MySQL主从复制默认是异步的高峰期延迟可能到秒级。用户下单后立刻去查订单列表如果命中从库很可能查不到刚写入的数据这就是经典的“主从延迟读不到自己写”的问题。解决思路有几种关键读请求强制走主库或者用中间件做“写后读同库”的绑定规则再或者接受短暂延迟并做前端交互提示。从库负载均衡与健康检查。多个从库之间要用负载均衡策略不能简单随机。ShardingSphere、MyCat或者代理层的ProxySQL都能做但要注意从库挂掉之后自动摘除的逻辑不然一个从库宕机会拖垮所有读请求。分库分表不是读写分离的自然延伸。很多团队把读写分离和分库分表混在一起做这是很危险的。读写分离解决的是读写争抢资源的问题分库分表解决的是单表数据量过大的问题两者没有必然关系建议分步实施避免一次改动太大导致风险不可控。实操心得做主从切换演练时不要只在文档里写“修改虚拟IP指向”要真的去把主库停掉看从库能不能顶上应用能不能自动恢复。我第一次做主从切换演练时发现业务代码里写死了主库IP根本不是走域名或VIP的方式结果主库一挂整个写链路直接瘫痪演练变成事故。这个教训值得每个团队引以为戒。4. 缓存与消息队列应对峰值流量的两大关键选择4.1 缓存选型为什么Redis是事实标准读写分离之后数据库的压力虽然在下降但高峰期热门商品的详情页、库存查询、购物车计算还是会集中打到数据库上。这时候如果不加缓存DB的QPS还是会冲到很高的水位而且大部分请求都是在查同一批热数据非常浪费。缓存选型这件事业界已经用脚投票了。Redis基本是事实标准因为它数据结构丰富、性能极高单实例10万QPS很轻松、支持持久化和集群模式。Memcached也有它的场景但如果你不是对内存碎片极其敏感、对多线程有刚性需求直接用Redis就够了省得维护两套技术栈。Redis落地时有几个细节要特别注意缓存key的设计要有业务前缀和版本号比如product:detail:v2:123这样就算序列化方式或者结构变了也可以通过切换前缀完成平滑迁移不用等缓存自然过期。缓存过期时间不要设置成完全一样的值要加一个随机偏移量否则大量key同时过期数据库会瞬间被打满这就是缓存雪崩的常见成因。缓存更新策略电商场景下我推荐“Cache Aside”模式读的时候先读缓存没命中再读数据库并回填写的时候先更新数据库再删除缓存。这种模式比先更新缓存再写数据库更稳因为删除操作天然规避了并发写缓存时的数据不一致问题。4.2 消息队列选型与其他功能解析用于削峰填谷和系统解耦消息队列比缓存更晚一点引入但一旦引入整个系统的“韧性”会完全不一样。它的核心作用是削峰填谷和系统解耦订单创建时不需要立即同步调用库存、积分、短信、推荐等一堆服务只要把订单事件丢进MQ后面的消费者慢慢消费就行。消息队列选型对比组件优点缺点适用场景Kafka吞吐量极高生态成熟适合大数据量日志和事件流功能相对简单延迟略高需要搭配ZooKeeper或KRaft订单事件流、日志采集、大数据分析RocketMQ功能丰富事务消息、延迟消息、死信队列Java生态友好吞吐略低于Kafka运维成本稍高电商核心链路需要可靠消息保障的场景RabbitMQ社区活跃路由规则灵活部署简单吞吐量有限大量堆积时性能下降明显中小规模系统简单任务队列电商核心链路我个人更推荐RocketMQ因为事务消息和延迟消息比如订单超时未支付自动关单在电商场景非常常用。如果公司已经有很强的Kafka运维能力也可以Kafka为主、必要时配合RocketMQ做事务消息但尽量避免老项目里同时维护三套MQ。用消息队列之后要处理的消息可靠性主要有三块生产者失败重试、消费者失败重试和死信处理、消息幂等。消息幂等是最容易被忽视的坑——Kafka的“至少一次”语义意味着消费者可能收到重复消息下单、扣库存、发券这类操作如果不做幂等重复消费会造成严重资损。好在电商业务天然有幂等键可以用比如订单号、操作流水号拿它们做唯一约束或去重表就能挡住重复消息的冲击。5. 分布式服务化从集中式单体到微服务5.1 服务拆分的原则与边界当团队超过二三十人、代码库达到几十万行级别时单体应用的问题会从“性能瓶颈”变成“协作瓶颈”。“改个库存功能要发布整个订单系统”这件事会越来越让人抓狂所以服务化拆分一定不是纯技术驱动而是组织效率驱动的结果。服务拆分首先要明确边界我常用的原则是“领域驱动设计DDD的限界上下文 团队结构对齐”。电商领域大致可以拆成用户服务、商品服务、库存服务、订单服务、支付服务、营销服务、物流服务等每个服务有自己独立的数据库至少是独立的Schema。但拆分不能一步到位要循序渐进。我的建议是先从最容易拆、收益最大的服务开始比如把用户服务和商品服务先拆出去因为它们相对独立被调用方多拆分后部署和扩容的弹性立刻提升。支付、订单这类强事务的核心链路则要谨慎等基础设施成熟了再拆。5.2 服务化之后的基础设施家族服务拆分之后原来的“一次调用”变成了“多次远程调用”需要一套完整的基础设施来解决服务发现、配置管理、流量控制、链路追踪等问题。注册中心和配置中心Java生态主要用Nacos或ConsulKubernetes环境下也可以直接用K8s的Service发现能力。Nacos比较适合国内团队因为中文文档完善、控制台好用支持服务注册发现和配置管理二合一能少维护一个组件。链路追踪必须上推荐SkyWalking也可以考虑兼容OpenTelemetry协议的方案。服务化之后排查问题最大的痛点是一个请求跨五六个服务其中一个慢了怎么定位没有链路追踪你只能挨个服务看日志效率低到崩溃。有了TraceID贯穿全链路用SkyWalking的Topology图一眼就能看到瓶颈节点。网关层也得认真设计Spring Cloud Gateway是应用层网关的主流方案负责路由、鉴权、限流在它前面再挂一层负载均衡器比如Nginx或云厂商的SLB。需要重点注意的是网关不能写“重业务逻辑”它只做转发和通用横切逻辑否则会变成新的性能瓶颈和单点故障。5.3 分布式事务与数据一致性微服务最大的坑服务拆分之后原来在一个数据库里用本地事务搞定的事现在变成了跨服务、跨库的分布式事务问题。订单创建要扣库存、锁优惠券、加积分这几个操作分散在不同服务里怎么保证一致性这个问题的答案取决于业务对一致性的要求强弱。支付、退款这类资金相关操作我推荐用RocketMQ事务消息或TCC方案把最终一致性做扎实一般业务比如下单后发短信、加会员积分用本地消息表MQ重试就够了不要动不动上Seata分布式事务带来的性能和复杂度开销很大。我自己在实践中的做法是“能不用分布式事务就不用”。在架构设计时尽量通过流程编排来规避跨服务强一致比如订单先创建成“待支付”状态支付回调之后通过MQ异步触发扣库存和发券哪个环节失败了就走补偿任务扫描重试。这样虽然引入了补偿机制但整个链路是异步化、可重试的稳定性比同步的分布式事务高很多。特别注意分布式事务的复杂度是呈指数级上升的每多一个参与方排障链路就长一倍。所以服务拆分时要把“事务边界”当成第一考虑因素宁可一个服务内多放几个聚合根也别为了“微”而硬拆。6. 千万级并发架构终局形态与容量规划6.1 分层架构全景从用户请求到数据存储到了千万级并发这个量级系统的架构已经不再是“某个组件”的问题而是整个架构体系的系统工程。我把它拆成六个层次来看接入层DNS轮询 多CDN节点 WAF防护负责就近接入、防攻击、静态资源加速。负载均衡层LVS/云SLB做四层负载均衡Nginx做七层负载均衡负责流量分发和基础限流。网关层Spring Cloud Gateway或自研网关做路由、鉴权、限流、灰度发布。应用服务层按业务域拆分的微服务集群容器化部署支持弹性伸缩。缓存与中间件层Redis Cluster做分布式缓存Kafka/RocketMQ做消息队列Elasticsearch做商品搜索。数据存储层MySQL分库分表 TiDB或OceanBase等分布式数据库可选 数据仓库/大数据平台。流量从用户点击开始先经过CDN和接入层过滤大部分静态请求再经过负载均衡和网关进入应用层应用层通过缓存和MQ来抵挡大部分实时读和突发流量最终只有一小部分请求真正落到数据库。这个漏斗模型是支撑千万级并发的核心。6.2 容量评估与压测方法不能拍脑袋千万级并发不是上线时突然达到的它一定是业务增长和大促推动的。容量评估最忌讳“拍脑袋”要基于历史数据和业务预期去做。我常用的容量评估方法分三步。第一步明确核心链路的“预估峰值QPS”可以通过历史峰值乘以业务增长系数比如1.5到2倍再加上大促秒杀的增量来估算。第二步把QPS换算成资源需求应用服务器单台能支撑多少QPS、数据库单实例能支撑多少QPS、Redis单分片能支撑多少QPS然后计算出所需实例数。第三步做全链路压测验证用压测得到的真实数据回推修正容量模型。以一台4核8G的应用实例为例简单业务接口压测下来大约是3000到5000 QPS复杂接口可能在500 QPS以下。假设你的核心链路需要10万QPS按单台3000 QPS来算应用层至少需要35台实例考虑到单机故障和弹性冗余实际要留30%到50%的余量就是50台上下。数据库层的容量要更保守。MySQL单实例写入QPS安全水位是2000到3000读QPS经过缓存过滤后落到DB的可能只有总流量的5%一万的读QPS用三四台从库就能扛住。但写流量没法缓存只能做分库分表或者上分布式数据库。全链路压测有两点经验值得分享。第一一定不要在业务高峰期直接对线上做全量压测要么搭一套镜像环境要么用压测工具做流量回放第二压测不能只看QPS达标还要观察响应时间P99、错误率、GC频率、连接池使用率这些数据它们才能暴露系统的真实瓶颈。6.3 高可用和单元化从单机房到三地五中心千万级并发系统还有一个隐藏要求——高可用。故障恢复不是“能不能恢复”的问题而是“多久恢复”的问题。一般系统要求99.9%每年宕机8.7小时以内电商大促期间的SLA会更高。高可用设计涉及几个层面应用层多实例部署任何一个实例挂了流量会自动摘除数据库层一主多从 半同步复制主库故障可以自动选主切换缓存集群用Redis Cluster分片之间互相备份。到了更高的可用级别就要做多机房部署和单元化改造。终极形态是“三地五中心”满足“同城两机房双活、异地容灾”的容灾要求任何单机房宕机用户无感知或仅在秒级内切换到其他机房。但我必须提醒一点单元化改造是架构演进的大工程不是中小团队应该优先考虑的事情。如果业务量还没到每天千万级订单不要碰这个方向。我在实际工作中见过太多团队业务还在百万级却花大精力做多活结果开发效率下降严重线上故障反而更多了。高可用不是通过复杂架构实现的而是通过演练、监控、快速恢复能力实现的简单架构极致的可观测性往往比复杂架构三地多活更可靠。7. 场景适配与技术选型别用大炮打蚊子7.1 不同量级下的技术选型对照表很多人问我看到各种技术名词就头晕到底该学哪个如果从电商架构演进的角度我建议你按照下表逐步走业务量级应用架构数据库方案缓存消息队列微服务中间件日UV 1万单机部署单体应用单库单表Redis可选不需要或RabbitMQ不需要日UV 1~10万多实例负载均衡主从分离读写分离Redis集群RabbitMQ/RocketMQNacos可选日UV 10~100万微服务化拆分分库分表ShardingSphereRedis ClusterRocketMQ/KafkaNacos Sentinel SkyWalking日UV 100万微服务网格/容器化K8s分布式数据库TiDB/OceanBase多级缓存Kafka RocketMQ混用服务网格 多活架构这个表只是一个通用参考每个团队的业务读多写少程度、事务复杂度、团队技术积累都不同。比如你是纯内容社区读多写少极其明显缓存和CDN权重就更高数据库的压力其实没那么大但如果你是交易系统写路径的一致性要求很高数据库方案和分布式事务就要花更多心思。7.2 技术选型的底层逻辑稳定性优先于新潮做技术选型的时候我总结了一套自己的决策框架核心就五个字稳定优先简单至上。每个组件至少要从五个维度打分社区成熟度、团队熟悉度、运维成本、扩展性、性能和功能匹配度。社区成熟度是硬指标。选一个长期维护、社区活跃、网上踩坑文章多的组件而你选了刚发布没多久、只有一两个成功案例的新项目上线后遇到一个诡异bug全网搜不到解决方案等于一个人在裸奔。团队熟悉度经常被忽略但我认为最重要。组件的功能再好团队里没人真正掌握它上线就是灾难。我自己就吃过这个亏曾经为了“业界最佳实践”引入了一个团队完全没接触过的存储组件结果上线第一个月每次故障排查都要花比别人多好几倍的时间。另外要注意避免在技术规划时过度追求“一步到位”。很多架构师喜欢在一开始就把所有组件都规划进去实际上造成了巨大的维护成本。我建议是“只用当前业务能证明必要的技术”每引入一个新组件都要有一个明确的、当下的业务问题在等着它解决而不是为了“未来可能需要”。8. 常见问题与排查技巧实录8.1 缓存三大经典故障穿透、击穿、雪崩这几乎是每个电商系统都会遇到的问题我把典型现象、原因和解决方案整理成一张速查表问题典型现象常见原因解决思路缓存穿透缓存命中率骤降DB QPS飙升请求查询不存在的key每次都打到DB布隆过滤器拦截缓存空值但设置较短过期时间缓存击穿单个热点key过期瞬间DB被打满超热门数据缓存失效时并发请求同时到DB互斥锁/逻辑过期热点key过期时间不设集体失效缓存雪崩多个key同时过期或Redis宕机DB被打爆缓存设了相同过期时间Redis集群故障过期时间加随机偏移Redis高可用多级缓存本地分布式排查时先用监控看“缓存命中率”和“DB QPS”两个指标哪个异常往下追。缓存穿透的概率最低但破坏力也不小尤其是在被恶意刷接口时一个不存在的商品ID就能把DB打挂。布隆过滤器虽然能挡住大部分但我更推荐“参数校验缓存空值”组合拳成本最低、效果最直接。8.2 慢SQL与连接池问题线上数据库性能杀手数据库慢SQL是架构演进各阶段都会遇到的问题。很多系统崩溃的“第一因”其实只是一个慢查询一条深度分页的ORDER BY、一个没走索引的多表JOIN、一个在查询条件里做函数计算的字段就能把数据库CPU打满接着连接池被占满所有应用请求排队超时系统雪崩。排查慢SQL我有一套标准动作先开慢查询日志找到Top N慢SQL然后执行EXPLAIN看执行计划检查是否命中索引、扫描行数是否合理最后针对问题SQL做索引优化或改写。关于深分页问题可以用“子查询延迟关联”或“游标分页”替代传统的LIMIT加大偏移。连接池参数也值得认真调。HikariCP的maximumPoolSize不是越大越好连接太多反而增加数据库上下文切换开销。我通常设置为核心数 * 2 1左右再根据系统压测结果微调。很多团队把连接池设成几百结果数据库连接数成为瓶颈应用之间互相拖垮。排查技巧遇到应用偶发超时但看CPU、内存都正常优先查连接池等待时间和GC日志。我在真实环境中排查过很多次“没有明显资源瓶颈但接口偶发很慢”的问题最终定位都是Full GC导致的STW或者是数据库连接获取超时。8.3 消息堆积与重复消费MQ使用中的高频问题消息堆积是最常见也是最容易判断的问题监控里Lag堆积数持续上涨消费者处理的速率跟不上生产速率。原因要么是消费者的处理逻辑太慢比如消费时调外部接口超时要么是消费者实例数不够要么是某个错误导致消费线程卡死。排查思路先看消费组每个实例的消费速率和错误日志如果错误日志里有重试异常优先解决这个异常绝大多数堆积都是消费逻辑有bug导致不断重试如果消费正常但速率不足再考虑增加消费者实例或者调整批量消费参数。重复消费的问题同样高频。Kafka的“至少一次”语义加上消费者的自动提交offset机制在网络抖动或者Rebalance时很容易出现重复消费。解决思路前面已经提过最重要是幂等。消费者代码里必须对每条消息做“是否已处理”的检查用数据库唯一键兜底不要相信MQ的重试机制能帮你挡掉重复。8.4 流量突刺与限流降级大促保命的最后防线架构再完善总有预估不到的流量波峰。流量突刺对冲要用限流和降级来兜底。限流我常用的策略有三种固定窗口、滑动窗口和令牌桶。令牌桶因为允许一定程度的突发流量最适合电商场景。网关层的限流比如Sentinel配合Spring Cloud Gateway可以做入口级保护应用层的限流可以针对特定接口做更细的控制。降级则是主动关闭非核心功能来保护核心链路比如大促时把积分查询、推荐feed降级优先保住下单和支付。这里要强调一点限流和降级策略不能只写在配置里一定要做线上验证。我见过很多团队把Sentinel规则配置好了但没测过触发后的表现结果一到大促限流生效时用户直接看到错误页比不限流还惨。正确的做法是限流触发后返回一个友好的降级响应比如“排队中请稍后重试”而不是报500错误降级开关要可配置、可快速生效最好能在1分钟内全量生效。9. 最后几点个人体会架构演进这条路走过一遍之后回头看最大的感悟是大部分问题都不是技术不够而是对业务的理解不够。同一套架构放在不同的业务场景下结论可能完全相反。读多写少的内容社区和强事务一致性的交易系统技术选型和架构演进路径应该不一样一个日均万级UV的创业项目和千万级并发的大厂系统更不应该用同一套标准去规划。我现在做技术方案时一定会先问三个问题当前业务量级在什么位置核心链路的核心痛点是什么团队能力能支撑什么复杂度把这三个问题想清楚了技术选型其实是水到渠成的事。单机阶段的简单直接、读写分离的务实、缓存MQ的立竿见影、服务化的组织效率革命、千万级并发的系统工程每一步都不需要赶时髦只需要解决当时最痛的问题。如果你正准备规划自己系统的演进路线我的建议是把第7章的技术选型对照表打印出来贴在工位上对照表的位置走不要跨级跳更不要一步到位搞微服务。先让系统稳定撑住当前业务再想着为未来做什么准备。每个阶段踩过的坑、积累的监控数据、调优经验都是下一阶段架构演进最宝贵的输入。记住架构是长出来的不是设计出来的。
返回列表