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

资讯详情

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

后端技术栈演进史:从单体到微服务,我们经历了什么

后端技术栈演进史:从单体到微服务,我们经历了什么 不知你有没有见过那种凌晨两点的to B系统一台32核128G的物理机跑着Spring MySQL数据库连接池被打满GC日志刷得像疯了一样滚动。运维工程师在键盘前念叨“为什么当初要用单体”。可就在他手边那份三年前的技术选型评审表上清清楚楚写着“当前业务规模单体最合适。”单体不是落后的代名词而是每个系统在特定生命周期里最诚实的答案。那时候一个WAR包扔进Tomcat部署就是重启测试就是点几个链接SQL拐个弯就能查到任意一张表。整个团队对系统的认识可以浓缩进一个IDE的断点里。每一个新人都能在半天内从入口Servlet追到最后的JDBC这种“全知视角”让早期业务跑得像刚出栏的野马。代价是当流量从一百涨到一万当产品经理开始把“随便改一下”挂在嘴边那个我们曾经引以为傲的WAR包开始变得像一只越滚越大的雪球你推得动它却再也刹不住车。拆分的冲动源于一次事故。某个促销活动里一个死循环把CPU占满整个电商系统停摆——包括本该正常发货的订单模块、本该正常登录的账户模块。于是所有人都意识到一个模块的失控正在剥夺所有模块的生存权。拆分就是不把鸡蛋放在同一个篮子里更是要把那几颗特别调皮的鸡蛋单独挑出来给它们单开一个灶。第一刀往往切得极其粗犷用户服务、订单服务、商品服务。每个服务一个数据库每次发布不再看整包的颜色而是看某个服务的版本号。技术栈也开始失控这个服务用Java写那个服务突然用Go写——理由是“Go的并发模型更适合这个长连接场景”。微服务是一场技术民主化运动每一个团队都赢得了选择语言的权利却也默认接受了分布式带来的所有惩罚。从前本地接口直接调用现在变成了HTTP或者RPC网络超时、重试、幂等、分布式事务像幽灵一样缠了上来。最典型的下场一个简单的“下单”操作从前是一条SQL现在变成了六个服务之间的接力赛。A服务写入订单B服务扣库存C服务通知物流D服务给积分……如果B成功了C失败整条账怎么平那段时间所有后端工程师案头都至少放着一本《分布式系统原理》前五章翻阅得最勤后面的章节直到系统总是出问题才回过头来认真研读。分布式事务的最终一致性本质上是把“正确性”从数据库的可靠里剥离出来扔给一堆业务代码去背锅。再往后容器成了新世界的“集装箱”。Docker让服务有了统一的交付物Kubernetes则像个不知疲倦的港口调度员把成千上万个Pod搬来搬去。这是我们技术栈演进史上最具戏剧性的一幕过去我们小心翼翼地呵护机器生怕它宕机现在我们用代码定义机器让机器本身成为可随时销毁的畜力。你还记得那些年对配置文件里面的IP地址的恐惧吗在虚拟机时代一台新服务的上线流程是采购流程、申请资源、手工装JDK、手工调参数、配置负载均衡……快则三天慢则一周。而在K8s的时代一条yaml文件搞定一切滚动发布无需停服副本数自动扩缩。架构的核心命题从“如何让这个进程跑得更稳”变成了“如何让这个进程死后不影响别人”。容器化带来的直接后果是技术栈的“亚原子化”。你想用Redis做缓存直接部署一个Redis Pod你想用RabbitMQ直接起一个中间件。原先那个号称“大而全”的一体化技术栈被拆成了一个个小积木。中台一度被奉为圭臬结果很多中台变成“比单体还笨重的共享库”。每个业务线为了所谓的复用不停往中台里塞接口最终形成一个分布式大泥球。我见过一个金融服务中台里面有超过三百个“复用接口”但真正被两个以上业务调用的不到三分之一。剩下的都是“为了统一而统一”的僵尸服务。这让人想起《人月神话》里那句经典的话“系统软件的每部分都做正确并不够系统必须是架构师所设想的样子否则它就是一堆无效的累赘。”服务网格和云原生像是给微服务装上了一层“透明血管”。Istio、Linkerd的出现把流量管理、熔断、限流从业务代码里抽离出来让业务开发重新回到纯粹的CRUD。可这种优雅是有代价的你不仅要业务团队学会应对分布式还要额外培训一个运维团队去维护网格控制面且每一个服务调用都经过了代理延迟多了几个毫秒。不少团队在走过轰轰烈烈的微服务之路后开始痛苦地反思我们到底是为了解决什么问题才拆的如果只是为了让二十个开发不再冲突那拆到十个服务差不多就够了如果只是为了高并发可能单体加缓存加消息队列更省心。于是“模块化单体”被重新抬上桌面成为一种略显讽刺的“回头路”。真正的演进从来不是线性替代而是在每个时期选择当下最合适的复杂度处理方式。比如新立项的业务系统起始阶段唯一正确的架构就是单体——但要刻意保持模块边界清晰用Maven/Gradle Module或者Go Module把业务模块先用代码工程切分好。这不是向历史倒退而是带着对未来的敬畏往前走。当团队规模超过“两比萨团队”后再根据模块的独立生命周期逐个拆成服务。技术栈老练的团队都明白先把模块之间的边界画好比先决定用什么框架重要一百倍。后来的我们还经历了所谓的“无服务化”——Serverless。Lambda函数这种技术彻底把后端从“服务器管理”里解放出来。很多人欢呼终于不用管什么容器和Pod了我们只需要写一个函数平台负责执行。但很快发现Serverless对冷启动、对持续连接、对长任务运行极不友好。那些被微服务拆得精细的接口到了Serverless平台上反而更折腾。技术栈演进本质上是在一次又一次地挑战“魔法层”的边界容器化是魔法服务网格是魔法Serverless也是魔法——但魔法的底层永远是更复杂的调度、更细粒度的IO、更严苛的延迟预算。你以为你在向上抽象其实你在向下坠入更深的混沌。现在回头望整个后端技术栈的演进路径就是一部人类与复杂性的对抗史。单体时代我们用进程内复用对抗重复开发换来的是部署半径巨大的脆弱微服务时代我们用网络边界对抗牵一发动全身换来的是跨服务的调试地狱到了云原生我们用声明式API对抗环境差异换来的又是新的学习曲线和不可控的依赖关系网。每一次架构转型本质上都是在把原来的复杂度从某个象限挪到另一个象限而不是消灭复杂度。真正被淘汰的从来不是某种技术而是“一种技术包打天下”的幻想。我们经历了从“一台机器跑一个进程”到“一个集群跑一万个进程”的狂飙经历了从“面向数据库编程”到“面向API编程”的转身经历了从“救火式运维”到“声明式回归”的循环。这些经历让我们明白技术栈不是越新越好而是越匹配越好。微服务是组织沟通方式的镜像如果你所在的团队连一个30人的微信群都管理不好那拆出来的服务迟早会变成彼此甩锅的修罗场。单体时代大家在一个代码仓库里被迫协作微服务时代大家终于可以在各自的仓库里自由却也失去了对全局的掌控——这不是技术问题而是一个社会学问题。如今那些最老练的架构师不再轻易提“为未来预留扩展性”因为他们见过太多为未来预留出来的微服务最终只是给后任留下了一堆需要维护的死代码。架构演进最珍贵的能力是在早期坦然地做加法在中期勇敢地做减法在晚期谨慎地做乘法。当我们从单体走到微服务最大的收获不是那些炫酷的框架而是认清了一个朴素的事实任何演进都是有代价的你要换的从来不是技术栈而是你对系统复杂度的承受能力。未来的后端栈大概率会继续朝着更细的粒度、更高的抽象演进但作为经历者我们已经不再迷信任何名词。我们心里那块压舱石是那几行CRUD也能跑出十万QPS的朴素能力是在一个请求从网关走到数据库时你脑子里能清晰画出它走过的每一根“管道”——无论那是单体里的堆栈还是微服务里的一串IP。技术栈可以一直往前走但一个工程师的底气始终来自于他能不能看懂系统每一个字节的去向。这就是我们从单体到微服务真正经历的历史。
返回列表