Chris Richardson 微服务系列翻译全7篇链接:

原文链接:Choosing a Microservices Deployment Strategy


动机

部署一个单体应用意味着运行着庞大应用的多个副本,通常需要 N 台服务器(物理机或虚拟机),在每台服务器上运行 M 个应用实例。部署单体应用一般并不特别直接,但还是比部署微服务应用简单。

一个微服务应用包括几十甚至数百个服务,使用不同的语言和框架写成,每个服务都是一个拥有特定的部署、资源、扩展性及监控需求的小应用。例如:根据服务需求运行若干个服务实例,而且每个服务实例必须配套提供适当的 CPU、内存 和 I/O 资源。更具挑战性的是,部署服务还必须快速、可靠、高效。

单主机部署多服务实例

该模式下,需要多台物理机或虚拟机,在每个主机上部署多个服务实例。这是比较传统的部署方法。每个服务实例运行在一至多台主机的端口上,主机通常像照看宠物一样来管理这些服务。如下图所示:

这一模式有几个变型。其中之一就是每个服务对应一个或一组进程。例如:在 Apache Tomcat 服务器上部署 Java 服务实例作为 web 应用,一个 Node.js 服务实例可能包含一个父进程或一至多个子进程。

另一个变型是在一个进程或进程组中运行多个服务实例。例如:在同一台 Apache Tomcat 服务器中部署多个 Java web 应用,或者在一个 OSGI 容器中运行多个 OSGI 组件。

单主机多服务部署的优点:

1)资源利用率高,多个服务实例共享服务器及操作系统。如果一个进程或进程组运行多个服务实例的话,效率就更高了,比如多个web应用共享同一台 Apache Tomcat 服务器和 JVM。

2)部署服务实例快,只需将服务拷贝到主机并启动。如果服务是 Java 编写的,复制 JAR包 或者 WAR 包;如果是 Node.js 或者 Ruby 等其它语言,拷贝源代码即可。通过网络复制这些字节数还是比较小的。

3)由于没有太多开销,启动服务通常很快。如果服务实例运行在同一容器的进程或进程组,可以动态部署到容器或使用重启容器的方式启动服务。

不足在于:

1)服务实例之间没有隔离。虽然可以准确监控每个服务实例的资源使用情况,但是并不能限制每个实例使用的资源,很有可能一个异常的服务实例会消耗掉主机的所有内存和 CPU资源。

2)同一进程运行多个服务实例根本没有隔离性,所有服务实例共享一个 JVM 堆。一个异常的服务实例能够轻易的破坏运行在同一进程中的其它服务实例。此外,也无法监控每个服务资源使用的情况。

3)对运维团队来讲,需要了解部署服务的具体细节。服务可能用不同的语言和框架写成,因而开发团队必须分享给运维团队大量的细节。这种复杂性增加了部署中出错的风险。

每个主机一个服务实例

这一模式有两种不同实现:每台虚拟机部署一个服务实例和每台容器部署一个服务实例。

每台虚拟机一个服务实例

该模式下,把每个服务打包为一个虚拟机镜像,例如 Amazon EC2 AMI。每个服务实例(例如 EC2 实例)使用虚拟机镜像启动。下图展示了此模式的结构:

这也是 Netflix 部署视频流媒体服务的最初方案。Netflix 使用 Aminator 把每个服务实例打包成 EC2 AMI,每个运行的服务实例就是一个 EC2 实例。

有多种工具可用来构建虚拟机镜像。可以配置持续集成(CI)服务器(例如 Jenkins)来调用 Aminator,把服务打包为 EC2 AMI。Packer.io 是另一个自动化创建虚拟机镜像的工具,不同于 Aminator,它支持包括 EC2、DigitalOcean、VirtualBox 和 VMware 在内的多种不同虚拟化技术。

Boxfuse 公司使用更加优秀的方式来构建虚拟机镜像,克服了下面会讲到的虚拟机镜像的不足。Boxfuse 把 Java 应用打包为一个迷你的虚拟机镜像。这些镜像能够快速构建、启动,由于只暴露了有限的可能被攻击的端口,所以也更安全。

CloudNative 使用 Bakery 这款 SaaS 工具来创建 EC2 AMI。用户的微服务通过测试后,能够配置 CI 服务器调用 Bakery,把服务打包为 AMI。使用 Bakery 这样的 SaaS 工具意味着你不需要浪费宝贵的时间来设置创建 AMI 的基础设施。

每台虚拟机一个服务实例的优点:

  1. 每个服务实例运行互相隔离,有固定的 CPU 和内存,不会占用别的服务的资源。
  2. 能够充分利用成熟的云服务平台。AWS 这样的云平台提供了负载均衡和自动扩展这样实用的功能。
  3. 封装了服务实现的技术细节。一旦服务被打包成虚拟镜像,就变成了黑盒,虚拟机镜像的管理 API 就成了部署该服务的 API。部署变得更简单可靠。

