这七个系列的文章现在完成:
- 微服务介绍
- 构建微服务:使用API网关
- 构建微服务:微服务架构中的进程间通信
- 微服务架构中的服务发现
- 事件驱动的数据管理微服务
- 选择微服务部署策略(本文)
- 将重组重构为微服务
您还可以下载完整的文章集,以及使用NGINX Plus实现微服务的信息,作为电子书 -微服务:从设计到部署。
这是关于使用微服务构建应用程序的第六篇文章。在第一篇文章介绍了微服务架构模式,并讨论的好处和使用微服务的缺点。以下文章讨论微服务架构的不同方面:使用API网关,进程间通信,服务发现和事件驱动的数据管理。在本文中,我们讨论部署微服务的策略。
动机
部署单片应用程序意味着运行单个通常是大型应用程序的多个相同副本。您通常配置N个服务器(物理或虚拟),并在每个服务器上运行应用程序的M个实例。单片应用程序的部署并不总是完全直接的,但它比部署微服务应用程序简单得多。
一个微服务的应用程序包含几十个甚至数百个服务的。服务以各种语言和框架编写。每个都是具有自己的特定部署,资源,扩展和监视要求的小型应用程序。例如,您需要根据该服务的需求运行每个服务的一定数量的实例。此外,必须为每个服务实例提供适当的CPU,内存和I / O资源。更有挑战性的是,尽管这种复杂性,部署服务必须快速,可靠和具有成本效益。
有几种不同的微服务部署模式。让我们首先看一下每个主机的多个服务实例模式。
每个主机模式的多个服务实例
部署微服务的一种方法是使用每个主机的多个服务实例模式。使用此模式时,您可以配置一个或多个物理或虚拟主机,并在每个主机上运行多个服务实例。在许多方面,这是传统的应用部署方法。每个服务实例在一个或多个主机上的公知端口运行。主机通常像宠物一样治疗。
下图显示了此模式的结构。
有这种模式的几个变体。一个变体是每个服务实例是进程或进程组。例如,您可以将Java服务实例部署为Apache Tomcat服务器上的Web应用程序。一个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有面包店,一个用于创建EC2 AMI的SaaS产品。您可以将CI服务器配置为在对微服务传递进行测试后调用面包店。然后面包店将您的服务打包为AMI。使用SaaS产品(如面包店)意味着您不必浪费宝贵的时间来设置AMI创建基础架构。
每个虚拟机服务实例模式具有许多优点。VM的一个主要优点是每个服务实例以完全隔离的方式运行。它具有固定数量的CPU和内存,不能从其他服务窃取资源。
将微服务部署为VM的另一个好处是,您可以利用成熟的云基础架构。AWS等AWS提供了有用的功能,如负载平衡和自动扩展。
将服务部署为VM的另一个好处是它封装了您的服务的实现技术。一旦服务被打包为VM,它将变成一个黑盒子。VM的管理API成为部署服务的API。部署变得更简单和更可靠。
然而,每个虚拟机服务实例模式有一些缺点。一个缺点是资源利用效率较低。每个服务实例都有整个VM的开销,包括操作系统。此外,在典型的公共IaaS中,VM具有固定大小,并且VM可能未充分利用。
移动,公共IaaS通常对VM收费,而不管它们是忙还是空闲。诸如AWS之类的IaaS提供自动缩放,但是很难对需求变化做出快速反应。因此,您经常必须过度配置VM,这增加了部署成本。
这种方法的另一个缺点是部署新版本的服务通常很慢。VM映像由于其大小通常缓慢构建。此外,VM通常很慢实例化,也是因为它们的大小。此外,操作系统通常需要一些时间来启动。然而,请注意,这并不是普遍真实的,因为存在轻量级VM,如由Boxfuse构建的VM。
每个虚拟机服务实例模式的另一个缺点是,通常你(或你的组织中的其他人)负责许多未分化的繁重工作。除非您使用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秒钟。容器也启动非常快,因为没有冗长的操作系统启动机制。当容器启动时,运行的是服务。
使用容器有一些缺点。虽然容器基础设施正在快速成熟,但它不像虚拟机的基础设施那么成熟。另外,容器不如VM安全,因为容器与主机OS共享内核。
容器的另一个缺点是,你负责管理容器图像的未分化繁重。此外,除非您使用托管容器解决方案(如Google容器引擎或Amazon EC2容器服务(ECS)),否则您必须管理容器基础架构以及可能运行的基础架构。
此外,容器通常部署在具有每个VM定价的基础设施上。因此,如前所述,您可能会承担过度配置虚拟机的额外成本,以处理负载峰值。
有趣的是,容器和VM之间的区别很可能模糊。如前所述,Boxfuse VM快速构建和启动。该清除容器项目旨在打造轻量级虚拟机。人们对unikernels也越来越感兴趣。Docker最近收购了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函数:
- 直接,使用Web服务请求
- 自动响应由AWS服务(如S3,DynamoDB,Kinesis或简单电子邮件服务)生成的事件
- 自动通过AWS API网关处理来自应用程序客户端的HTTP请求
- 定期,根据
cron
类似的时间表
如您所见,AWS Lambda是部署微服务的一种方便的方法。基于请求的定价意味着您只需为您的服务实际执行的工作付费。此外,因为您不负责IT基础架构,您可以专注于开发应用程序。
然而,存在一些显着的限制。它不用于部署长时间运行的服务,例如使用来自第三方消息代理的消息的服务。请求必须在300秒内完成。服务必须是无状态的,因为在理论上AWS Lambda可能为每个请求运行单独的实例。它们必须以支持的语言之一编写。服务也必须快速启动;否则,它们可能超时并终止。
概要
部署微服务应用程序具有挑战性。有几十甚至几百种服务以各种语言和框架编写。每个都是一个小型应用程序,具有自己的特定部署,资源,扩展和监控要求。有几种微服务部署模式,包括每个虚拟机的服务实例和每个容器的服务实例。部署微服务的另一个有趣的选择是AWS Lambda,一种无服务器方法。在本系列的下一部分和最后一部分中,我们将讨论如何将单片应用程序迁移到微服务体系结构。
这七个系列的文章现在完成:
- 微服务介绍
- 构建微服务:使用API网关
- 构建微服务:微服务架构中的进程间通信
- 微服务架构中的服务发现
- 事件驱动的数据管理微服务
- 选择微服务部署策略(本文)
- 将重组重构为微服务
您还可以下载完整的文章集,以及使用NGINX Plus实现微服务的信息,作为电子书 -微服务:从设计到部署。