《微服务架构设计模式》第十二章 部署微服务应用

内容总结自《微服务架构设计模式》

部署微服务应用

    • 一、部署模式分类
    • 二、编程语言特定的发布包格式
      • 1、概述
      • 2、利弊
    • 三、将服务部署为虚拟机
      • 1、概览
      • 2、利弊
    • 四、将服务部署为容器
      • 1、概述
      • 2、利弊
      • 3、K8S部署
    • 五、Serverless部署
      • 1、概述
      • 2、利弊
      • 3、示例
    • 六、总结




一、部署模式分类

在20世纪90年代末开始开发企业Java应用程序以来,部署的流程和架构都发生了根本性的变化。早先开发人员将代码扔给运维人员进行手动部署的历史已经一去不复返了,生产环境的部署过程已经变得高度自动化。之前由物理机组成的生产环境已被越来越多轻量级和短生命周期的计算基础设施所取代。

《微服务架构设计模式》第十二章 部署微服务应用_第1张图片

分别为以下四类:

  1. 使用编程语言特定的发布包格式部署服务,例如Java JAR或WAR文件。我并不推荐这种做法,之所以介绍这个选项,是因为这个部署方法有各种显著的缺点,会促使你思考和选择其他更为合理和现代化的部署技术。
  2. 将服务部署为虚拟机,把服务打包为虚拟机镜像,这个镜像封装了服务的技术栈,这样可以简化部署。
  3. 将服务部署为容器,这些容器比虚拟机更轻量级。我将展示如何使用流行的 Docker编排框架Kubernetes部署FTGO应用程序的Restaurant Serviceo
  4. 使用Serverless部署模式部署服务,这比容器更加现代化。我们将研究如何使用AWSLambda(一种流行的Serverless平台)部署Restaurant service。




二、编程语言特定的发布包格式

1、概述

要在计算机上部署Restaurant Service,首先要安装必要的运行时环境,在本例中为JDK。如果它是WAR文件,则还需要安装Web容器,例如Apache Tomcat。配置完计算机后,将程序发布包复制到计算机并启动该服务。每个服务实例都作为JVM进程运行。

理想情况下,你已经设置好部署流水线,它会自动将服务部署到生产环境。部署流水线构建可执行的JAR文件或WAR文件。然后,它调用生产环境的服务管理接口来部署新版本。

《微服务架构设计模式》第十二章 部署微服务应用_第2张图片

在传统的昂贵、重量级应用程序服务器(如 WebLogic和 WebSphere)上部署应用程序时,通常会使用此方法。你还可以将服务打包为OSGI包,并在每个OSGI容器中运行多个服务实例。
将服务作为特定于语言的发布包进行部署的模式有好处也有弊端。我们先来看看好处。


2、利弊

优点:

  • 快速部署。
  • 高效的资源利用,尤其是在同一台机器上或同一进程中运行多个实例时。

缺点:

  • 缺乏对技术栈的封装。
  • 无法约束服务实例消耗的资源。
  • 在同一台计算机上运行多个服务实例时缺少隔离。很难自动判定放置服务实例的位置。




三、将服务部署为虚拟机

将做为虚拟机镜像打包的服务器部署到生产环境中。每个服务实例都是一个虚拟机。

1、概览

假设你负责部署Restaurant Service,只不过这次需要在AWS EC2上部署。一种选择是创建和配置EC2实例并将可执行文件或WAR文件复制到其上。虽然你可以从使用云主机中获得一些好处,但这种方法会遇到上一个模式中描述的相同问题。更好、更现代的方法是将服务打包为亚马逊机器镜像(AMI)。每个服务实例都是从该AMI创建的EC2实例。EC2实例通常由AWS Auto Scaling Group(ASG)负责管理,ASG尝试确保所需数量的实例始终正常运行。

《微服务架构设计模式》第十二章 部署微服务应用_第3张图片

2、利弊

优点:

  • 虚拟机镜像封装了技术栈。
  • 隔离的服务实例。
  • 使用成熟的云计算基础设施。

