克里斯·理查森(ChrisRichardson)。
部署单片应用意味着运行单个应用程序(通常是大型应用程序)的多个相同副本。您通常提供N个服务器(物理或虚拟),并在每个服务器上运行应用程序的M个实例。单块应用程序的部署并不总是完全简单的,但它比部署微服务应用程序简单得多。
A 微服务应用由数十甚至数百个服务组成。服务是用各种语言和框架编写的。每个应用程序都是一个小型应用程序,具有自己的特定部署、资源、缩放和监视需求。例如,您需要根据对该服务的需求运行每个服务的一定数量的实例。此外,必须为每个服务实例提供适当的CPU、内存和I/O资源。更具有挑战性的是,尽管如此复杂,部署服务必须是快速、可靠和具有成本效益的。
有几种不同的微服务部署模式。让我们先看看每个主机模式的多个服务实例。
部署微服务的一种方法是使用每个主机多个服务实例模式。使用此模式时,可以提供一个或多个物理或虚拟主机,并在每个主机上运行多个服务实例。在许多方面,这是传统的应用程序部署方法。每个服务实例在一个或多个主机上运行在一个众所周知的端口上。主机通常是像宠物一样对待.
下图显示了此模式的结构。
这种模式有几个变体。一个变体是每个服务实例都是一个流程或一个进程组。例如,您可以将Java服务实例作为web应用程序部署到阿帕奇Tomcat服务器。一个Node.js服务实例可以由父进程和一个或多个子进程组成。
此模式的另一个变体是在同一个进程或进程组中运行多个服务实例。例如,您可以在同一个ApacheTomcat服务器上部署多个JavaWeb应用程序,或者在同一个OSGI容器中运行多个OSGI包。
每个主机模式的多个服务实例既有优点,也有缺点。一个主要的好处是它的资源使用是相对有效的。多个服务实例共享服务器及其操作系统。如果一个进程或进程组运行多个服务实例,例如,共享同一个ApacheTomcat服务器和JVM的多个Web应用程序,则效率更高。
这种模式的另一个好处是部署服务实例相对较快。您只需将服务复制到主机并启动它。如果服务是用Java编写的,则复制JAR或WAR文件。对于其他语言,如Node.js或Ruby,您可以复制源代码。在这两种情况下,通过网络复制的字节数都相对较少。
此外,由于缺乏开销,启动服务通常是非常快的。如果服务是它自己的进程,您只需启动它。否则,如果服务是在同一个容器进程或进程组中运行的多个实例之一,则可以将其动态部署到容器中,或者重新启动容器。
尽管具有吸引力,但每个主机模式的多个服务实例仍有一些明显的缺陷。一个主要的缺点是服务实例很少或根本没有隔离,除非每个服务实例是一个单独的进程。虽然可以准确地监视每个服务实例的资源利用率,但不能限制每个实例使用的资源。不正常的服务实例有可能消耗主机的所有内存或CPU。
如果多个服务实例在同一进程中运行,则根本不存在隔离。例如,所有实例都可能共享同一个JVM堆。行为不当的服务实例很容易破坏在同一进程中运行的其他服务。此外,您无法监视每个服务实例使用的资源。
这种方法的另一个重要问题是,部署服务的操作团队必须知道如何执行服务的具体细节。服务可以用多种语言和框架编写,因此开发团队必须与操作共享许多细节。这种复杂性增加了部署期间出错的风险。
正如您所看到的,尽管熟悉多个服务实例,但每个主机模式都有一些明显的缺陷。现在让我们看看部署微服务以避免这些问题的其他方法。
部署微服务的另一种方法是每个主机的服务实例模式。使用此模式时,可以在其自己的主机上单独运行每个服务实例。这种模式有两种不同的特性:每个虚拟机的服务实例和每个容器的服务实例。
当你使用每个虚拟机的服务实例模式,您可以将每个服务打包为虚拟机(VM)映像,例如AmazonEC 2 AMI。每个服务实例都是使用VM映像启动的VM(例如,EC2实例)。下图显示了此模式的结构:
这是Netflix部署其视频流服务的主要方法。Netflix使用氨基酯。每个正在运行的服务实例都是一个EC2实例。
您可以使用多种工具来构建自己的VM。您可以配置您的持续集成(CI)服务器(例如,詹金斯)调用aminator将您的服务打包为EC2AMI。Packer.io是自动创建VM映像的另一种选择。与aminator不同,它支持多种虚拟化技术,包括EC2、DigitalSea、VirtualBox和VMware。
公司箱式保险丝有一种引人注目的方法来构建VM映像,这克服了下面我描述的VM的缺点。BoxFUSE将Java应用程序打包为一个最小的VM映像。这些映像构建速度快,启动速度快,而且由于它们暴露了有限的攻击面,因此更安全。
公司云人有面包店,一个SaaS产品,用于创建EC2Amis。您可以配置您的CI服务器,以便在测试您的微服务通行证之后调用Bakery。面包店然后将您的服务包装为AMI。使用SaaS产品(如Bakery)意味着您不必浪费宝贵的时间来设置AMI创建基础设施。
每个虚拟机模式的服务实例有许多优点。VM的一个主要好处是每个服务实例都在完全隔离状态下运行。它有固定数量的CPU和内存,不能从其他服务中窃取资源。
将微服务部署为VM的另一个好处是可以利用成熟的云基础设施。像AWS这样的云提供了一些有用的特性,比如负载平衡和自动标度。
将服务部署为VM的另一个好处是,它封装了服务的实现技术。一旦一个服务被打包成一个VM,它就变成了一个黑匣子。VM的管理API成为部署服务的API。部署变得更加简单和可靠。
但是,每个虚拟机模式的服务实例有一些缺点。一个缺点是资源利用率不高。每个服务实例都有整个VM(包括操作系统)的开销。此外,在一个典型的公共IaaS中,VM的大小是固定的,并且VM可能没有得到充分的利用。
移动操作时,公共IaaS通常会向VM收费,而不管它们是繁忙的还是空闲的。IaaS(如AWS)提供自动标度,但它是很难对需求的变化迅速作出反应。因此,您经常不得不过多地提供VM,这会增加部署成本。
这种方法的另一个缺点是,部署新版本的服务通常很慢。由于VM映像的大小,它们的构建速度通常很慢。另外,VM的实例化速度通常很慢,这也是因为它们的大小。另外,操作系统通常需要一些时间来启动。但是,请注意,这并不是普遍正确的,因为轻量级VM(如BoxFUSE构建的VM)是存在的。
每个虚拟机模式的服务实例的另一个缺点是,通常您(或组织中的其他人)负责许多未区分的繁重工作。除非您使用诸如Box引信这样的工具来处理构建和管理VM的开销,否则这是您的责任。这种必要但耗时的活动分散了你核心业务的注意力。
现在让我们看看部署微服务的另一种方法,它更轻量级,但仍然具有VM的许多好处。
当您使用每个容器的服务实例模式,每个服务实例都在自己的容器中运行。容器是操作系统级的虚拟化机制。容器由在沙箱中运行的一个或多个进程组成。从进程的角度来看,它们有自己的端口命名空间和根文件系统。您可以限制容器的内存和CPU资源。一些容器实现也有I/O速率限制。集装箱技术的例子包括码头工人和Solaris区.
下图显示了此模式的结构:
要使用此模式,您可以将服务打包为容器映像。容器映像是由运行服务所需的应用程序和库组成的文件系统映像。一些容器映像由一个完整的Linux根文件系统组成。其他的则更轻巧。例如,要部署Java服务,您可以构建一个容器映像,其中包含Java运行时、可能是ApacheTomcat服务器以及已编译的Java应用程序。
一旦将服务打包为容器映像,然后启动一个或多个容器。通常在每个物理或虚拟主机上运行多个容器。您可以使用群集管理器,例如库伯奈特斯或马拉松来管理你的集装箱。群集管理器将主机视为资源库。它根据容器所需的资源和每个主机上可用的资源来决定将每个容器放在哪里。
每个容器模式的服务实例既有优点,也有缺点。集装箱的好处与越南船民相似。它们将服务实例彼此隔离开来。您可以轻松地监视每个容器所消耗的资源。此外,与VM一样,容器封装用于实现服务的技术。容器管理API也用作管理服务的API。
然而,与VM不同,容器是一种轻量级技术。容器映像通常构建得非常快。例如,在我的笔记本上,打包一个弹簧靴应用程序作为码头容器。容器的启动速度也非常快,因为没有冗长的OS引导机制。当容器启动时,运行的是服务。
使用容器有一些缺点。虽然集装箱基础设施正在迅速成熟,但它还不如VM的基础设施那么成熟。另外,容器并不像VM那样安全,因为容器彼此共享主机操作系统的内核。
容器的另一个缺点是,您负责管理容器映像的未区分的繁重工作。另外,除非您使用的是托管容器解决方案,如Google容器引擎或AmazonEC 2集装箱服务(ECS),那么您必须管理容器基础结构,并可能管理运行它的VM基础结构。
此外,容器通常部署在具有每个VM定价的基础设施上。因此,正如前面所描述的,您可能需要额外的额外成本来处理负载中的峰值。
有趣的是,集装箱和越野车之间的区别可能会变得模糊。如前所述,BoxfuseVM构建和启动速度很快。ClearContainers项目的目标是创建轻量级VM。[编辑器-正如2017年12月宣布的那样,透明容器的开发正在开放源码中继续进行。Kata容器项目]也有越来越多的兴趣单核。码头公司最近收购了UniKernSystems。
还有一种更新的、越来越流行的无服务器部署概念,这种方法避免了在容器中部署服务还是在VM中部署服务的问题。接下来让我们看看这个。
拉姆达是无服务器部署技术的一个示例。它支持Java、Node.js和Python服务。要部署一个微服务,您可以将其打包为一个ZIP文件,并将其上传到AWSLambda。您还提供了元数据,除其他外,元数据指定了为处理请求而调用的函数的名称(a.k.a)。(一项活动)。AWSLambda自动运行足够多的微服务实例来处理请求。您只需根据所花费的时间和占用的内存对每个请求进行计费。当然,问题在于细节,您很快就会看到AWSLambda有其局限性。但是,无论是作为开发人员还是组织中的任何人都不需要担心服务器、虚拟机或容器的任何方面,这种想法令人难以置信地吸引人。
A Lambda函数是无状态服务。它通常通过调用AWS服务来处理请求。例如,在将图像上传到S3桶时调用的Lambda函数可以将项插入DynamoDB映像表,并将消息发布到Kinesis流以触发图像处理。Lambda函数也可以调用第三方web服务。
有四种方法可以调用Lambda函数:
cron
-类似时间表如您所见,AWSLambda是部署微服务的一种方便方法。基于请求的定价意味着您只为服务实际执行的工作付费。另外,由于您不负责IT基础设施,所以您可以集中精力开发您的应用程序。
然而,也有一些重大的限制。它不打算用于部署长期运行的服务,例如使用来自第三方消息代理的消息的服务。请求必须在300秒内完成。服务必须是无状态的,因为理论上AWS Lambda可以为每个请求运行一个单独的实例。它们必须用支持的语言之一编写。服务也必须快速启动;否则,它们可能会超时并终止。
部署微服务应用程序具有挑战性。有几十甚至数百个服务是用各种语言和框架编写的。每个应用程序都是一个小型应用程序,具有自己的特定部署、资源、缩放和监视需求。有几种微服务部署模式,包括每个虚拟机的服务实例和每个容器的服务实例。部署微服务的另一个有趣的选择是AWS Lambda,一种无服务器的方法。在本系列的下一个也是最后一个部分中,我们将研究如何将单块应用程序迁移到微服务体系结构