什么是微服务?

微服务描述了一种软件开发的云原生架构方法,它通过应用程序接口(API)或消息协议相互通信,由松散耦合的服务即服务架构应用程序。每项服务都是独立自主的,运行独特的流程。随着开发人员寻求构建可扩展、有弹性的应用程序,微服务变得越来越流行。

 

微服务解释

微服务又称微服务架构,是云原生应用程序开发中使用的一种软件架构类型。采用这种设计的应用程序由小型、独立和松散耦合的可部署组件组成,这些组件共同提供应用程序的功能。

微服务架构中的每个服务都执行不同的业务功能,并通过定义明确的接口与其他微服务通信,这些接口大多使用 RESTful API。

与作为单一单元开发的单体应用程序不同,微服务允许开发人员使用可独立开发、测试和部署的模块进行构建,从而加快了产品上市时间。由于微服务的解耦特性允许开发人员更频繁地推送新代码和新功能,因此现代应用程序能够跟上不断变化的客户需求。

超过 四分之三的企业已转向微服务,用分布在主机服务器集群上的容器化云原生应用程序取代了由单个网络服务器托管的单体应用程序。

 

从面向服务架构到微服务

面向服务的体系结构(SOA)从 2000 年代初开始出现,它是一种通过将大型分布式系统分解成较小的、松散耦合的服务来构建大型分布式系统的方法。微服务架构是 SOA 的自然演进。

微服务的概念是弗雷德-乔治在 2011 年的一次软件架构研讨会上提出的。George 在开发一个电子商务网站时,一直在尝试用 SOA 解决可扩展性问题,并萌生了构建小型自主服务的想法。

微服务架构采用了 SOA 的服务导向原则,并针对现代云原生应用进行了改进。SOA 的粗粒度服务变成了细粒度的 "微 "服务,这使它们具有很高的效率,并提供了将技术堆栈与特定服务相匹配的灵活性。微服务架构甚至用 REST API 或消息队列等轻量级选项取代了繁琐的 SOAP API,从而减少了通信负荷。

微服务很快受到软件架构师的青睐,Netflix、亚马逊、《卫报》和 Spotify 等公司都开始采用这种架构。

微服务架构是现代云原生应用程序相关优势的基础。

图 1:微服务架构是现代云原生应用程序相关优势的基础。

 

微服务的优势

微服务为构建可适应不断变化的业务要求的云原生 Application Framework 提供了一个框架。应用程序的架构带来了无数好处。

敏捷性

微服务架构适合独立开发和部署。与单体应用程序不同的是,在单体应用程序中,修改一行代码就需要更新整个应用程序,而开发人员可以修改或更换服务,而不会影响分布式系统。部署单个服务的能力使得为应用程序添加新功能或回滚更改变得非常容易。

可扩展性

大规模扩展整个应用程序并非最优选择。使用微服务时,只对需要扩展的组件进行扩展。开发人员可以根据需要处理单项服务,从而最终提高大负载下的性能、有效利用资源并降低基础设施成本。

选择

在微服务架构中,云原生应用并不共用堆栈和数据库。开发人员可以选择自己喜欢的工具和技术,以满足个别服务的不同要求。

一体化

开发人员可以用任何语言编写微服务,并将其连接到用任何语言编程的微服务。此外,微服务可以在任何平台上运行,因此可以与传统系统集成。

代码重用

微服务架构允许开发人员构建模块化服务,并可在不同应用中重复使用。通过使用可重复使用的组件,程序员可以减少开发时间,提高代码质量,因为他们投资于 "一次编写,经常重复使用 "的文化。

容错

微服务架构提高了复原力。由于服务可以自主运行,因此单个服务的故障很少会导致应用程序瘫痪,而单体应用程序往往会出现这种情况。

合作

微服务架构使团队能够同时处理不同的服务,从而加快产品上市速度。开发人员无需与其他团队协调即可做出决策,同时微服务也促进了跨团队协作,因为每个团队都负责开发和维护整体的一部分。这样可以更好地与业务目标保持一致,更有效地利用资源。

持续迭代

使用微服务构建的应用程序可以不断发展。开发人员可以快速部署核心微服务,将其作为最小可行产品,并在团队完成附加服务时升级应用程序。新技术出现时,可将其纳入设计中。基于微服务的应用仍在进程中,持续向理论上的完美迈进。

 

何时使用微服务

虽然基于容器的微服务有很多好处,但它们并不总是正确的应用架构选择。在做出软件工程决策时,请考虑您对应用程序的目标,以及您预见到的开发障碍和应用程序生命周期内的需求。微服务最适合复杂的应用程序。考虑使用微服务的场景包括

大型应用

如果您正在构建一个庞大而复杂的应用程序,微服务将允许您把应用程序划分成易于管理的部分,使其更易于开发、部署和维护。