弊端:

  • 资源利用效率较低。
  • 部署速度相对较慢。
  • 系统管理的额外开销。




四、将服务部署为容器

将做为容器镜像打包的服务部署到生产环境中。每一个服务实例都是一个容器。

1、概述

容器是一种更现代、更轻量级的部署机制,是一种操作系统级的虚拟化机制。容器通常包含一个或多个在沙箱中运行的进程,这个沙箱将它们与其他容器隔离。例如,运行Java服务的容器通常由JVM进程组成。

从在容器中运行的进程的角度来看,它就好像在自己的机器上运行一样。它通常有自己的IP地址,可以消除端口冲突。例如,所有Java进程都可以侦听端口8080。每个容器也有自己的根文件系统。容器运行时使用操作系统机制将容器彼此隔离。容器运行时最流行的示例是

《微服务架构设计模式》第十二章 部署微服务应用_第4张图片

创建容器时,可以指定它的CPU和内存资源,以及依赖于容器实现的IO资源等。容器运行时强制执行这些限制,并防止容器占用其机器的资源。使用Docker编排框架(如Kubernetes)时,指定容器的资源尤为重要。这是因为编排框架使用容器请求的资源来选择运行容器的底层机器,从而确保机器不会过载。

《微服务架构设计模式》第十二章 部署微服务应用_第5张图片

2、利弊

优点:

  • 封装技术栈,可以用容器的API实现对服务的管理。
  • 服务实例是隔离的。
  • 服务实例的资源受到限制。

但与虚拟机不同,容器是一种轻量级技术。容器镜像通常可以很快构建。例如,在我的笔记本电脑上,只需五秒就可以将Spring Boot应用程序打包为容器镜像。通过网络传输容器镜像(例如进出容器镜像仓库)也相对较快,主要是因为仅传输所需要的镜像层的子集。容器也可以很快启动,因为没有冗长的操作系统启动过程。当容器启动时,所运行的就是服务。


弊端:

需要承担大量的容器镜像管理工作。你必须负责给操作系统和运行时打补丁。此外,除非使用托管容器解决方案(如Google Container Engine或AWSECS),否则你必须管理容器基础设施以及容器运行可能需要的虚拟机基础设施。


3、K8S部署

Kubernetes是一个Docker编排框架。Docker编排框架将运行Docker的一组计算机视为资源池。你只需要告诉Docker编排框架运行你的服务的N个实例,它就会自动把其余的事情搞定

Docker编排框架(如 Kubernetes)有三个主要功能:

  1. 资源管理:将一组计算机视为由CPU、内存和存储卷构成的资源池,将计算机集群视为一台计算机。
  2. 调度:选择要运行容器的机器。默认情况下,调度考虑容器的资源需求和每个节点的可用资源。
  3. 服务管理:实现命名和版本化服务的概念,这个概念可以直接映射到微服务架构中的具体服务。编排框架确保始终运行所需数量的正常实例。它实现请求的负载均衡。编排框架也可以执行服务的滚动升级,并允许你回滚到旧版本。
《微服务架构设计模式》第十二章 部署微服务应用_第6张图片

Kubernetes 的普通节点称为“工作节点”,它会运行一个或多个Pod。Pod是 Kubernetes的部署单元,由一组容器组成。

主节点运行多个组件,包括以下内容:

  1. API服务器:用于部署和管理服务的REST API,例如,可被kubectl命令行使用。
  2. Etcd:存储集群数据键值的NoSQL数据库。
  3. 调度器:选择要运行Pod 的节点。
  4. 控制器管理器:运行控制器,确保集群状态与预期状态匹配。例如,一种称为复制( replication)控制器的控制器通过启动和终止实例来确保运行所需数量的服务实例。
《微服务架构设计模式》第十二章 部署微服务应用_第7张图片

