部署单体应用程序的时候 , 我们往往需要运行单个的通常也是大型应用程序的多个相同副本。通常 , 您需要配置 N 台服务器 ( 物理服务器或虚拟服务器 ), 并在每台服务器上运行 M 个应用程序实例。单体应用程序的部署并非总是完全简单的 , 但比部署微服务应用程序要简单得多。
微服务应用程序包含数十甚至数百个服务。服务以多种语言和框架编写。每个应用程序都是一个微型应用程序 , 具有自己的特定部署 , 资源 , 扩展和监视要求。例如 , 我们需要根据对该服务的需求运行一定数量的每个服务的实例。另外 , 必须为每个服务实例提供适当的 CPU, 内存和 I / O 资源。更具挑战性的是 , 尽管存在这种复杂性 , 但部署服务必须快速 , 可靠且具有成本效益。
有几种不同的微服务部署模式。首先是每个主机多个服务实例的模式。
每个主机多个服务实例模式
部署微服务的一种方法是使用“每个主机多个服务实例”模式。使用此模式时 , 您将配置一个或多个物理或虚拟主机 , 并在每个虚拟或虚拟主机上运行多个服务实例。这是应用程序部署的传统方法。每个服务实例在一个或多个主机上的一个端口上运行。
下图显示了此模式的结构。
此模式有多种变体。每个服务实例的一个变体是一个流程或一个流程组。例如 , 您可以将 Java 服务实例作为 Web 应用程序部署在 Apache Tomcat 服务器上。一个 Node.js 服务实例可能包含一个父进程和一个或多个子进程。
此模式的另一个变体是在同一进程或进程组中运行多个服务实例。例如 , 您可以在同一 Apache Tomcat 服务器上部署多个 Java Web 应用程序 , 或在同一 OSGI 容器中运行多个 OSGI 捆绑软件。
每个主机多个服务实例模式既有优点也有缺点。一个主要的好处是它的资源使用相对高效。多个服务实例共享服务器及其操作系统。如果一个进程或进程组运行多个服务实例 , 例如共享同一个 Apache Tomcat 服务器和 JVM 的多个 Web 应用程序 , 则效率更高。
这种模式的另一个好处是 , 部署服务实例相对较快。您只需将服务复制到主机并启动即可。如果服务是用 Java 编写的 , 则可以复制 JAR 或 WAR 文件。对于其他语言 , 例如 Node.js 或 Ruby, 则复制源代码。无论哪种情况 , 通过网络复制的字节数都相对较小。
另外 , 由于缺少开销 , 因此启动服务通常非常快。如果服务是它自己的过程 , 则只需启动它。否则 , 如果服务是在同一容器进程或进程组中运行的多个实例之一 , 则可以将其动态部署到容器中或重新启动容器。
尽管具有吸引力 , 但“每个主机的多个服务实例”模式仍存在一些重大缺陷。一个主要缺点是 , 除非每个服务实例是一个单独的进程 , 否则服务实例几乎没有隔离。虽然您可以准确地监视每个服务实例的资源利用率 , 但不能限制每个实例使用的资源。行为异常的服务实例可能会占用主机的所有内存或 CPU。
如果多个服务实例在同一进程中运行 , 则根本没有隔离。例如 , 所有实例可能 共享相同的 JVM 堆。行为异常的服务实例很容易破坏在同一进程中运行的其他服务。此外 , 您无法监视每个服务实例使用的资源。
这种方法的另一个重要问题是 , 部署服务的运营团队必须知道如何执行服务的具体细节。服务可以用多种语言和框架编写 , 因此开发团队必须与操作共享许多细节。这种复杂性增加了部署期间出错的风险。
如您所见 , 尽管很熟悉 , 但是“每个主机的多个服务实例”模式仍存在一些重大缺陷。现在 , 让我们看一下避免这些问题的其他微服务部署方式。
一个主机一个服务实例模式
部署微服务的另一种方法是“每主机服务实例”模式。使用此模式时 , 每个服务实例都在其自己的主机上独立运行。此模式有两种不同的专业化 : 每个虚拟机的服务实例和 , 每个容器的服务实例。
一个虚拟机一个服务实例模式
使用每个虚拟机模式的服务实例时 , 会将每个服务打包为虚拟机 (VM) 映像 , 例如 Amazon EC2 AMI。每个服务实例都是使用该 VM 映像启动的 VM( 例如 ,EC2 实例 )。下图显示了此模式的结构
这是 Netflix 部署其视频流服务的主要方法。Netflix 使用 Aminator 将其每项服务打包为 EC2 AMI。每个正在运行的服务实例都是一个 EC2 实例。
您可以使用多种工具来构建自己的 VM。您可以配置持续集成 (CI) 服务器 ( 例如 Jenkins) 以调用 Aminator 将服务打包为 EC2 AMI。Packer.io 是用于自动创建 VM 映像的另一个选项。与 Aminator 不同 , 它支持多种虚拟化技术 , 包括 EC2,DigitalOcean,VirtualBox 和 VMware。
Boxfuse 公司有一种引人注目的方式来构建 VM 映像 , 它克服了我在下面描述的 VM 的缺点。Boxfuse 将 Java 应用程序打包为最小的 VM 映像。由于这些映像暴露出有限的攻击面 , 因此它们可以快速构建 , 快速启动并且更安全。
CloudNative 公司拥有 Bakery, 这是一个 SaaS 产品 , 用于创建 EC2 AMI。您可以将 CI 服务器配置为在微服务测试通过后调用面包店。然后 , 面包店将您的服务打包为 AMI。使用 Bakery 等 SaaS 产品意味着您不必浪费宝贵的时间来建立 AMI 创建基础架构。
每个虚拟机模式的服务实例有很多好处。VM 的主要优点是 , 每个服务实例都可以完全隔离地运行。它具有固定数量的 CPU 和内存 , 无法从其他服务中窃取资源。
将微服务部署为 VM 的另一个好处是 , 您可以利用成熟的云基础架构。AWS 之类的云提供了有用的功能 , 例如负载平衡和自动扩展。
将服务部署为 VM 的另一个好处是 , 它封装了服务的实施技术。将服务打包为 VM 后 , 它将变成一个黑匣子。VM 的管理 API 成为用于部署服务的 API。部署变得更加简单和可靠。
但是 , 每个虚拟机的服务实例模式有一些缺点。一个缺点是资源利用效率较低。每个服务实例都有整个 VM( 包括操作系统 ) 的开销。此外 , 在典型的公共 IaaS 中 ,VM 具有固定的大小 , 并且 VM 使用率可能不足。
迁移时 , 公共 IaaS 通常对 VM 收费 , 而不管它们是忙还是闲。像 AWS 这样的 IaaS 可提供自动扩展功能 , 但是很难对需求变化做出快速反应。因此 , 您通常必须过量配置 VM, 这会增加部署成本。
这种方法的另一个缺点是 , 部署新版本的服务通常很慢。由于 VM 映像的大小 , 其生成速度通常很慢。同样 , 再次由于其大小 ,VM 实例化速度通常很慢。另外 , 操作系统通常需要一些时间才能启动。但是请注意 , 这并不是普遍适用的 , 因为存在轻量级 VM, 例如 Boxfuse 构建的那些。
每个虚拟机服务实例模式的另一个缺点是通常您 ( 或组织中的其他人 ) 要承担很多无差别的工作。除非您使用 Boxfuse 之类的工具来处理构建和管理 VM 的开销 , 否则这是您的责任。这项必要但耗时的活动分散了您的核心业务。
一个容器一个服务实例模式
当您使用“每个容器的服务实例”模式时 , 每个服务实例都在其自己的容器中运行。容器是操作系统级别的虚拟化机制。容器由在沙箱中运行的一个或多个进程组成。从进程的角度来看 , 它们具有自己的端口名称空间和根文件系统。您可以限制容器的内存和 CPU 资源。一些容器实现也具有 I / O 速率限制。容器技术的示例包括 Docker 和 Solaris Zones。
下图显示了此模式的结构 :
要使用此模式 , 请将服务打包为容器映像。容器映像是由运行服务所需的应用程序和库组成的文件系统映像。一些容器映像由完整的 Linux 根文件系统组成。其他则更轻巧。例如 , 要部署 Java 服务 , 您需要构建一个容器映像 , 其中包含 Java 运行时 ( 可能是 Apache Tomcat 服务器 ) 和已编译的 Java 应用程序。
将服务打包为容器映像后 , 便可以启动一个或多个容器。通常 , 您在每个物理或虚拟主机上运行多个容器。您可以使用集群管理器 ( 例如 Kubernetes 或 Marathon) 来管理容器。集群管理器将主机视为资源池。它根据容器所需的资源和每个主机上可用的资源来决定将每个容器放置在何处。
每个容器的服务实例模式既有优点也有缺点。容器的好处类似于 VM 的好处。它们将您的服务实例彼此隔离。您可以轻松地监视每个容器消耗的资源。另外 , 容器与 VM 一样 , 封装了用于实现服务的技术。容器管理 API 也可用作管理服务的 API。
但是 , 与 VM 不同 , 容器是一种轻量级技术。容器映像通常构建起来非常快。例如 , 在我的笔记本电脑上 , 将 Spring Boot 应用程序打包为 Docker 容器仅需 5 秒钟。由于没有冗长的 OS 启动机制 , 因此容器也可以非常快速地启动。当容器启动时 , 运行的是服务。
使用容器有一些缺点。尽管容器基础结构日趋成熟 , 但它不如 VM 基础结构成熟。另外 , 容器不如 VM 安全 , 因为容器彼此共享主机 OS 的内核。
容器的另一个缺点是 , 您要对管理容器图像进行无差别的繁重工作负责。另外 , 除非您使用托管容器解决方案 ( 例如 Google Container Engine 或 Amazon EC2 容器服务 (ECS)), 否则您必须管理容器基础架构以及可能在其上运行的 VM 基础架构。
此外 , 容器通常部署在按虚拟机定价的基础架构上。因此 , 如前所述 , 您可能会产生过度配置 VM 的额外费用 , 以处理负载高峰。
有趣的是 , 容器和 VM 之间的区别可能会模糊。如前所述 ,Boxfuse VM 可以快速构建和启动。Clear Containers 项目旨在创建轻量级 VM。[编辑–正如 2017 年 12 月宣布的那样 , 开源容器 Kata Containers 项目现在继续进行 Clear Containers 的开发。]对 Unikernels 的兴趣也越来越大。Docker,Inc. 最近收购了 Unikernel Systems。
还有一种新的和越来越流行的无服务器部署概念 , 它是一种避免必须在容器或 VM 中部署服务之间进行选择的问题的方法。接下来让我们看看。
无服务器部署
AWS Lambda 是无服务器部署技术的示例。它支持 Java,Node.js 和 Python 服务。要部署微服务 , 请将其打包为 ZIP 文件 , 然后将其上传到 AWS Lambda。您还提供元数据 , 元数据除其他事项外 , 该元数据指定为处理请求 ( 也称为事件 ) 而调用的函数的名称。AWS Lambda 自动运行您的微服务的足够实例来处理请求。您只需根据花费的时间和消耗的内存为每个请求付费。当然 , 细节中有魔鬼 , 您很快就会看到 AWS Lambda 有局限性。但是 , 无论您是开发人员还是组织中的任何人都不需要担心服务器 , 虚拟机或容器的任何方面的想法令人着迷。
Lambda 函数是无状态服务。它通常通过调用 AWS 服务来处理请求。例如 , 将图像上载到 S3 存储桶时调用的 Lambda 函数可以将项目插入 DynamoDB 图像表中 , 并将消息发布到 Kinesis 流以触发图像处理。Lambda 函数还可以调用第三方 Web 服务。
有四种方法可以调用 Lambda 函数 :
- 直接使用网络服务请求
- 自动响应由 AWS 服务 ( 例如 S3,DynamoDB,Kinesis 或简单电子邮件服务 ) 生成的事件
- 通过 AWS API 网关自动处理来自应用程序客户端的 HTTP 请求
- 按照类似 cron 的时间表定期
如您所见 ,AWS Lambda 是部署微服务的便捷方法。基于请求的定价意味着您只需为服务实际执行的工作付费。另外 , 由于您不对 IT 基础结构负责 , 因此您可以专注于开发应用程序。
但是 , 存在一些重大限制。它不打算用于部署长期运行的服务 , 例如消耗来自第三方消息代理的消息的服务。请求必须在 300 秒内完成。服务必须是无状态的 , 因为从理论上讲 ,AWS Lambda 可能会为每个请求运行一个单独的实例。必须使用一种受支持的语言编写它们。服务还必须快速启动 ; 否则 , 它们可能会超时并终止。
总结
部署微服务应用程序具有挑战性。以多种语言和框架编写的服务有数十甚至数百种。每个应用程序都是一个微型应用程序 , 具有自己的特定部署 , 资源 , 扩展和监视要求。有几种微服务部署模式 , 包括每个虚拟机的服务实例和每个容器的服务实例。部署微服务的另一个有趣的选择是无服务器方法 AWS Lambda。
原文链接:https://blog.csdn.net/topdeveloperr/article/details/105430644