时间线的复杂性

微服务架构可容纳开发速度不同的独立服务。即使服务出现意外延迟,项目也能持续进行,而不会对应用程序开发时间表造成全面影响。

频繁更新

微服务架构非常适合需要频繁更新的应用程序,因为独立的服务允许开发人员修改模块而不是应用程序。

高度可扩展性

如果您的应用程序需要处理大量流量或需要快速大规模扩展,那么微服务是必不可少的。如果您需要大规模扩展应用程序的特定部分,而不是扩展整个应用程序,这一点尤为重要。

多个团队

如果您有多个开发团队在开发同一个应用程序,微服务将帮助您保持灵活性和效率。每个团队都可以使用适合自己的技术栈来开发自己的微服务,而不必担心应用程序的其他部分。

分散式架构

如果你想构建一个分散架构的应用程序,微服务是自主的,可以部署在不同的地点,甚至不同的云服务提供商之间。

混合云

如果您计划采用混合云架构,其中一些服务将持续在本地部署运行,另一些服务将在云中运行,那么微服务将帮助您管理应用程序的复杂性。

API 调用代表由 API 网关路由到内部微服务端点的客户端请求

图 2:API 调用代表由 API 网关 路由到内部微服务端点的客户端请求。

 

构建和部署基于微服务的应用程序

微服务架构要求精心规划。生产环境中常见的某些技术和实践使开发人员能够有效地开发、维护和运行基于微服务的应用程序。

DevOps

包括 CI/CD在内的 DevOps 实践对于微服务的架构方法至关重要。与单片应用程序不同,微服务本质上是复杂的分布式系统,具有众多活动部件和独立的技术栈。这种复杂性要求开发和运营团队之间经常协作,以确保各组件无缝集成。

DevOps 实践提供了必要的协作、沟通和自动化工具,在整个 软件开发生命周期中有效地将团队凝聚在一起。

持续交付

持续交付与微服务相辅相成,通过利用基础设施自动化工具(如持续集成服务器、部署管道和自动化测试框架)简化 CI/CD 管道流程,开发人员可以频繁可靠地发布软件更新。

持续交付 对于确保每个服务都能独立于其他微服务进行更新和发布尤为重要。

REST

微服务与微服务之间的通信(大多数是在网络应用程序中进行的)使 REST 成为了一种补充。REST,即 "表征状态传输"(Representational State Transfer),是一种用于构建 RESTful API 的架构设计模式,它允许服务以 XML、HTML 和 JSON 等标准格式通过 HTTP 进行通信。但 REST API 是基于微服务的应用程序的基础,原因有几个。

Rest API 是轻量级的,与平台无关,这意味着它们提供了一个标准化接口,使微服务能够进行通信,而不管它们的底层技术是什么。由于请求包含完成请求所需的信息,REST API 不需要服务器上存储的上下文。它们可以在不影响性能的情况下处理大量请求,基于 REST 的微服务架构中的服务可以独立发展,以无状态的方式进行高效通信。

集装箱

虽然微服务让团队可以选择其服务的语言和框架,但在同一 CD 管道中使用各种语言也带来了挑战。容器 抽象掉了服务之间的差异,因为每个微服务都成为一个自足的单元,并与其代码库、数据库和依赖关系打包在一起。现在,同质化的 CD 管道可以对每个容器进行一致的测试。

当服务被容器分隔开来时,就能在互不干扰的情况下进行交互,而一旦部署完毕,容器就能提供轻量级、可移植的运行时环境,让服务在不同平台上都能始终如一地运行。Docker 和 Kubernetes 等工具被广泛用于管理容器化的微服务。

Kubernetes Orchestrator

像 Kubernetes 这样的编排工具可以抽象出底层基础架构,并在多个服务器之间自动进行容器管理、部署和大规模扩展。它的可扩展性还能让开发人员和运营商使用自己喜欢的开源和商业软件工具,减少容器管理的人工工作。

无服务器

无服务器计算是部署微服务的另一种选择。无服务器架构 使用功能即服务(FaaS)平台来创建更小的部署单元,并按需大规模扩展。虽然无服务器架构可能会增加对供应商的依赖,但却能降低运营成本、复杂性和工程设计周期。

 

微服务最佳实践

