2 01 | 是什么推动了单体应用到微服务架构的演进?
你好,我是姚秋辰。
“微服务”是近些年在大型应用架构领域的一个热门话题,从实践领域来看,我们身边的一二线大厂也纷纷选择全面拥抱微服务。就拿国内Java系的一线大厂来说,如阿里系、美团点评、PDD等,它们都将自己的核心业务系统构建在微服务架构之上。
即便你是刚参加工作的萌新,也一定从铺天盖地的“微服务”相关信息流中了解到了这个名词的热度。谷歌搜索指数显示,自2014年起,微服务的搜索热度一路上升。
其实,微服务并不是一个新兴的技术概念,很早之前它就已经进入了公众视野。
早在2012年,一位叫做Fred George的技术专家就在一次大会上分享了自己的微服务落地经验,讲述他是如何带领团队将一个极度庞大的J2EE巨无霸程序,分解成20多个小服务的。作为微服务领域的先驱,他是这样描述微服务架构的:
Micro Services Architecture - small, short lived services rather than SOA.
如果你在工作中没有接触过微服务架构的系统,那么此时一定非常蒙圈,不明白大佬所说的微服务架构到底是什么。没关系,就让我带你去回顾微服务的发展历史,了解微服务解决了什么痛点;然后我们一道来分析微服务架构的优势,让你明白为什么如今一线大厂会采用微服务架构。
那么,我们就从微服务架构的前世今生聊起吧。
单体应用之殇
在互联网技术发展的早期阶段,我们采用“单体应用”的方式来构建网络系统。你没看错,即便是如今的各大老牌互联网大厂,在当年也是从单体应用小作坊成长起来的。
以Java单体应用为例,我们将业务逻辑打包在一起,做成一个WAR包部署到Tomcat、JBoss之类的容器中,对外提供服务。业务上了一定规模之后,再通过集群化水平扩展的方式,将单体应用部署到一个集群中,承接更大的用户访问量。
然而,随着业务复杂度的进一步提升,单体应用在生产力和高可用性层面就面临了巨大的挑战。我在参加工作之初做过近五年的单体应用开发,深知其中的痛处。
我刚毕业的时候,参与了一个巨无霸的电商套件的开发,那是一个标准的单体应用。整个开发加测试团队有100多号人,所有人的代码都提交到一个主干分支,每次merge代码都要面对各种代码冲突,开发过程中耗费了大量的沟通成本。不仅如此,由于庞大的业务体系都部署在一个WAR包中,每一次提交代码都要执行3个小时的回归测试,不出错还好,一旦出错就要回炉重造。周而复始执行这套繁重的流程,研发效率非常低下,完全无法达到“快速迭代”的目的。
在上线阶段我们也经常碰到各类问题。我参与的这个单体应用的发布周期是2个月一次(这在单体应用中已经算是很快的发布节奏了),每次发布一旦出现Bug,无法单独回滚这个小改动,我必须将整个发布里所有的功能全部回滚,待问题修复之后再重新发布。更可悲的是,整个WAR包的服务经常因为一个小Bug导致团灭,曾经有一次,我提交了一个“数据批量导入导出”的代码改动,把一个隐蔽Bug发布到了线上,业务持续运行一段时间之后,JVM内存发生了泄露,导致集群各节点的HEALTHCHECK失败服务被重启,进而影响到了所有服务。
上面这些问题是不是很让人头痛?想要解决它们,我们就要用到一句老话,叫“大事化小,小事化了”。
在架构领域,我的经验是“一切看似大到无法解决的问题,都可以通过逐一拆解、各个击破的方式来解决”。在“单体应用”这个问题上,我们可以采取“微服务”化的方式,通过将这个巨无霸应用拆分成各个独立的小型微服务应用,分而治之!
微服务架构的优势
微服务架构是在SOA(面向服务架构)之上做的进一步扩展。在一线实践中,我们通过领域建模等理论将一个大型应用拆分成了更细粒度且边界清晰的服务模块。而且,每个微服务都能被独立测试、独立部署,并借助Docker和CI/CD(持续集成环境)完成快速上线,不必像单体应用一样经历繁琐的release流程和漫长的发布窗口。
每个微服务就像一个“麻雀虽小、五脏俱全”的小王国,它拥有独立的代码库和数据库Schema,通常由一个小规模的微服务技术团队全权负责,这个团队汇聚了产品、技术、架构等人员,采用Scrum之类的敏捷开发流程做快速迭代。基于此,微服务具备了“独立演进”能力。
如果你对微服务拆分比较感兴趣,我推荐你去了解“领域建模”和“领域模型驱动(DDD)”的相关知识,后续我也会在这个课程中写一篇扩展阅读,跟你分享互联网公司常用的服务拆分规划理论:主链路规划。
你现在肯定在好奇,为什么能独立开发部署的“微服务”可以解决单体应用的痛点呢?从我自己的经验来说,我认为微服务架构有这样几个天然的优势:
- 快速迭代+快速回滚
细粒度的可独立部署的小型服务,再加上敏捷开发模式的加持,可以让你对产品功能实现快速迭代。在互联网公司中,微服务团队通常以周甚至0.5周为时间单位进行快速迭代。如果迭代过程中发现线上Bug,也可以在最短的时间内做线上回滚,并且不会影响到其他应用的正常发布。
- 资源利用大大提高
你可以将硬件等资源定向分配给需要用到资源的微服务,实现差异化的资源利用。在大厂的微服务体系中,我们会统计每个服务集群的线上压力水位,应用弹性计算技术在各个服务之间调配计算资源。
- 大幅降低协作成本
代码库、数据库、编译打包从“共享”变为了“独享”,微服务团队也保持了小规模特战队的模式,进一步降低了组内组外的沟通协作成本。
- 高可用
高可用是系统设计的第一目标,关于这一点,我想和你多介绍一些大厂微服务架构中的实践经验。通过这些介绍,让你对微服务化的必要性有更加深刻的认识。
相比前牵一发而动全身的单体应用来说,我们可以通过很多技术手段对微服务施加个性化的保护措施,比如弹性机房水位调拨、流量整形、熔断降级。
- 弹性机房水位调拨
弹性机房实现了计算资源的自动分配,这种弹性伸缩能力必须建立在微服务化的基础上。它可以根据每个微服务的重要程度(核心服务 vs 边缘业务)以及当前承接的用户访问压力,动态地将计算资源(如虚机、云存储)分配给需要资源的服务。
- 流量整形
根据每个微服务承载能力的不同,控制外部流量抵达服务的速率。“限流”其实只是流量整形的一个场景,大型微服务的流量整形有很多种方式,比如匀速排队、流量预热、削峰填谷等等。
- 熔断降级
在流量高峰的时候,我们可以对边缘服务做人工降级,把计算资源腾挪给核心应用,降低核心服务的访问压力。除了人工降级以外,我们还可以为每个服务设置自动降级和熔断指标,比如当调用失败率达到某个阈值之后,开启自动降级措施,降低对下游业务的访问压力。
我们只有把应用微服务化之后,才能更好地使用上面这些技术手段对业务系统做精细力度的保护,从而实现高可用的目标。
到这里,相信你已经对微服务架构有了更深一步的认识。不过,任何事物都有其两面性,微服务不光有好的一面,也有很多问题等着我们去解决。比如集群环境下的服务治理、数据一致性、以及高并发场景下的服务容错等等。不过呢,你大可放心,这些问题都不算事儿,在实战环节我会教你如何使用Spring Cloud组件将其一一攻破。下节课,我们正式开启Spring Cloud的大门。
总结
今天我带你了解了微服务架构,我们将单体应用和微服务架构做了个比较,分析了单体应用无法适应互联网快速迭代的痛点,以及微服务架构是如何利用灵巧敏捷的小规模服务,很好地适应了互联网行业的快速迭代和高可用保障的要求。
总结来说,微服务架构是通过应用领域模型等理论,将庞大的单体应用拆分为更细粒度的小型服务,每个服务都可以独立部署、测试和发布,加之敏捷开发的推广,使得微服务很好地迎合了如今互联网行业快速试错、快速迭代的节奏,同时也保证了系统的可用性。
思考题
你的公司是否也采用了微服务架构呢?你能从技术角度分享一下公司项目的技术选型方案吗?欢迎你和我分享,我在留言区等你。
好啦,这节课就结束啦,也欢迎你把这节课分享给更多对Spring Cloud感兴趣的朋友。我是姚秋辰,我们下节课再见!