微服务架构可谓是当前软件开发领域的技术热点,它在各种博客、知识媒体和业界知名会议演讲上的出镜率非常之高,无论是做基础架构还是做业务系统的工程师,对微服务都相当关注,而这个现象与热度已经持续了近 5 年之久,经久不衰。
然而,随着云原生技术的推广,以及大量的微服务落地,反微服务的声音越发响亮。尤其是在今年 3 月初,服务网格的著名开源项目 Istio 发布了 1.5 版本,其控制面由原先的多个微服务组件,合并成了一个单体应用,大大简化了其架构与部署运维的复杂性,赢得了满堂喝彩。社区关于微服务模式质疑的声音此起彼伏,也有文章大声呼喊:“醒醒,你不是真的需要微服务!”
那么,在云原生时代,是否需要微服务?什么时候应该采用微服务?微服务究竟能给业务带来哪些好处?如何在不同环境下正确合理地落地微服务?希望读完本文后,每位读者都能在心中有个答案。
微服务是什么
2014 年,Martin Fowler 与 James Lewis 共同提出微服务的概念,定义了微服务架构是以一组小型服务的方式来开发一个独立的应用系统,每个服务都以一个独立进程的方式运行,每个服务与其他服务使用轻量级(通常是 HTTP )通信机制。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署,同时服务会使用最小规模的集中管理能力,也可以采用不同的编程语言和数据库,实现去中心化的服务管理。
而早在 2005 年,Peter Rodgers 博士在云端运算博览会上就提出了微 Web 服务,将程序设计成细粒度的服务(Granular Service),以作为 Microsoft 下一阶段的软件架构。
由此可以看出,微服务并不是一个新的概念,在很早之前就有了充足的理论基础。大系统终究会拆解成小系统,“合久必分,分而治之”;传统行业的系统架构大多都是庞大的单体架构,微服务是架构发展的一个非常自然的演变状态。
遗憾的是,微服务模式并非“银弹”,微服务也有其弊端和痛点。Martin Fowler 也在他的博客中写道:“除非你的系统太复杂,作为单体应用会很难管理,否则不要考虑微服务。绝大多数软件系统都应该构建为单体应用。要注重在单体应用中实现良好的模块化,但不要试图将其拆分成单独的服务。”
微服务架构的优点
通常来说,架构没有好坏优劣之分,只有适合与不适合。但是当把微服务架构与单体架构进行比较,会发现微服务有如下一些优点:
因素 | 单体架构 | 微服务架构 | 说明 |
---|---|---|---|
故障隔离 | 线程级 | 进程级 | 微服务独立运行,通过进程的方式隔离,使故障范围得到有效控制、架构变得更可靠。 |
整体可用性 | 较低 | 较高 | 微服务架构由于故障得到有效隔离,整体可用性更高,有效降低了单点故障对整体的影响。 |
架构持续演进 | 困难 | 容易 | 微服务的粒度更小,架构演进的影响面相应也更小,架构演进不需要大规模重构,只需调整个别微服务即可。 |
可重用性 | 低 | 高 | 微服务架构可以实现以服务为粒度,通过接口共享重用。 |
可扩展性 | 笨重 | 灵活 | 微服务架构可以根据服务对资源的要求以服务为粒度进行扩展,而单体应用只能整体进行扩展。 |
交付速度 | 较慢 | 较快 | 服务拆分后,各个服务可以独立并行开发、测试、部署,交付效率大大提升,产品更新换代速度更快,用户体验更好。 |
微服务还有许多优点,如“反脆弱性(anti-fragility)”、架构抽象、技术隔离等。但并不是说采用了微服务就自然地具备了这些特性。
微服务的先决条件
准确地来讲,要想享受微服务的福利,需要具备一些先决条件。
一、团队调整
需要重新组建团队,以服务为核心,按照业务领域划分全功能团队,改变原有的研发流程、决策机制。例如,倡导敏捷文化、快速迭代,做更多的自动化测试,加强 Code Review 等。
在新的团队组织里面,一切以人为本,需要建立开放自由的环境。领导对下级高度信任,增强其自我驱动,充分发挥每一个人的力量,而不是让工程师成为“螺丝钉”。
微服务框架可以封装、抽象分布式场景下的一些常用能力,例如负载均衡、服务注册发现、容错、远程通信等能力,可以让开发人员快速地开发出高质量的服务。因此,在采用微服务架构之前,应该先进行微服务架构的选型、学习和试用。整个团队要对微服务的基本概念、微服务框架的实现原理,微服务治理与监控等知识需要有一定的储备。
二、基础设施建设
基础设施即代码,可以通过编程的方式管理虚机或容器,免去了手动配置、更新各个硬件的环节,这就使得基础设施极具弹性,能够快速、高效、准确地进行重复性操作。开发人员使用同一套代码或配置,就可以部署并管理成千上万台物理机。
当服务数量增多、交付频繁的时候,故障次数可能会大幅度上升,我们需要通过全面地监控发现故障,及时处理并发出警报。当生产环境出现问题的时候,需要将故障进行分级,评估影响面,并分配给相应的负责人。
微服务架构的一个大优势就是快速交付,快速交付不止体现在服务的粒度更小,可以独立交付,还体现在整个流程更快速。微服务架构基于自动化的工具链,以流水线交付的方式串联整个 DevOps 流程。小团队可以基于服务独立开发、测试、部署、运维。
以上这两点不是采用微服务模式的充分必要条件,但当团队满足了上述两个条件后,微服务化的过程将事半功倍,后续维护和迭代也会顺风顺水,而不是叫苦连天。
微服务是逐步拆分出来的
其次,微服务是应该随着业务的演进逐步拆分出来的。
避免在设计系统的时候直接划分微服务。几乎所有成功的微服务架构都是从一个巨大的单体架构拆分出来的;几乎所有在一开始就构建微服务架构的案例,后续都遇到了巨大的困难。
面对一个新的业务和领域,很难在开始阶段就对业务梳理得很清晰,往往是经过一段时间踩过一些坑,经过模块调整后,业务内部架构才能逐渐清晰起来。并且从一个已有的模块清晰的单体架构逐步划分服务,要比一开始就构建微服务简单的多。如果一开始就划分了微服务,其一,第一版交付的时间会延后许多,因为有许多公共服务需要去构建起来;其二,服务很容易拆分得不合理,大大影响整个调用流程的性能,甚至可能需要花费很大的精力去处理分布式事务,最后不得不再将多个微服务整合成一个单体。
只有当业务复杂度达到一定的程度后,微服务架构消耗的成本才会体现其优势,这个时候就可以开始设计微服务架构、进行微服务划分了。微服务设计应该优先尊崇垂直划分优先原则,垂直划分服务可以让团队自上而下地关注业务实现,端到端负责,避免跨服务多次调用引起的性能与沟通成本。
微服务需要监控与治理
拆分之前,整个系统拥有的服务数一般只有个位数;拆分之后,服务可能变成了数十上百个,实例数可能会达到成千上万个。这么多服务与实例,需要构建一套监控系统,能够监控所有服务日常运行状态,并且需要在服务出错的时候给对应负责人发出报警信息;在出现故障时,能够通过调用链查询以及服务拓扑图等功能进行分析查看,也可以进一步查看到全息日志等具体信息。
除了监控,服务治理也至关重要。可以通过 SDK/Sidecar 手段提供服务高可用的治理策略,这些策略往往对业务是非侵入或者弱侵入的,能够让绝大多数服务轻松实现服务高可用。
微服务之间一旦建立起路由,就意味着会有数据在服务之间流通。由于不同服务可以提供的资源和对数据流量的承载能力不尽相同,为了防止单个 Consumer 占用 Provider 过多的资源,或者突发的大流量冲击导致 Provider 故障,需要服务限流来保证服务的高可用。
在服务治理中,虽然我们可以通过限流规则尽量避免服务承受过高的流量,但是在实际生产中服务故障依然难以完全避免。当整个系统中某些服务产生故障时,如果不及时采取措施,这种故障就有可能因为服务之间的互相访问而被传播开来,最终导致故障规模的扩大,甚至导致整个系统奔溃,这种现象我们称之为“雪崩”。熔断降级其实不只是服务治理中,在金融行业也有很广泛的应用。比如当股指的波动幅度超过规定的熔断点时,交易所为了控制风险采取的暂停交易措施。
负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,同时多服务器能够消除这部分的单点故障。
如何在云原生时代落地微服务
一、选择合适的时机
就像前面提到的,组织架构与团队文化要适应云原生的节奏,需要足够敏捷、足够自主,构建全功能团队,产品、UI、前后端研发、测试等角色要齐全;需要提前做好自动化的流水线,可以一键构建、发布、部署,可以快速扩缩容等;服务提前做好容器化部署改造,服务容器化更适合在云原生场景下集成其他功能与组建。等上述一切都 ready 了之后,并且业务也逐步发展到了一定规模急需拆分了,这个时候就应该果断进行微服务拆分和架构设计了。
二、选择合适的微服务框架
现在主流的微服务框架主要分为两类:侵入式与非侵入式。主流的开源侵入式框架包括 Spring Cloud、Dubbo、brpc 等,其功能特色各有千秋,在不同的场景均有应用,大部分架构师对其均有比较多的了解,社区和文档的成熟度都比较高。虽然 Spring Cloud 这样的传统侵入式微服务框架大多具有版本碎片化严重、升级成本高等问题,但总的来说,已经可以满足绝大部分服务治理的需求,并且借此快速推进微服务化改造。
现在大部分人更关心的是非侵入式框架的选型,即近几年火起来的服务网格技术。2017 年,随着 Linkerd 的传入,Service Mesh 翻译成服务网格,并开始进入国内社区的视野,部分大公司也同步自研了适配公司内部应用场景和依赖的服务网格框架,用以助力内部服务快速迭代与发展。
而 Istio 作为一个开源的 Service Mesh 开源框架,一经推出就备受瞩目,成为了各大厂商和开发者争相追捧的对象。很多人相信,Istio 会成为继 Kubernetes 之后又一个明星级产品。有了 Istio,你几乎可以不再需要其他的微服务框架,也不需要自己去实现服务治理等功能。只要把网络层委托给 Istio,它就能帮你完成这一系列的功能。简单来说,Istio 就是一个提供了服务治理能力的服务网格。此外,Istio 还提供完善的可观察性方面的能力,包括对所有网格控制下的流量进行自动化度量、日志记录和追踪。换句话说,选择了 Istio,单体应用无需做任何改造即可轻松接入微服务,享受云原生各项福利。
三、借助云厂商产品快速进行云原生与微服务落地
之所以提到云厂商,是因为大部分中小型公司或者传统行业都面临着单体应用和传统微服务框架的各种弊端和诟病,急需进行云原生与微服务改造,但是缺乏足够的人力与技术,去维护一套功能齐全的云原生底座与基础架构服务。例如 Istio 框架,其版本迭代频繁,控制面与数据面在提供了强大的功能的同时,代码实现相当复杂,在遇到了异常的时候,很多工程师往往很难定位问题。
而云厂商则提供了一整套云原生应用编排与微服务管理解决方案,所有技术都得到产品化,方便使用与查看效果,并且避免或者快速解决运行期间可能遇到的各种问题。在一定程度上,这不仅提高的服务的效率,也大大降低了各种成本,可以快速充分地享受云原生福利,助力内部业务稳定对外服务,快速扩张。
总结
最后,我们再回到开篇的疑问,我们是否还需要微服务?
这个问题没有唯一与正确的答案,每个人所处的场景不同,正如一千个人心中有一千个哈姆雷特。任何软件或者架构都有其利弊,没有十全十美的东西。大家需要思考和衡量的是,当前的软件与系统是否满足了微服务化改造的前提,微服务化改造后其带来的收益是否大于损失、利是否大于弊,团队各个方面是否做好了准备,如果还没有,那么请你再等等,单体架构也挺好!
参考文献
《持续演进的 Cloud Native 》 王启军 / 著
《Istio Handbook——Istio 服务网格进阶实战》ServiceMesher 社区联合编著: https://www.servicemesher.com/istio-handbook/
《混合微服务高可用在企业级生产中的实践》 罗广明: https://cloudnative.to/blog/microservices-ha-practice/
作者简介:
罗广明,现就职于百度基础架构部云原生团队,云原生技术专家,云原生社区联合创始人,ServiceMesher 社区管委会成员,多年来一直从事微服务技术与产品的研发工作,对 Spring Cloud、Istio 以及微服务中间件有深入研究和实战经验。