这是关于使用微服务构建应用程序的系列文章的第六篇。第一篇文章介绍了微服务架构模式,并讨论了使用微服务的优缺点。以下文章讨论了微服务架构的不同方面:使用API网关,进程间通信,服务发现和事件驱动的数据管理。在本文中,我们将介绍部署微服务的策略。
部署单体应用意味着运行单个(通常是大型)应用程序的多个相同副本。通常会配置N个服务器(物理或虚拟),并在每个服务器上运行M个实例。单体应用的部署并不总是完全简单,但它比部署微服务应用程序简单得多。
微服务应用程序包含数十甚至数百个服务。服务以各种语言和框架编写,每个都是一个迷你应用程序,具有自己的特定部署,资源,扩展和监控要求。
例如,需要根据根据服务的需求运行每个服务特定数量的实例。同时,必须为每个服务实例提供适当的CPU,内存和I/O资源。
更具挑战性的是:尽管存在这种复杂性,但部署服务必须快速,可靠且具有成本效益。
有一些不同的微服务部署模式。让我们首先看一下每个主机多服务实例模式。
部署微服务的一种方法是使用单主机多服务实例模式。使用此模式时,可以配置一个或多个物理或虚拟主机,并在每个主机上运行多个服务实例。这是应用程序部署的传统方法,每个服务实例都在一个或多个主机上的一个已知的端口上运行。下图显示了此模式的结构。
这种模式有几种变体。
一种变体是:每个服务实例是进程或进程组。例如:
另一个变体是:在同一进程或进程组中运行多个服务实例。例如:
单主机多服务实例模式的优点:
在任何一种情况下,通过网络复制的字节数相对较小。
此外,由于开销很小,所以启动服务通常非常快。如果服务是它自己的进程,你只需启动它。否则,如果服务是在同一容器进程或进程组中运行的多个实例之一,则可以将其动态部署到容器中,也可以重新启动容器。
每个主机多服务实例模式的缺点:
几乎没有服务实例的隔离,除非每个服务实例是一个单独的进程。虽然可以准确地监视每个服务实例的资源利用率,但无法限制每个实例使用的资源。
行为不当的服务实例可能会占用主机的所有内存或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镜像,它克服了我在下面描述的虚拟机的缺点。Boxfuse
将Java应用程序打包为最小的VM镜像。这些镜像构建速度快,启动快,并且因为它们暴露有限的攻击面而更安全。
CloudNative
公司拥有Bakery
,这是一个用于创建EC2 AMI的SaaS产品。可以将CI服务器配置为在微服务通过测试后调用Bakery
。然后,Bakery
将的服务打包为AMI。使用Bakery等SaaS产品意味着不必浪费宝贵的时间来设置AMI创建基础架构。
单虚拟机单服务实例模式的优点:
单虚拟机单服务实例模式的缺点:
Boxfuse
构建的轻量级VM)Boxfuse
这样的工具来处理构建和管理VM的开销。这项必要但耗时的活动会分散的核心业务。现在让我们看一下部署微服务的替代方法,这些微服务更轻量级但仍具有VM的许多优点。
当使用单容器单服务实例模式时,每个服务实例都在其自己的容器中运行。容器是操作系统级别的虚拟化机制,在沙箱中运行的一个或多个进程,它们有自己的端口、命名空间、根文件系统,可以限制容器的内存和CPU资源,某些容器实现也具有I/O速率限制。容器技术的示例包括Docker
和Solaris Zones
。下图显示了此模式的结构:
要使用此模式,请将服务打包为容器镜像(是由运行服务所需的应用程序和库组成的文件系统镜像)。一些容器镜像由完整的Linux根文件系统组成,其他更轻巧。
例如,要部署Java服务,需要构建一个包含Java运行时(可能是Apache Tomcat服务器)和已编译的Java应用程序的容器镜像。将服务打包为容器镜像后,即可启动一个或多个容器。
通常在每个物理或虚拟主机上运行多个容器,可以使用集群管理器(如Kubernetes或Marathon)来管理容器。集群管理器将主机视为资源池,根据容器所需的资源和每个主机上可用的资源决定放置每个容器的位置。
单容器单服务实例模式的好处类似于VM的好处:
单容器单服务实例模式的缺点:
容器通常部署在收费的虚拟机基础架构上,因此,为了处理负载峰值,可能会产生过度配置VM的额外成本。有趣的是,容器和虚拟机之间的区别可能会变得模糊。如前所述,Boxfuse VM的构建和启动速度很快。
Clear Containers项目旨在创建轻量级VM。正如2017年12月宣布的那样,Clear Containers的开发现在继续在开源Kata Containers项目中进行。对unikernel的关注越来越多, Docker Inc.
最近收购了Unikernel Systems
。
还有一种更新且越来越流行的无服务器部署概念,这种方法可以避免在容器或虚拟机中部署服务之间做出选择的问题。让我们看看下一步。
AWS Lambda是无服务部署技术的一个示例。它支持Java,Node.js和Python服务。要部署微服务:
AWS Lambda自动运行足够的微服务实例来处理请求。只需根据所花费的时间和消耗的内存为每个请求付费。当然,魔鬼在细节中,很快就会看到AWS Lambda有局限性。但是,作为开发人员或组织中的任何人都不需要担心服务器,虚拟机或容器的任何方面,这一概念令人难以置信。
Lambda函数是无状态服务。它通常通过调用AWS服务来处理请求。例如,将镜像上载到S3存储桶时调用的Lambda函数可以将数据项插入DynamoDB镜像表,并将消息发布到Kinesis流以触发镜像处理。Lambda函数还可以调用第三方Web服务。
有四种方法可以调用Lambda函数:
AWS Lambda是部署微服务的便捷方式。基于请求的定价意味着只需为服务实际执行的工作付费。此外,由于不负责IT基础架构,因此可以专注于开发应用程序。
但是,有一些重大的局限性,它不能用于部署长时间运行的服务(例如,使用来自第三方消息代理的消息服务):
部署微服务应用程序具有挑战性。有数十甚至数百种服务以各种语言和框架编写,每个都是一个迷你应用程序,具有自己的特定部署模式,资源,扩展和监视要求。
有几种微服务部署模式,包括:
在本系列的下一部分和最后一部分中,我们将介绍如何将单体应用迁移到微服务架构。