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. C++技术问题总结-第8篇 STL内存池是怎么实现的

    STL内存池机制,使用双层级配置器.第一级採用malloc.free,第二级视情况採用不同策略. 这样的机制从heap中要空间,能够解决内存碎片问题. 1.内存申请流程图     简要流程图例如以下. ...

  2. F02 金融学第二定律 资金的积聚

    美国南北战争,北方取胜的关键在于发行了债券,从而积聚了资金,提升了北方军队战斗力. 纽约的逆袭,得益于伊利运河的修建,而伊利运河的建造需要的资金,全靠债券发行积聚的资金. 聚积起来的资金,往往决定了重 ...

  3. node.js之路由,中间件,ge请求和post请求的参数

    一.路由 1.什么是路由 服务器需要根据不同的URL或请求来执行不一样的操作,我们可以通过路由来实现这个步骤 2.实现路由的方法 2.1.get请求访问网址时,做什么事 1 app.get(" ...

  4. MPSOC之6——开发流程linux编译

    0.顶层Makefile增加交叉编译器 顶层makefile: ARCH ?= $(SUBARCH) CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%&q ...

  5. Java Web Session设置

    一.前言 在做 java web项目时,我们很多时候都要用到 Session,那么我就简单的写一下 Session 的写法. 二.代码实现 Servlet Session 的设置 package co ...

  6. 苹果审核返回崩溃日志 iOS .crash文件处理 symbolicatecrash.  困扰我多年的牛皮癣根治了 看到这篇文章拿过来用下

    AppStore审核被拒,返回crashLog.txt文件,可是打开后都是十六进制的地址,我们可以使用Xcode自带的 symbolicatecrash 解析得到我们需要的详细崩溃信息crashLog ...

  7. NOIP2017day1游记

    NOIP 2017总结 Day1 Day1T1 第一眼看到瞬间慌掉,woc这玩意啥! 然后懵逼了两分钟 好的 我相信他是NOIP第一题 那我就打个表吧 然后花五分钟打了个暴力 玩了几组数据 哇!好像有 ...

  8. A星寻路算法(A* Search Algorithm)

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  9. 单源最短路径(1):Dijkstra 算法

    一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...

  10. iOS通用链接(Universal Links)突然点击无效的解决方案

    接上文<微信中通过页面(H5)直接打开本地app的解决方案>已经把iOS搞定并且已经正常能跑了,突然就再也用不了了... 问题描述 测试告诉我,如果从微信打开App之后,点击App右上角的 ...