设计微服务架构需要仔细规划和考虑。要成功构建基于微服务的应用程序,开发人员应观测以下最佳实践:

  • 领域驱动设计领域驱动设计(DDD)是一种专注于业务领域和应用程序行为的设计方法。它可以帮助开发人员将应用程序拆分成更小、更易于管理的组件,使其更易于构建、部署和维护。
  • 服务边界:在设计微服务架构时,必须定义清晰的服务边界。每个微服务都应有明确的职责。
  • 小型服务:保持 "微观 "服务,专注于单一职责。如果忽视了这一基本原则,就会牺牲可管理性。
  • 应用程序接口设计:微服务通过应用程序接口(API)进行通信,因此要使用一致、可扩展和安全的应用程序接口(API),将数据访问限制在授权应用程序、用户和服务器范围内。
  • 分散式数据管理:微服务应用程序需要多种存储和数据库选项。每个微服务都应有自己的数据存储。这种方法可帮助您避免数据不一致,并允许您自主地大规模扩展每个微服务。您希望开发团队为每项服务选择数据库,以确保数据库最适合他们的项目。
  • CI/CD 管道:实施 CI/CD 可以帮助您快速发现并修复错误,这对于在微服务架构中管理多个代码库尤为重要。
  • 有意的复原力:保护应用程序不会因依赖性故障而关闭。尽可能不要在微服务之间使用远程过程调用(RPC),并采用断路器等功能来防止级联故障。
  • 标准作业程序:制定标准操作程序,确定编码惯例、目录结构和通信协议。遵循一套标准将产生一致且可管理的微服务。

 

采用微服务

eBay、Etsy、Uber--无数企业拆解了它们的单体应用程序,并将其重构为基于微服务的架构,以充分利用大规模优势、业务敏捷性和经济效益。

计划过渡到微服务的组织应首先采用 DevOps,这将为您管理所遇到的复杂问题做好准备。从根本上说,在制定项目计划时,应考虑到以下阶段。

确定业务能力

迁移到微服务架构的第一步是确定应用程序需要支持的业务能力或功能。这将有助于您确定应用程序的范围,并为您决定优先开发哪些功能以及如何设计和相互集成这些微服务提供依据。

分解单体应用程序

大多数组织使用领域驱动设计或基于特征的分解来分解其单体应用程序。

确定应用程序的业务功能后,为每个微服务定义服务边界,确保每个微服务都有明确界定的职责。您需要映射业务功能、数据存储和外部系统之间的依赖关系。根据限定的上下文和依赖关系,定义将取代单体应用程序的微服务。

每个专注于单一业务能力的微服务都应有清晰的接口。审查如何访问数据实体,最后考虑如何分割数据以减少服务之间的依赖性。

定义服务接口

实施每个微服务的服务接口,确保接口反映微服务的唯一职责。您可以使用不同的技术(如 RESTful API 或消息传递协议)来定义服务接口。

实施和测试服务

根据您的要求和专业知识,选择编程语言和框架来实施服务。根据需要迭代设计,包括测试新的接口、通信协议和数据存储。

将服务容器化

实施并测试服务后,您要使用 Docker 或 Kubernetes 等容器技术将其容器化。容器化将使您能够独立地部署和管理服务。

自动部署和协调

使用 Kubernetes 或 Docker Swarm 等工具自动协调服务。除了有效简化服务的部署,通过 Kubernetes 或 Docker 实现自动化还将提高应用程序的可靠性和可用性。无论哪种平台,都能在服务实例发生故障或反应迟钝时进行检测,并采取补救措施。例如,Kubernetes 可以重启故障实例或将其重新安排到其他节点,而 Docker 可以自动将故障容器迁移到另一个节点。

监控和管理服务

分解单体应用程序并非一次性过程。它要求随着应用程序及其用户需求的变化而进行维护和更新。监控新的微服务并跟踪关键指标,如响应时间和资源利用率。

 

确保微服务的安全

高度分布式的云原生微服务应用程序带来了复杂的安全问题。它们的潜在漏洞点不是单一的,而是数十个,甚至数百个,每个都必须确保安全。在现代应用程序不断扩大的攻击面中,应用程序接口和代码依赖性只是两个风险源。

网络应用程序和应用程序接口安全

现代应用程序消耗来自一系列来源的输入--标准 Web 请求、移动设备 API 调用、云事件、IoT 设备遥测通信、云存储等。此外,单个客户端的网络请求(即南北向流量)可能会在内部微服务之间产生数百个 API 调用(即东西向流量)。

以 API 为中心的网络应用的复杂性要求采用可扩展、灵活和多层次的策略,这些策略适用于任何类型环境或云架构中的任何类型 工作负载 。仅确保云原生应用程序前端 Web 界面的安全是不够的。云原生应用程序要求应用层保护云原生 API。网络应用程序和应用程序接口安全(WAAS) 是必不可少的。

代码依赖性和软件构成分析

开源软件组件约占云原生应用的 70%。虽然这加快了开发速度,但许多开源包及其依赖包都存在漏洞。此外,依赖驱动的开放源码软件包的每个版本都可能改变关键功能。没有全面的可视性,漏洞就不会被发现。