Kubernetes定义了许多类型的对象。从开发人员的角度来看,最重要的对象如下:

  1. Pod:Pod是 Kubernetes 的基本部署单元。它由一个或多个共享IP地址和存储卷的容器组成。服务实例的pod通常由单个容器组成,例如运行JVM的容器。但在某些情况下,Pod包含一个或多个实现支持功能的边车( sidecar)容器。例如,Nginx服务器可以有一个边车容器,定期执行git pull 以下载最新版本的网站。Pod的生命周期很短,因为Pod的容器或它运行的节点可能会崩溃。
  2. Deploymen:Pod的声明性规范。Deployment是一个控制器,可确保始终运行所需数量的Pod实例(服务实例)。它通过滚动升级和回滚来支持版本控制。微服务架构中的每个服务都是Kubernetes 的一个De-ployment。
  3. Service:向应用程序服务的客户端提供的一个静态/稳定的网络地址。它是基础设施提供的服务发现的一种形式,如第3章所述。每个Service具有一个IP地址和一个可解析为该IP地址的 DNS名称,并跨一个或多个Pod对TCP和UDP流量进行负载均衡处理。IP地址和 DNS名称只能在Kubernetes内部访问。稍后,我将介绍如何配置可从集群外部访问的服务。
  4. ConfigMap:名称与值对的命名集合,用于定义一个或多个应用程序服务的外部化配置(有关外部化配置的概述,请参阅第11章)。Pod容器的定义可以引用ConfigMap来定义容器的环境变量。它还可以使用ConfigMap在容器内创建配置文件。可以使用Secret来存储敏感信息(如密码),它也是ConfigMap的一种形式。




五、Serverless部署

使用公共云提供的Serverless部署机制部署服务。

1、概述

特定于编程语言的发布包,服务作为虚拟机和服务作为容器,这几种部署模式都是完全不同的,但它们具有一些共同的特征。首先,对于所有三种模式,你必须预先准备一些计算资源,例如物理机、虚拟机或容器。某些部署平台实现自动扩展,可根据负载动态调整虚拟机或容器的数量。但是,即使它们处于闲置状态,你也总是需要为某些虚拟机或容器付费。

另一个共同特征是你必须负责系统管理。不论运行什么类型的计算资源,你必须承担为操作系统和软件打补丁的工作。在物理机器的情况下,这还包括机架和网络的管理。你还要负责管理语言运行时。这是Amazon称为“无差别的重举”(Undifferentiated heavy lifing)的一个例子。从计算的早期开始,系统管理就是你需要做的事情之一。事实证明,有一个应对此问题的解决方案:Serverless 。



使用AWS Lambda部署Serverless。AWS Lambda支持Java、Node.js、C#、GoLang和 Python 。Lambda函数是无状态服务。它通常通过调用AWS服务来处理请求。例如,用户上传照片到S3存储桶时,触发的Lambda函数可以将照片的元数据插入到DynamoDB 的IMAGES表中,并向Kinesis发布消息,以触发图像处理(例如制作缩略图等)。Lambda函数还可以调用第三方Web服务。

要部署服务,需将应用程序打包为ZIP文件或JAR文件,将其上载到AWS Lambda,并指定响应请求(也称为事件)的函数的名称。AWS Lambda自动运行你的充足的微服务实例来处理传入的请求。根据所花费的时间和消耗的内存,你需要为每个请求付费。当然,细节是魔鬼,稍后你会发现AWS Lambda也有不少局限性。但是,作为开发人员或组织中的任何人都不需要担心服务器、虚拟机或容器的任何方面,这一理念非常强大。


调用Lambda函数的四种方式:

  1. HTTP请求。
  2. AWS 服务生成的事件。
  3. 定时调用。
  4. 直接使用API 调用。

2、利弊

