“微服务”——又一个出现在拥挤的软件架构街道上的新术语。尽管我们的本能倾向是轻蔑地瞥一眼这些东西,但这一术语描述了一种我们发现越来越有吸引力的软件系统风格。在过去的几年里,我们看到许多项目使用这种风格,到目前为止,结果是积极的,以至于对于我们的许多同事来说,这正在成为构建企业应用程序的默认风格。然而,遗憾的是,没有太多信息概述微服务风格是什么以及如何去做。
简而言之,微服务架构风格:
[1]是一种将单个应用程序开发为一组小服务的方法,每个小服务都在自己的进程中运行,并与轻量级机制(通常是 HTTP 资源 API)进行通信。这些服务是围绕业务能力构建的,并且可以通过完全自动化的部署机制独立部署。这些服务有最低限度的集中管理,它们可以用不同的编程语言编写并使用不同的数据存储技术。
My Microservices Resource Guide提供了指向有关微服务的最佳文章、视频、书籍和播客的链接。
要开始解释微服务风格,将其与单体风格进行比较是很有用的:单体应用程序构建为单个单元。企业应用程序通常由三个主要部分构建: 客户端用户界面(由 HTML 页面和在用户机器上的浏览器中运行的 javascript 组成) 数据库(由插入到公共的、通常是关系的数据库管理中的许多表组成系统)和服务器端应用程序。服务器端应用程序将处理 HTTP 请求、执行域逻辑、从数据库检索和更新数据,以及选择和填充要发送到浏览器的 HTML 视图。这个服务器端应用程序是一个整体——一个单一的逻辑可执行文件。
[2]. 对系统的任何更改都涉及构建和部署服务器端应用程序的新版本。
这样的单体服务器是构建这样一个系统的自然方式。处理请求的所有逻辑都在单个进程中运行,允许您使用语言的基本功能将应用程序划分为类、函数和命名空间。小心一点,您可以在开发人员的笔记本电脑上运行和测试应用程序,并使用部署管道来确保正确测试更改并将其部署到生产中。您可以通过在负载均衡器后面运行多个实例来水平扩展单体应用。
单体应用程序可能会成功,但越来越多的人对它们感到沮丧——尤其是当越来越多的应用程序被部署到云时。变更周期是紧密联系在一起的——对应用程序的一小部分进行的变更需要重新构建和部署整个整体。随着时间的推移,通常很难保持良好的模块化结构,从而更难保持应该只影响该模块中的一个模块的更改。扩展需要扩展整个应用程序,而不是需要更多资源的部分。
图 1:单体和微服务
这些挫折导致了微服务架构风格:将应用程序构建为服务套件。除了服务可独立部署和扩展的事实外,每个服务还提供了一个牢固的模块边界,甚至允许使用不同的编程语言编写不同的服务。它们也可以由不同的团队管理。
我们并不声称微服务风格是新颖的或创新的,它的根源至少可以追溯到 Unix 的设计原则。但是我们确实认为没有足够的人考虑微服务架构,如果他们使用它,许多软件开发会更好。
微服务架构的特征
论微服务架构及其应用
近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单块(Monolithic)软件架构面临着越来越多的挑战,已逐渐无法适应互联网时代对软件的要求。在这一背景下,微服务架构模式(Microservice Architecture Pattern)逐渐流行,它强调将单一业务功能开发成微服务的形式,每个微服务 运行在一个进程中;采用 HTTP 等通用协议和轻量级 API 实现微服务之间的协作与通信。 这些微服务可以使用不同的开发语言以及不同数据存储技术,能够通过自动化部署工具独立 发布,并保持最低限制的集中式管理。 请围绕“论微服务架构及其应用”论题,依次从以下三个方面进行论述。
1.概要叙述你参与管理和开发的、采用微服务架构的软件开发项目及在其中所担任的主要工作。
2.与单块架构相比较,微服务架构有哪些特点?请列举至少 4 个特点并进行说明。
3.结合你参与管理和开发的软件开发项目,描述该软件的架构,说明该架构是如何采用微服务架构模式的,并说明在采用微服务架构后,在软件开发过程中遇到的实际问题和解决方案。
写作要点
- 项目概述:简要介绍你参与的微服务项目背景和功能,及你在其中所担任的主要工作。
- 微服务优势
- 技术异构性:每个微服务都是独立的,可以选择不同的技术来实现。
- 弹性:部分服务异常不会导致整个系统不可用。
- 扩展:需要扩展时,只需要对某个服务进行扩展。
- 简化部署:部署时,只需要重新部署修改的服务,而不用部署整个系统。
- 与组织结构相匹配:团队越大维护越困难,根据团队情况调整服务结构。
- 可组合性:系统变更时可以根据情况时有微服务进行组合使用,而不是整个系统的改造。
- 对可替代性的优化:单系统代码关联性较强,不易调整,微服务容易进行改造或重构。
- 微服务挑战
- 分布式系统的复杂度:分布式系统比单系统复杂度搞,服务间的资源管理更为复杂。
- 运维成本:每个服务都是独立的部署单元,都需要独立的配置、部署、监控、日志收集等功能。
- 部署自动化:微服务比单个服务部署周期和频率会高很多,需要自动化代替人工。
- DevOps与组织结构:与单系统团队职责划分明确不同,需要全能型团队。
- 服务间的依赖测试:因为将单系统拆分成了多个服务,需要对服务间的依赖关系进行测试。
- 服务间的依赖管理:微服务间相互协作,服务数量越多,相互的依赖也需要进行管理。
我们不能说微服务架构风格有一个正式的定义,但我们可以尝试描述我们认为适合该标签的架构的共同特征。与概述共同特征的任何定义一样,并非所有微服务架构都具有所有特征,但我们确实希望大多数微服务架构表现出最多的特征。虽然我们的作者一直是这个相当松散的社区的活跃成员,但我们的目的是尝试描述我们在自己的工作和我们认识的团队的类似努力中看到的内容。特别是我们没有制定一些定义来符合。
通过服务组件化
自从我们涉足软件行业以来,就一直希望通过将组件连接在一起来构建系统,这很像我们在物理世界中看到的东西。在过去的几十年里,我们看到了作为大多数语言平台一部分的大型公共库纲要取得了相当大的进步。
在谈论组件时,我们遇到了组件构成的困难定义。我们的定义是, 组件是可独立替换和升级的软件单元。
微服务架构将使用库,但它们将自己的软件组件化的主要方式是分解为服务。我们将库定义 为链接到程序中并使用内存中的函数调用进行调用的组件,而服务是与诸如 Web 服务请求或远程过程调用之类的机制进行通信的进程外组件。(这与许多 OO 程序[3]中的服务对象的概念不同。)
使用服务作为组件(而不是库)的一个主要原因是服务是可独立部署的。如果您的应用程序[4]由单个进程中的多个库组成,则对任何单个组件的更改都会导致必须重新部署整个应用程序。但是,如果该应用程序分解为多个服务,您可以预期许多单个服务更改只需要重新部署该服务。这不是绝对的,一些变化会改变服务接口导致一些协调,但是一个好的微服务架构的目标是通过服务契约中的内聚服务边界和演化机制来最小化这些。
使用服务作为组件的另一个结果是更明确的组件接口。大多数语言没有定义显式发布接口的良好机制。通常,只有文档和规范才能防止客户端破坏组件的封装,从而导致组件之间的耦合过于紧密。通过使用显式远程调用机制,服务可以更容易地避免这种情况。
使用这样的服务确实有缺点。远程调用比进程内调用更昂贵,因此远程 API 需要更粗粒度,这通常更难使用。如果您需要更改组件之间的职责分配,当您跨越流程边界时,这种行为移动就更难做到了。
在第一次近似时,我们可以观察到服务映射到运行时进程,但这只是第一次近似。一个服务可能由多个进程组成,这些进程总是一起开发和部署,例如一个应用程序进程和一个仅由该服务使用的数据库。
围绕业务能力组织
在寻求将大型应用程序拆分为多个部分时,管理通常侧重于技术层,导致 UI 团队、服务器端逻辑团队和数据库团队。当团队按照这些方式分开时,即使是简单的更改也会导致跨团队项目需要时间和预算批准。一个聪明的团队将围绕这一点进行优化,并针对两害相权取其轻——只需将逻辑强加到他们有权访问的任何应用程序中即可。换句话说,逻辑无处不在。这是康威定律[5] 的一个例子。
任何设计系统(广义定义)的组织都会产生一个设计,其结构是该组织通信结构的副本。
——梅尔文·康威,1968
图 2:康威定律在起作用
微服务的划分方法不同,划分为围绕业务能力组织的服务 。此类服务为该业务领域采用广泛的软件实现,包括用户界面、持久性存储和任何外部协作。因此,团队是跨职能的,包括开发所需的全部技能:用户体验、数据库和项目管理。
图 3:团队边界强化的服务边界
微服务有多大?