不足:

  1. 资源利用率低。每个服务实例完全占有包括操作系统在内的整个虚拟机。此外,在公有 IaaS 中,固定大小的虚拟机资源没有被充分利用。
  2. 公有 IaaS 通常依据虚拟机数量收费,不考虑其忙碌还是空闲。AWS 这类的 IaaS 提供了自动扩展,但是很难针快速响应;因而很容易过度调配虚拟机,增加部署花费。
  3. 部署新的服务通常很缓慢。虚拟机镜像由于其大小的问题,构建过程会比较慢,而且操作系统启动也要花费一定时间。然而,因为还有 Boxfuse 这样轻量级的虚拟机存在,这一问题也并非普遍。
  4. 用户或组织中的其他人要负责大量无差别的沉重的工作。除非使用 Boxfuse 这样的工具来解决构建和管理虚拟机镜像这些复杂的事情,否则这种必要且耗时的工作会占用你处理核心业务的时间。

每台容器一个服务实例

使用每台容器部署一个服务实例时,每个服务实例运行在自有容器中。容器是操作系统层面的虚拟化机制,一个容器由运行在沙盒中的一个或多个进程组成。从进程的角度看,它们有着自己的端口命名空间和根文件系统。用户能够限制容器的内存和 CPU 资源,有些容器还能限制 I/O 速率。容器技术的代表包括 Docker 和 Solaris Zone。下图展示了这种模式的架构:

使用这种模式时,用户将服务打包为容器镜像。一个容器镜像就是运行服务所需的应用和库组成的文件系统镜像。一些容器镜像还包括完整的 Linux 根文件系统。以部署 Java 服务为例,构建的容器镜像包括 Java 运行时或者Apache Tomcat 服务器以及编译好的 Java 应用。

一旦将服务打包为容器镜像,就可以启动一到多个容器了。通常一台物理机或虚拟主机上会运行多个容器,可以使用 Kubernetes 或 Marathon 这样的集群管理工具来管理容器。集群管理工具把主机看做资源池,根据每个容器需要的资源和每个主机上可用的资源来调度容器。

每台容器一个服务实例的优点类似虚拟机具有的优势:

  1. 服务实例之间完全隔离,也能容易的监控每一台容器的资源消耗。
  2. 与虚拟机类似,容器能够封装实现服务的技术细节。容器管理 API 也可用作管理服务的 API。
  3. 不同于虚拟机,容器技术更为轻量,容器镜像构建速度也更快。比如在笔记本电脑上,只用短短五秒就能把 Spring Boot 应用打包为 Docker 镜像。由于没有冗长的操作系统启动过程,容器启动也非常迅速。容器启动,服务就会运行。

不足:

  1. 虽然容器技术正迅速走向成熟,然而相对虚拟机架构来说还略显青涩。由于容器之间共享同一主机的操作系统内核,因而也没有虚拟机那么安全。
  2. 管理容器镜像也是一项繁重的工作。除非使用 Google Container Engine 或 Amazon EC2 这些容器解决方案,否则需要同时管理容器基础设施和虚拟机基础设施。
  3. 容器通常部署在按每台虚拟机定价的基础设施上,为了处理负载高峰,可能会过度配置虚拟机,从而增加额外的成本。

有趣的是,容器和虚拟机之间的区别变的模糊起来。如前文所述,Boxfuse 能够快速构建和启动虚拟机,Clear Container 项目则致力于创建轻量级的虚拟机镜像,unikernel 技术也引起了大家的注意。Docker 近期(注:2016 年 1 月 21 日)收购了 Unikernel Systems。

Serverless部署

AWS Lambda 就是 serverless 部署技术的范例。它支持 Java、Node.js 和 Python 服务。为了部署一个微服务,你需要把服务打包为 ZIP 文件并上传到 AWS Lambda,还要提供元数据,指定处理请求的函数名称。AWS Lambda 自动为微服务运行足够的实例来处理请求。可以简单根据每个请求花费的时间和消耗的内存来计费。开发人员无需担心服务器、虚拟机或容器的各个方面。

Lambda 函数是一个无状态的服务,通过调用 AWS 服务处理请求。例如,一个 Lambda 函数在一张图片被上传到 S3 时候调用,他能在 DynamoDB 表中插入一条记录,并向 Kinesis stream 发送一条消息来触发图片的处理。一个 Lambda 函数也可以调用第三方 web 服务。
有以下四种方法来调用 Lambda 函数:

  • 直接调用,直接使用 web 服务请求
  • 自动调用,自动响应由 S3、DynamoDB、Knesis、或 Simple Email Service 等 AWS 服务生成的事件
  • 自动调用,自动通过 AWS API 网关处理来自应用客户端的 HTTP 请求
  • 定期调用,通过类似 Cron 的定时任务实现

