Happy Coding, Happy Life

解析微服务架构(三)

| Comments

[请勿转载]

微服务架构的核心特征

什么是核心特征,就是当我们谈论同一件事情的时候,那些不同的人们所关注的相同的部分。从业界的讨论来看,微服务通 常有如下几个显著特征:

  • 服务与组件

一直以来,我们都比较提倡使用组件(Component)的方式,模块化应用系统。它类似生活中的汽车,由不同的零件组成,每个零件都是可以独立替换的。因此,这类通常都有很好的灵活性和替换性。

在软件领域,我们也将组件定义为应用软件构建中独立的单元,它的最大特点是,对整个应用软件而言,组件能够被容易的替代或者更新。

传统实现组件的方式是采用和应用程序一样的的编程语言,构建独立的共享库(Libaray),从而达到解耦和复用的效果。对于共享库而言,我们知道它是语言相关、平台相关,并且是和应用程序运行在同一个进程中的,因此,任何共享库的变化都意味着整个应用程序也要被更新,并且需要被重新部署。换句话说,如果应用由多个共享库组件组成,那么任何库的变更都将导致整体应用的重新发布。

其实,微服务也可以作为组件。把微服务当成应用程序中的组件,其中一个最主要的好处是微 服务可以独立部署。如果应用由多个共享库组成,那么其只能跑在一个进程中,那么任何库的变更都将导致整体应用的重新发布。

但是如果应用程序由多个服务构成,我们可以想像,大部分情况下,每个服务的变更仅需要重新部署相应的服务。当然,这也不是绝对的,比如某些对服务接口的变更就需要其相关服务也发生变化,但微服务架构的目的,是尽量避免这种服务间的耦合并完善服务的交互接口。换句话说,通过服务来实现组件,将应用拆散为一系列的服务,运行在不同的进程中时,任何一个服务的局部变化只需重新部署对应的服务本身。同时,将服务作为组件也可以帮助我们明确的定义出组件的边界,因为服务之间的调用是跨进程的,清晰的边界和职责定义应该是在设计阶段时必须考虑的。

把服务当成组件的另外一个优点是在组件和组件之间、或者组件和应用程序之间定义了清晰的、跨语言、跨平台的接口。许 多开发语言虽然定义了良好的公共调用接口的机制,也提供了详尽的文档和规范说明,但由于共享库其本身的特性,充分依赖于特定平台、特定语言,因此组件间的耦合度较高。同共享库相比,微服务是通过语言无关、平台无关的远程接口调用,因此不存在这个问题。当然,使用微服务也有它的不足之处,那就是远程调用比进制内部调用更消耗性能,而且远程的接口由于是分布式调用,无疑增加了维护的复杂度。

  • 围绕业务组织团队

在单块应用架构的时代,为了节省成本、快速实现目标,企业或者组织一般都会根 据技能类型的差异化来划分团队。例如用户体验设计师一般都被划分到用户体验设计团队,而懂服务器端的开发人员,一般都被归类为后端业务逻辑开发团队;对于那些精通数据库技能的开发者,一般会在DBA团队中找到他们的身影。实际上,当团队被按照这个策略或者维度划分后,即便是某些简单的需求变更,都有可能导致不同团队之间跨组织、跨团队的协作,耗费很高的跨团队的沟通和协作成本。

正如康威定律(Conway’s law)提出的,一个组织的设计成果,其 结构往往对应于这个组织中的沟通和组织结构。另外,《敏捷宣言》的一个核心理念是“个体与交互高于过程和工具”。

如果仔细想想,我们发现康威定律从正反两方面支持了这一理念。有些公司受困于垂直、等级化的管理结构,这给工程师们带来了完成工作时不必要的阻力。更多的互联网公司则放手,让团队找到自组织的管理结构。我们既看到“漠视”康威定律所造成的危害,也看到了“拥抱”该定律所带来的好处。

而微服务架构的开发模式不同于传统方式,它倡导围绕应用程序为核心,按业务能力来划分为不同的团队。每个团队都要求能 够对每个服务,将其对应的业务领域的全部功能实现,譬如对于某业务需求的更改,从用户体验界面到业务逻辑实现,再到数据的存储和迁移等。因此团队的组织是跨职能的,会包含实现该业务所需功能的所有技能。近年兴起的全栈工程师正是因为架构和开发模式的转变而出现,当然具备全栈的工程师其实很少,但将不同领域的工程师组织为一个全栈的团队就容易的多。

  • 关注产品而不是项目

传统的应用开发大部分都是基于项目模式的。什么是项目模式?就是当项目启动后,企业或者组织会从开发 团队中抽出一部分资源、从测试团队中抽出一部分资源,同时也从其他不同的技能团队中抽出不同的资源,组成一个项目团队,然后设置一个时间期限,让大家完成项目。当项目结束后,所有的资源都会被释放,所有人在项目中的职责结束。