好处:

  • 有许多AWS服务可供集成:编写消费由AWS服务生成的事件(如DynamoDB和Kinesis)并通过AWS API Gateway处理HTTP请求的Lambda函数非常简单。
  • 消除许多系统管理任务:你不需要再负责底层的系统管理。不必为操作系统或运行时打补丁。因此,你可以专注于开发应用程序。
    弹性:AWS Lambda运行应用程序所需的多个实例,以处理负载。你没有预测所需容量的挑战,也不会存在未充分配置或过度配置虚拟机或容器的风险。
  • 基于使用情况的定价:与典型的laaS云(虚拟机或容器按分钟或小时收费,即使处于空闲状态)不同,AWS Lambda仅向你收取处理每个请求时所消耗的资源的费用。

弊端:

  • 长尾延迟:由于AWS Lambda动态运行你的代码,因为AWS需要花费时间来配置应用程序实例和启动应用程序,因此某些请求具有高延迟。这在运行基于Java的服务时尤其具有挑战性,因为它们通常需要至少几秒钟才能启动。例如,下一节中描述的示例Lambda函数需要一段时间才能启动。因此,AWS Lambda可能不适合对延迟敏感的服务。
  • 基于有限事件与请求的编程模型:AWS Lambda不用于部署长时间运行的服务,例如使用来自第三方消息代理的消息服务。

由于这些缺点和限制,AWS Lambda并不适合所有服务。但在选择部署模式时,我建议首先评估Serverless部署是否支持你的服务要求,然后再考虑替代方案。


3、示例

区别于传统的Spring MVC风格,它将一组相同功能的服务,合并在一起,构建出一个lambda.zip然后向外暴露

使用AWS Lambda部署Restaurant Service。它是一个具有REST API的服务,用于创建和管理餐馆。例如,它与Apache Kafka没有长时间的连接,因此它非常适合使用AWS Lambda。

该服务由几个Lambda函数组成,每个REST端点一个。AWS APl Gateway负责将HTTP请求路由到Lambda函数。

每个Lambda函数都有一个请求处理程序类。ftgo-create-restaurant Lambda函数调用createRestaurantRequestHandler类,ftgo-find-restaurant Lambda函数调用FindRestaurantRequestHandler。因为这些请求处理程序类实现了同一个服务的功能,所以它们被打包在同一个ZIP文件restaurant-service-aws-lambda.zip中

《微服务架构设计模式》第十二章 部署微服务应用_第8张图片




六、总结

  1. 你应该选择支持服务要求的最轻量级部署模式。按以下顺序评估选项:Serverless ,容器、虚拟机和特定于语言的程序包。
  2. Serverless部署不适合每项服务,因为长尾延迟和使用基于事件/请求的编程模型的要求。但是,当适合部署应用时,Serverless部署是一个非常有竞争力的选择,因为它消除了管理操作系统和运行时的必要,并提供自动弹性配置和基于请求的定价。
  3. Docker容器是一种轻量级操作系统级虚拟化技术,比 Serverless部署更灵活,并且具有更可预测的延迟。最好使用Docker编排框架,例如Kubernetes,它管理机器集群上的容器。使用容器的缺点是你必须管理操作系统和运行时,并且很可能也需要管理Docker 编排框架及其底层运行的虚拟机。
  4. 将你的服务部署为虚拟机。一方面,虚拟机是重量级的部署选项,因此部署速度较慢,并且很可能比第二个选项使用更多资源。另一方面,AmazonEC2等现代云是高度自动化的,并提供了丰富的功能。因此,使用虚拟机部署小型简单应用程序有时可能比设置Docker编排框架更容易。
  5. 除非你只有少量服务,否则通常最好避免将服务部署为特定于编程语言的发布包。例如,当你开始使用微服务时,你可能会使用与单体应用程序相同的机制来部署服务,而且很可能是此选项。只有开发了一些服务后,你才应该考虑建立一个复杂的部署基础设施,如 Kubernetes。
  6. 使用服务网格(一种网络层,调节进出服务的所有网络流量)的众多好处之一是,它使你能够在生产环境中部署服务,对其进行测试,然后才将生产流量路由到更新后的服务。将部署与发布隔离可以提高新版本服务的可靠性。

你可能感兴趣的:(读书笔记,微服务,架构,云原生)