尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

理解后端架构:从单体应用到微服务的演进

理解后端架构:从单体应用到微服务的演进 十年前一个后端系统往往意味着一个巨大的代码仓库里面按业务模块划了几十个包编译一次要喝掉半杯咖啡。Team分工也简单前端催接口后端改接口测试点页面全公司只有一个人知道数据库表结构长什么样。那时候没有人质问“架构”这个词因为系统还在跑业务还在涨加班还没到凌晨三点。单体架构不是一种罪恶它只是把复杂性暴露在了一个看似安全的地方——所有代码共享一个进程所有调用都在内存里所有异常都是全局异常一切尽在掌握直到某一天掌握不住了。单体的黄金时代单体架构最初的优势朴素而致命简单。你不需要理解微服务、消息队列、分布式链路追踪只需要一个jar包或一个dll扔到服务器上跑起来就行。对于早期业务这几乎是最优解。在没有流量压力时单体架构是最优解这句话没有任何反讽成分。维护成本低调试效率高事务一致性天然成立一条SQL能解决的事绝不需要两个服务来回握手。很多创业公司就是靠单体撑过了最关键的生死期这不是什么光荣的往事而是性价比的必然。但单体架构的麻烦像老房子里的白蚁等你发现时承重墙已经酥了。业务代码纠缠成一团编译时间从十秒涨到十分钟每次发布都像在雷区里散步。更要命的是任何一个模块的流量高峰都会拖垮整个系统——比如一个双十一秒杀活动把核心会员服务直接打挂你根本找不到是哪个线程在怒吼。单体架构真正的瓶颈不是技术而是“所有东西都在一起”所导致的恐惧感——没有人敢重构没有人敢删除没有人敢说“这块代码我负责”。被逼出来的拆分拆分的冲动往往来自一次惨痛的故障比如凌晨两点的发布事故或者一个无关接口的流量洪峰。你会想要是把订单服务和用户服务隔开至少用户登录不会被订单拖死。这个想法朴素而正确。微服务不是技术选择而是组织沟通成本演化出来的必然结果——当十个团队都往一个代码仓库提交时任何一次合并都是一场政治博弈。一开始拆分很策略性按业务边界把几个核心模块抽成独立服务用HTTP或RPC通信。你会发现快乐是暂时的因为立刻要面对网络问题超时、重试、限流、熔断、降级、幂等。以前是一个函数调用现在是一次远程旅行对方可能宕机可能挂起可能返回一个无法解析的垃圾。分布式系统最大的谎言是“网络是可靠的”这句话你迟早会在生产环境里用血学到。分布式之痛当你拆出第一个微服务时你觉得自己掌握了架构的真谛。紧接着第二个、第三个服务也拆出来整个系统的拓扑图开始像一棵疯狂生长的藤蔓。调用链从A到B到C再到D然后D回调A你开始画时序图画到一半就放弃了。微服务把代码上的耦合变成了网络上的通信表面上解耦了实际上把复杂度转移到了运维层面。分布式事务会逼疯每一个后端工程师。原来一个本地事务可以保证扣库存和下单的原子性现在得靠消息队列、最终一致性、本地消息表、Saga一整套神仙操作。你以为你在做架构实际上你在做哲学思辨——什么是一致性什么又是最终最终一致性的“最终”通常是凌晨两点而你正在被产品经理夺命call。更讽刺的是很多系统根本不需要那么复杂的分布式事务只是拆得太碎反而用一堆基础设施去弥补原本不需要弥补的问题。数据的地盘代码拆分只是第一步数据拆分才是真正的鸿沟。数据库分拆是比代码拆分更痛苦的旅程因为数据不像类和方法那样可以随时移动。你曾经用一个外键就能关联订单和用户现在订单在库A用户在库B跨库查询变成了梦魇。你不得不引入缓存、搜索服务、数据同步管道甚至为了一个简单的列表页要聚合三个服务的数据。有时候你会怀疑我们到底为了什么拆分数据层面的耦合根本拆不干净用户身份、操作日志、支付回调、库存变更这些数据天生就是纠缠的。以为拆分数据就能隔离障碍结果只是把障碍从一个地方搬到了另无数个地方。而每个地方都需要etl、同步、校验、补偿你需要为数据的一致性写一大堆定时任务然后每天凌晨看它们执行结果祈祷没有红点。康威定律的裁决你很快会发现一个残酷的规律微服务的边界永远不是技术画出来的而是公司的组织架构画出来的。康威定律决定了架构的最终形态你无法让一群按前端组、后端组、数据库组划分的团队做出真正服务化的系统。如果你的组织里还有“DBA岗”和“运维岗”那么微服务就会变成一组频繁跨部门开会、互相等待的pipeline。真正的微服务变革必须先重组团队。每个服务一个全功能团队包含开发、测试、运维、DBA自己掌控整个服务的生命周期。这比拆代码难十倍因为你要拆的是权力和职责。很多公司拆了代码却保留了原来的组织架构结果服务之间依然依赖关系暧昧接口变更要发邮件群聊、开会评审、层层审批复杂度没有消失只是换了个地方憋屈。可观测性不是可选当你有几十个微服务每个服务部署多条实例请求在服务间跳跃任何一次失败都像大海捞针。没有可观测性的微服务是一场慢性的灾难——你根本不知道哪里慢了哪里错了哪里挂了只能靠用户投诉和监控大屏上通红的数字来猜。日志不再意味着一个文件的tail而是分布式链路追踪、指标聚合、日志收集、告警规则、trace id全链路透传。你需要一套完整的可观测性体系日志、指标、链路、告警。然后你要为这套体系本身运维——ES集群、Prometheus、Grafana、Jaeger、Loki还有它们各自的存储、高可用、备份。可观测性不是“锦上添花”而是微服务架构的默认前提省略它的代价是每次事故都从“重启大法”开始。很多团队在微服务路上跑了一段发现一半的精力都在处理观测工具业务代码反而成了配角。运维战争的日常微服务带来的不只是代码拆分还有一整套基础设施的复杂度。每个服务要有CI/CD流水线、容器镜像、配置中心、注册中心、网关、熔断器、分布式配置。你从写业务变成了“搭台子”从Java工程师变成了YAML工程师。每一个微服务都意味着一个需要监控、升级、备份、扩缩容的独立宇宙它们互相纠缠、偶尔冲突、悄悄把磁盘写满、把CPU烧到爆。Kubernetes成了标配你以为它能解决一切结果它带来了新的一层复杂性Service Mesh、Ingress、HPA、PV/PVC、网络策略、资源配额。你为了管理复杂的服务又引入了更复杂的系统来管理这些复杂的服务。程序员开始像敬畏上帝一样敬畏k8s碰到问题不查代码先查集群最后发现是系统时钟偏移导致的诡异故障。运维战争从未结束只是从机房搬到了云上从手工脚本变成了声明式配置。演进而非革命很少有人是白手起家从零开始微服务的绝大多数人都是在单体上修修补补拆一个服务就折腾一个月。最务实的路径不是推倒重来而是“绞杀者模式”用新服务一点点替换单体中的模块让老系统逐渐萎缩直到无处可缩。这不是什么新概念但执行起来需要极强的纪律。你得控制服务粒度不能拆得太碎更不能为了微服务而微服务。一个服务应该多大理想粒度的判据不是代码行数而是“能否由一个两到九人的团队独立拥有并全生命周期负责”。如果你的服务需要跨三个团队才能改一条字段那它就不是微服务而是一块散布在网络上的巨型砖头。从单体到微服务本质是一次持续的交割把本来集中在代码里的复杂性分散到组织、流程和基础设施中。你不该追求架构的“先进”而该追求架构与组织的匹配度。微服务的真相很多人问了半天最后发现自己需要的其实是一个模块化单体——分清楚模块边界、保持代码整洁、用接口隔离依赖然后在必要时单独部署几个热点模块。微服务不是免费的午餐它是一顿昂贵的自助餐吃的时候兴奋结账的时候肉疼。如果你只有三个服务却专门为了它们建设了完整的微服务治理平台那这平台本身就是最大的架构负债。真正的架构演进永远是为了让业务跑得更快而不是为了简历上的技术名词。当你觉得微服务“很酷”的时候请先把它翻译成“我们愿意承担分布式、数据一致性、运维可观测性、跨团队沟通的额外成本吗”。如果答案是犹豫那你的系统其实仍在单体的黄金时代里过得很好。架构没有终点只有成本而每一次演进都是在用新的复杂性偿还旧的复杂性留下的债。理解这一点比背一百个架构名词更重要。
返回列表