可以看出,AWS Lambda 是部署微服务的一个便捷的方式。基于请求的定价方式意味着用户只需要为服务实际运行的业务付费。此外,用户无需考虑 IT 基础设施的问题,从而能够专注于应用的开发。

然而,AWS Lambda 也有一些局限性。它并不适合被用来部署长期运行的服务,比如消费来自第三方消息的服务。请求需要在 300 秒内完成,由于 AWS Lambda 理论上能够针对每个请求运行单独的实例,因此服务必须保持无状态。此外,它还必须用一种支持的编程语言来编写。服务也需要快速启动,否则将会超时或停止。

总结

部署一个微服务应用充满挑战。应用由几十个甚至上百个用不同的语言和框架实现的服务所组成,每个服务都是一个拥有独立部署、资源、扩展和监控需求的微应用。微服务部署的模式有多种,包括单虚拟机单服务实例和单容器单服务实例。另一个有趣的微服务部署方法则是 AWS Lambda,一个 serverless 的方式。

Chris Richardson微服务翻译:微服务部署的更多相关文章

  1. Chris Richardson微服务翻译:重构单体服务为微服务

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服务部署 ...

  2. Chris Richardson微服务翻译:微服务之事件驱动的数据管理

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理(本文) 微服 ...

  3. Chris Richardson微服务翻译:微服务架构中的服务发现

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现(本文) 微服务之事件驱动的数据管理 微服 ...

  4. Chris Richardson微服务翻译:构建微服务之微服务架构的进程通讯

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯(本文) 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...

  5. Chris Richardson微服务翻译:构建微服务之使用API网关

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关(本文) 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...

  6. Chris Richardson微服务翻译:微服务介绍

    作者简介:Chris Richardson,世界著名的软件架构师,经典著作<POJOS IN ACTION>的作者,cloudfoundry.com 的创始人 微服务目前正受到大量的关注, ...

  7. 【转】「Chris Richardson 微服务系列」微服务架构的优势与不足

    Posted on 2016年5月4日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战. 作者介绍:Chris Ric ...

  8. 【CHRIS RICHARDSON 微服务系列】微服务架构中的进程间通信-3

    编者的话 |本文来自 Nginx 官方博客,是微服务系列文章的第三篇,在第一篇文章中介绍了微服务架构模式,与单体模式进行了比较,并且讨论了使用微服务架构的优缺点.第二篇描述了采用微服务架构的应用客户端 ...

  9. 【CHRIS RICHARDSON 微服务系列】事件驱动的数据管理-5

    编者的话 |本文来自 Nginx 官方博客,是「Chris Richardson 微服务」系列的第五篇文章.第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点:第二和第三篇描述了微服务架构模 ...

随机推荐

  1. Hadoop Yarn 安装

    环境:Linux, 8G 内存.60G 硬盘 , Hadoop 2.2.0 为了构建基于Yarn体系的Spark集群.先要安装Hadoop集群,为了以后查阅方便记录了我本次安装的详细步骤. 事前准备 ...

  2. Codeforces 29D Ant on the Tree 树的遍历 dfs序

    题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径.要求遍历叶子节点时依照给定叶子节点的先后顺序訪问. 思路: 给每 ...

  3. Java快速排序算法

    快速排序算法思想: 快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一 ...

  4. mongodb 3.4 集群搭建:分片+副本集

    mongodb是最常用的nodql数据库,在数据库排名中已经上升到了前六.这篇文章介绍如何搭建高可用的mongodb(分片+副本)集群. 在搭建集群之前,需要首先了解几个概念:路由,分片.副本集.配置 ...

  5. intellij IDEA里各图标对应的文件类型

    本篇内容为大家提供的是IntelliJ IDEA 使用教程中的常见文件类型的图标介绍,IntelliJ IDEA是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一, ...

  6. redis集群配置,spring整合jedis,缓存同步

    前台的商品数据(图片等加载缓慢)查询,先从redis缓存查询数据. redis是一个nosql数据库,内存版数据库,读取速度11w/s.本身具有内存淘汰机制,是单线程服务器(分时操作系统),线程安全. ...

  7. 3.更改ssh服务远程登录的配置

  8. C# 委托与事件详解(三)

    今天我接着上面的3篇文章来讲一下,为什么我们在日常的编程活动中遇到这么多sender,EventArgs e 参数:protected void Page_Load(object sender, Ev ...

  9. 小白的Python之路 if __name__ == '__main__' 解析

    if __name__ == '__main__' 参考文献: http://www.cnblogs.com/xuxm2007/archive/2010/08/04/1792463.html http ...

  10. 用VS2015写一个简单的ASP.net网站

    第一步:打开VS2015,然后新建一个空的解决方案,其中解决方案的名称WebSiteTest可类似认为是本次网站的名称,系统会以该名称(WebSiteTest)生成一个文件夹,在WebSites文件夹 ...