二十、微服务架构

1 微服务架构产生的历史背景

1.1 研发成本挑战

1.1.1 代码重复率

  1. 从技术架构角度看,传统垂直架构的特点是本地 API 接口调用,不存在业务的拆分和互相调用,使用到什么功能就本地开发,非常方便,不需要过度依赖于其它功能模块。
  2. 跨地域、跨开发小组协调很困难。

1.1.2 需求变更困难

代码重复率变高之后,已有功能变更或者新需求加入都会非常困难,以充值缴费功能为例,不同的充值渠道开发了相同的限额保护功能,当限额保护功能发生变更之后,所有重复开发的限额保护功能都需要重新修改和测试,很容易出现修改不一致或者被遗漏,导致部分渠道充值功能正常:

1.2 运维成本高

1.2.1 代码维护困难

传统的业务流程是由一长串本地接口或者方法调用串联起来的,而且往往由一个负责开发和维护。随着业务的发展和需求变化,本地diamante在不断地迭代和变更,最后形成了一个个垂直的功能孤岛,只有原来的开发者才理解接口调用关系和功能需求,一旦原来的开发者离职或调到其它项目组,这些功能模块的运维就会变得非常困难:

1.2.2 部署效率低

  1. 业务没有拆分,很多功能模块都打到同一个 war 包中,一旦有一个功能发生变更,就需要重新打包和部署。
  2. 测试工作量较大,因此存在大量重复的功能类库,需要针对所有调用方进行测试,测试工作量大。

1.3 新需求上线周期长

  1. 新功能通常无法独立编译、打包、部署和上线,它可能混杂在老的系统中开发,很难剥离出来,这就无法通过服务灰度发布的形式快速上线。
  2. 由于业务没有进行水平和垂直拆分,导致代码重复率高,新需求的开发、测试、打包和部署成本都比较高。

2 微服务架构带来的改变

2.1 应用解耦

微服务化之前,一个大型的应用系统通常会包含多个子应用,不同应用之间存在很多重复的公共代码,所有应用共用一套数据库,架构图如下:

将功能A 和功能B 服务化之后,应用作为消费者直接调用服务A 和服务B ,这样就实现了对原有重复代码的收编,同时系统之间的调用关系也更加清晰,如下图:

基于服务注册中心的定于发布机制,实现服务消费者和提供者之间的解耦。

2.2 分而治之

将核心业务抽取出来,作为独立的服务,逐渐形成稳定的底层微服务。
应用的拆分分为水平拆分和垂直拆分两种,水平拆分以业务领域为维度,抽象出几个不同的业务域,每个业务域作为一个独立的服务中心对外提供服务。领域服务可以独立地伸缩和升级,快速地响应需求变化,同时与其它业务领域解耦。原理图如下:

应用的垂直拆分主要包括前后台逻辑拆分、业务逻辑和数据访问层拆分,拆分之后的效果图如下:

2.3 敏捷交付

敏捷性的产生,是将运行中的系统解耦为一系列功能单一服务的结果。微服务架构能够对系统中其它部分的依赖加以限制,这种特性能够让基于微服务架构的应用在应对 BUG 或是对新特性需求时,能够快速地进行变更。而传统的垂直架构:“要对应用程序中某个小部分进行变更,就必须对整体架构进行重新编译和构建,并且重新进行全量部署。”

3 微服务架构解析

微服务架构(MSA)是一种架构风格,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。对比图如下:

3.1 微服务划分原则

通用的划分原则是:微服务通常是简单、原子的微型服务,它的功能单一,只负责处理一件事,与代码行数并没有直接关系,与需要处理的业务复杂度有关。有些复杂的功能,尽管功能单一,但是代码量可能成百上千行,因此不能以代码量作为划分微服务的维度。

“微”所表达的是一种设计思想和指导方针,是需要团队或者组织共同努力找到的一个平衡点。

3.2 开发微服务

对于不同的微服务,虽然实现逻辑不同,但是开发方式、持续集成环境、测试策略和部署机制以及后续的上线运维都是类似的,为了满足 DRY 原则并消除浪费,需要搭建统一的开发打包和持续集成环境。

3.3 基于 Docker 容器部署微服务

Docker 是一套开源工具,它能够以某种方式对现有的基于容器的虚拟化技术进行封装,使得它能够在更广阔的工程社区中得到应用,主要在于快速和可移植性。

3.3.1 快速

普通的虚拟机在每次开机时都需要启动一个完整的新操作系统实例,而 Docker 容器能够通过内核共享的方式,共享一套托管操作系统。这意味着,Docker 容器的启动和停止只需要几百毫秒。这样就有更高的敏捷性。

物理机 VS Docker VS 虚拟机

3.3.2 可移植性

  1. 线上线下环境等同性:本地模拟线上环境,定位 BUG 更快。
  2. 与特定的云提供商解耦:参考 JVM。
  3. 提升运维效率:Docker 对可移植的容器部署进行标准化,节省时间与精力。如果你在构建某个应用程序,你的选择包括物理机、虚拟化的本地基础设施、公有云和私有云,以及各种可用的 PaaS 选项。而通过 Docker 标准化的容器格式,任何一种提供商都可以实现一种统一的部署体验。
  4. 敏捷性:快速启动,更敏捷。

3.4 治理和运维微服务

微服务架构对运维和部署流水线要求非常高,服务拆分的粒度越细,运维和治理成本就越高,挑战总结如下:

  1. 监控度量问题:海量微服务的各种维度性能 KPI 采集、汇总和分析,实时和历史数据同比和环比,对采集模块的实时性、汇总模块的计算能力、前端运维 Portal 多维度展示能力要求非常高。
  2. 分布式运维:服务拆分得越细,一个完整业务流程的调用链就越长,需要采集、汇总和计算的数据量就越大,分布式消息跟踪系统需要能够支撑大规模微服务化后带来的性能挑战。
  3. 海量微服务对服务注册中心的处理能力、通知的实时性也带来了巨大挑战。
  4. 微服务治理:微服务化之后,微服务相比于传统的 SOA 服务有了指数级增长,服务治理的展示界面、检索速度等需要能够支撑这种变化。
  5. 量变引起质变:当需要运维的服务规模达到一定上限后,就由量变引起质变,传统的运维框架架构可能无法支撑,需要重构。

解决微服务运维的主要措施就是:分布式和自动化。利用分布式系统的性能线性增长和弹性扩容能力,支撑大规模微服务对运维系统带来的性能冲击,包括:

  1. 分布式性能数据采集、日志采集 Agent。
  2. 分布式汇总和计算框架。
  3. 分布式文件存储服务。
  4. 分布式日志检索服务。
  5. 分布式报表展示框架。

3.5 特点总结

  1. 单一职责原则:每个服务应该负责单独的功能。
  2. 独立部署、升级、扩展和替换。
  3. 支持异构/多语言。
  4. 轻量级。

因此优点如下:

  1. 开发、测试和运维更加简单。
  2. 局部修改很容易部署,有利于持续集成和持续交付。
  3. 技术选择更灵活,不与特定语言和工具绑定。
  4. 有利于小团队作战,敏捷交付。

4 个人总结

微服务涉及到了组织架构、涉及、交付、运维等方面的变革,核心目标是为了解决系统的交付周期,降低维护成本和研发成本。
但是带来了运维成本、服务管理成本等。
不可脱离业务实际而强制使用微服务。