但服务架构倡导的是避免采用这种项目模式,更倾向于让开发团队负责整个产品的生命周期。大家熟知的亚 马逊CTO Werner Vogels,曾经说过一句经典的名言,“You build it, you run it”。即对于开发产品的团队而言,产品就是团队的,也是每个成员的。团队中的每个人都有责任、有义务确保产品的快速发展以及演进。

  • 去中心化

在第二章我们提到,传统的单块应用架构,倾向于采用统一的技术平台或方案来解决所有问题。其实,我们 知道,在现实生活中,并不是每个问题都是钉子,也不是每个解决方案都是一个锤子。 问题有其具体性,解决方案也应有其针对性。用最适合的技术方案去解决具体的问题,往往会事半功倍。传统的单块架构系统倾向采用统一的技术平台或方案来解决所有问题,而微服务的架构意味着,可以针对不同的业务特征选择不同的技术方案,有针对性的解决具体的业务问题。

对于单块架构系统,初始的技术选型严重限制将来采用不同语言或框架的能力。如果想尝试新的编程语言 或者框架,没有完备的功能测试集,很难平滑的完成替换,而且系统规模越大,风险越高。

而基于微服务架构,使我们更容易在系统上尝试新的技术或解决方案。譬如说,可以先挑选风险最小的服务作为尝试,快速得到 反馈后再决定是否试用于其他服务。这也意味着,即便对一项新技术的尝试失败,也可以抛弃这个方案,并不会对整个产品带来风险。

  • 独立业务数据

传统的单块应用架构,倾向于采用统一的数据存储平台来存储所有的数据。随着业务的快速发展,需求的不断变化,一方面,数 据变得越来越复杂,难以管理;另一方面,随着应用系统的业务逻辑不断更新和发展,数据库不仅承担着数据存储的作用,还承担着不同系统之间的集成作用。同时,传统的数据库大多是关系型数据库,存储的数据都是以结构化信息为主,但随着互联网的快速发展,数据的结构并不具有确定性,或者说结构发生变化的频率非常快,因此,对于如何有效维护业务数据,也成了一个难题,相应的维护成本越来越高。

微服务架构,提倡具有业务属性的独立单元或者服务自身维护其相关的业务数据。这样的话,有几个非常明显的优势:首先具有 业务属性的服务单元能够有权利管理其相关的数据,同时能够随着业务的发展,不断更新业务数据。其次,每个业务单元只关心自己的业务数据,因此可以选择最合适的工具或者产品来存储以及管理数据。譬如可以根据具体业务场景,使用MySQL、PostgreSQL等关系型数据库,也可以使用文档类型的MongoDB、键值类型的Riak等NoSQL数据库。譬如,在一个复杂的电商系统中,产品数据的种类繁多,更新也比较频繁,如果使用类似MongoDB这种文档数据库,能灵活的根据需求动态调整结构。而像当用户访问系统时产生的会话信息,则可以使用Redis等键值系统进行存储;通常来说,报表数据的结构变化不大,而且要求数据的高一致性,因此可以使用熟悉的关系型数据库。

  • 基础设施自动化

随着云技术的大规模推广与使用,部署和运维的复杂度在大幅度降低。利用云,我们可以快速的创建系统需要的资源,降低应用的交付周期。同时,由于持续集成、持续交付等实践的深入人心,很多团队都开始在构建软件的过程中,使用持续交付提倡的基础设施自动化技术(更多关于持续交付的知识,请参考《持续交付-发布可靠软件的系统方法》一书)。

这也就意味着,如果微服务架构将应用程序本身分成多个小的服务,每个服务都是一个独立的部署单元。因此,微服务的实践,对持续交付和部署流 水线要求非常高。微服务的粒度越细,就意味着需要部署的业务单元就越多,业务单元越多,就需要更稳定的基础设置自动化机制,能够创建运行环境,安装依赖,部署应用等。

  • 演进式架构设计

在过去十年中,敏捷方法论以及其实践已经被越来越多的组织尝试并认可。敏捷方法论正在帮助组织以拥抱变化的心 态,去不断尝试,不断获取反馈,从而以高效的方式构建正确的应用系统。实际上,敏捷并不是一种静止的状态,它是组织一直在拥抱变化,尝试改变、获取反馈的演进式发展的一个动态过程。

类似的,架构设计也应该是随着业务的发展而不断发展,随着需求的变化而不断变化的。当我们试图构建一个单块应用架构系统 时,我们会面临非常艰难的技术选型。哪种方案才是合理的?那种方案才是最正确的?在传统的单块设计中,企业或者组织通常是希望构建一个大而全、无所不能的平台,但是在技术发展如此之快的今天,单一的技术平台已经无法适应市场的快速变化,组织应该随着业务的发展,随着企业的发展,不断尝试并改进架构设计,真正做到业务驱动架构,架构服务于业务。


总结

微服务强调的是一种独立测试、独立部署、独立运行的软件架构模式,是一种更灵活、更开放、更松散的演进式架构。通过本章所介绍的微服务的核心特征,帮助我们更清晰、深刻的理解了微服务其概念背后所蕴含的思想。

Comments