独立的 软件构成分析(SCA) 工具在开发生命周期的后期才发现开源风险,导致漏洞积压,无法及时解决。将 SCA 和 IaC 安全 工具分开使用会导致警报嘈杂,缺乏背景信息和对相互关联风险的了解。由于在没有运行时和工作负载覆盖的情况下,漏洞是不可避免的,因此最好通过集成的云原生 安全来确保云原生应用程序的安全。

云到代码 CNAPP

云原生应用程序保护平台(CNAPP) 可识别整个云 原生应用程序 的关键风险并进行优先排序,它集成了多种类型的安全功能,可提供全面的代码到云保护--云安全态势管理(CSPM)、云工作负载保护、云基础架构权限管理(CIEM)、Kubernetes 安全态势管理(KSPM)、基础架构即代码安全、WAAS、SCA 等。

云安全领导层在探索如何最好地保护采用容器、微服务和无服务器功能等云原生技术的应用程序的快速开发需求时,应考虑采用 CNAPP。

 

微服务常见问题

所有云原生应用都是微服务应用,但并非所有微服务应用都是云原生应用。微服务架构可在本地部署或云中实施,不一定需要云专用技术或工具。
微服务通过 API 进行通信,API 网关通常被用作中间层,尤其是当应用程序中的服务数量不断增加时。API 网关位于微服务的外围,作为代理管理所有入口流量,提供单一入口点并路由所有请求。
服务网格是应用于基于微服务的系统的专用基础设施层,它使开发人员能够在微服务架构中分离和管理服务与服务之间的通信。服务网格技术可以处理服务发现、负载平衡和流量管理等事务,让开发人员可以专注于编写代码,而不是管理基础设施。
由于微服务是具有多个组件和服务的分布式系统,因此日志记录和监控在维护系统整体健康和性能方面发挥着至关重要的作用。每个微服务都会生成日志,需要对日志进行汇总和分析,以确定系统中存在的问题。
无状态微服务不会在请求之间维护状态信息。它们的设计具有自主性,不依赖先前存储的数据来处理接收到的请求。无状态微服务更易于管理和大规模扩展,但可能需要额外的复杂性来维持多个请求中的数据一致性。无状态微服务通常用于简单而独立的任务,如数据验证或授权,在这些任务中不需要有状态的操作。
有状态微服务是一种维护应用程序状态的微服务。这意味着微服务可以访问并修改在请求之间持久化的数据,其中可能包括用户会话数据、数据库连接或其他状态信息。有状态微服务可带来性能提升、数据一致性改善和应用程序设计复杂性降低等优势。不过,它们确实需要额外的管理,而且可能难以横向大规模扩展。
如果一个领域代表一个要解决的问题--就像在领域驱动设计(DDD)中那样--那么领域模型就是实施问题解决方案的模型。
边界上下文表示领域边界内的一组功能特征,即领域模型。换句话说,正如子域是域的一个区段一样,有界上下文也是解决方案的一个区段。因此,微服务是一种有界上下文,但并非所有有界上下文都是微服务。事实上,有界语境并不一定相互孤立。
分布式跟踪是一种能让开发人员通过多个微服务跟踪请求并识别请求流中任何问题的技术。分布式跟踪工具允许开发人员跟踪系统中的请求流,并识别请求流中的任何瓶颈或问题。
微服务架构是使用微服务模式语言设计和实施的。模式语言包括事件来源、数据管理、通信等模式。
服务发现模式有助于应用程序和服务在分布式微服务环境中相互查找。服务实例会因大规模扩展、升级和服务故障而发生动态变化,这些模式提供了发现机制来应对这种瞬时性。负载平衡可使用服务发现模式,将健康检查和服务故障作为重新平衡流量的触发器。
适配器微服务模式可转换原本不兼容的类或对象之间的关系。依赖第三方应用程序接口的应用程序可能会使用适配器模式来确保应用程序与应用程序接口之间的通信。
Strangler 应用程序模式有助于管理将单体应用程序重构为微服务的过程,具体做法是用微服务慢慢替换单体的各个部分。
后端换前端(BFF)模式可确定数据在服务器和客户端之间的获取方式。BFF 在用户界面和界面所调用的资源之间插入了一个层,允许开发人员为每个用户界面创建和支持一种后端类型,并使用该界面的最佳选项。这反过来又能根据界面需求调整资源,从而提高前端性能。
实体和集合模式以有意义的方式对数据进行分类。例如,一个电子商务网站可能会使用实体模式来表示单个产品,使用集合模式来表示订单,即买家订购的产品集合。
缓存是许多微服务应用程序的重要组成部分,因为它有助于提高性能和减少后端负载。大多数云服务提供商(CSP)都为客户提供托管缓存服务。
对象存储是许多微服务应用不可或缺的一部分,因为它允许存储和检索大型文件和数据对象。大多数 CSP 都提供托管对象存储服务,可用于存储和检索微服务应用程序的对象。