微服务微服务架构下你不得不知的3种部署策略
Posted 逆流°只是风景-bjhxcc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务微服务架构下你不得不知的3种部署策略相关的知识,希望对你有一定的参考价值。
文章目录
前言
不知道大家有了解过你们公司的软件产品是如何部署的么?采用的什么部署策略?其实在软件开发生命周期中,部署是非常关键的一环,你需要考虑多方面的因素,如何保证你部署对用户无感知?如何把影响范围控制到最小?如何出现问题快速的实现回滚?
现在的大多数应用程序都是云原生、微服务的方式。例如,淘宝,它就是由许许多多的子服务组成的。服务数量越多,意味着出现问题的可能性更大。那么部署的策略极为关键,高效部署的期望达成的目标有如下几点:
- 零停机
- 快速部署
- 客户对新版本的快速反馈
- 出现问题容易回滚
那么本文和大家分享3种微服务部署比较常见的3种部署策略,滚动部署、蓝绿部署和金丝雀部署。
滚动部署
上图显示了部署模式:旧版本以蓝色显示,新版本在集群中的每个服务器上以绿色显示。
在滚动部署中,应用程序的新版本逐渐替换旧版本。实际部署发生在一段时间内。在此期间,新旧版本将共存,不会影响功能使用和用户体验。此过程可以更轻松地回滚与旧组件不兼容的任何新组件。
优点:
- 减少停机时间:滚动部署允许以增量方式部署更新,从而减少应用程序的整体停机时间。这是因为应用程序在部署过程中对用户仍然可用。
- 更好的风险管理:通过逐步更新一部分服务器,滚动部署可以实现更好的风险管理。如果在更新期间出现任何问题,可以及早检测到并在将更新推广到所有服务器之前缓解这些问题。
- 提高可靠性:滚动部署可以通过降低广泛故障的风险来帮助提高应用程序的可靠性。由于更新是针对一部分服务器推出的,因此可以在问题影响整个系统之前检测并解决问题。
- 简化回滚:如果在部署过程中出现问题,滚动部署可以更轻松地回滚更新。由于更新是增量部署的,回滚到以前的版本只需要回滚已更新的服务器子集。
缺点:
-
复杂性: 滚动部署的设置和管理可能很复杂,尤其是对于具有许多服务器的大型应用程序。它需要仔细规划和协调,以确保以正确的顺序推出更新,并及时更新所有服务器。
-
更长的部署时间:滚动部署可能需要比其他部署策略更长的时间才能完成,因为更新是逐步推出的。这可能会导致更长的部署时间,这可能不适合对正常运行时间有严格要求的应用程序。
-
增加资源使用:滚动部署可能需要更多资源,因为更新会在部署到所有服务器之前先部署到一部分服务器。这可能会导致资源使用量增加和成本增加。
-
兼容性问题的风险:滚动部署会增加在不同服务器上运行的不同版本的应用程序之间出现兼容性问题的风险。这可以通过在推出更新之前彻底测试应用程序情况的兼容性来缓解。
蓝绿部署
在蓝绿部署中,有两个相同的环境(或资源集)用于部署和测试新版本的软件。一个环境被认为是“蓝色”环境,而另一个被认为是“绿色”环境。
当前版本的软件在蓝色环境中运行,新版本在绿色环境中进行部署和测试。一旦新版本在绿色环境中被认为稳定且功能齐全,流量可以从蓝色环境切换到绿色环境,使新版本成为当前版本。
这种方法的优点是它最大限度地降低了部署新版本软件可能导致的停机或错误的风险。如果在部署或测试过程中出现问题,可以快速切换回蓝色环境,而不会对用户造成任何干扰。这使得蓝绿部署成为需要高可用性和正常运行时间的公司的热门选择。
优点:
- 停机时间最短:蓝绿部署允许零停机更新,因为新版本的应用程序在切换到蓝色环境之前部署到绿色环境,这可以导致停机时间最少。
- 降低风险:由于新版本的应用部署到绿色环境,部署过程中出现的任何问题都与绿色环境隔离,降低了大范围故障的风险。
- 简化回滚:如果部署过程中出现问题,很容易回滚到以前的版本,因为蓝色环境仍然运行以前的版本。
- 提高可靠性:由于蓝色和绿色环境相同,蓝绿部署可以帮助确保应用程序可靠和稳定。
缺点:
- 复杂性增加: 蓝绿部署的设置和管理可能很复杂,尤其是对于具有许多组件的大型应用程序。它需要仔细规划和协调,以确保正确设置绿色环境,并确保从蓝色环境到绿色环境的无缝切换。
- 增加资源使用:运行两个相同的环境可能需要更多资源,这会导致成本增加。
- 更长的部署时间: 蓝绿可能需要更长的部署时间,因为新版本的应用程序需要先部署到绿色环境,然后才能切换到蓝色环境。
- 配置漂移的风险:由于两个相同的环境同时运行,如果更改一个环境而不更改另一个环境,则存在配置漂移的风险。通过使用自动化和配置管理工具来确保环境保持相同,可以减轻这种风险。
金丝雀部署
金丝雀部署就像蓝绿部署,只是它风险更小。你无需一步从蓝色切换到绿色,而是使用一种分阶段的方法。
通过金丝雀部署,您可以在生产基础设施的一小部分中部署新的应用程序代码。一旦应用程序被签署发布,只有少数用户被路由到新版本上,这样可以最大限度地减少任何影响。
在没有错误报告的情况下,新版本可以逐步推广到基础架构的其余部分。
优点:
- 降低风险: 金丝雀部署可以降低风险,因为新版本的应用程序被推出到一小部分用户或服务器,允许在问题影响更广泛的受众之前检测和缓解任何问题。
- 早期反馈: 金丝雀部署提供一小部分用户对新版本应用程序的早期反馈,这有助于在向更广泛的受众推出之前识别问题并改进应用程序。
- 提高可靠性:金丝雀部署有助于提高应用程序的可靠性,确保在问题影响更广泛的受众之前及早发现并解决任何问题。
- 受控推出:金丝雀部署允许受控推出新版本的应用程序,这有助于确保推出顺利并且不会导致任何意外问题。
缺点:
- 复杂性增加:金丝雀部署的设置和管理可能很复杂,尤其是对于具有许多组件的大型应用程序。它需要仔细规划和协调,以确保正确设置金丝雀版本并且无缝推出。
- 增加资源使用:运行两个版本的应用程序可能需要更多资源,这会导致成本增加。
- 更长的部署时间: 金丝雀部署可能需要更长的时间才能部署,因为新版本的应用程序需要在向更广泛的受众推出之前进行测试和监控。
- 金丝雀超载的风险:如果金丝雀子集太小或不能代表更广泛的受众,它可能会因流量或使用而超载,这可能会扭曲结果并影响应用程序的整体性能。
总结
总而言之,没有适用于所有情况的单一“最佳”部署策略,因为不同的方法可能更适合不同的场景、团队和应用程序。比如我们公司就是采用的停机部署,虽然提起来有点low,但是我们是TO B业务,这种方式成本最低,怎么简单怎么来。
总的来说,最佳部署策略将取决于多种因素,包括应用程序的规模和复杂性、团队的规模和专业知识、所需的风险和停机时间级别、资源和基础设施的可用性以及其他特定考虑因素给相关组织和应用程序。
重要的是要不断评估和试验不同的部署策略,以找到最适合你的团队和你的应用程序的策略,并且需要随着需求的变化,去不不断调整迭代你的部署策略,这才是正道。
微服务实战:选择微服务部署策略
【编者的话】这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺点。随后的文章讨论了微服务不同方面:使用API网关,进程间通讯,服务发现和事件驱动数据管理。这篇文章,我们将讨论部署微服务的策略。
本系列文章:
- 微服务实战(一):微服务架构的优势与不足
- 微服务实战(二):使用API Gateway
- 微服务实战(三):深入微服务架构的进程间通信
- 微服务实战(四):服务发现的可行方案以及实践案例
- 微服务实践(五):微服务的事件驱动数据管理
动机
部署一个单体式应用意味运行大型应用的多个副本,典型的提供若干个(N)服务器(物理或者虚拟),运行若干个(M)个应用实例。部署单体式应用不会很直接,但是肯定比部署微服务应用简单些。
一个微服务应用由上百个服务构成,服务可以采用不同语言和框架分别写就。每个服务都是一个单一应用,可以有自己的部署、资源、扩展和监控需求。例如,可以根据服务需求运行若干个服务实例,除此之外,每个实例必须有自己的CPU,内存和I/O资源。尽管很复杂,但是更挑战的是服务部署必须快速、可靠和性价比高。
有一些微服务部署的模式,先讨论一下每个主机多服务实例的模式。
单主机多服务实例模式
部署微服务的一种方法就是单主机多服务实例模式,使用这种模式,需要提供若干台物理或者虚拟机,每台机器上运行多个服务实例。很多情况下,这是传统的应用部署方法。每个服务实例运行一个或者多个主机的well-known端口,主机可以看做宠物。
下图展示的是这种架构:
这种模式有一些参数,一个参数代表每个服务实例由多少进程构成。例如,需要在Apache Tomcat Server上部署一个Java服务实例作为web应用。一个Node.js服务实例可能有一个父进程和若干个子进程构成。
另外一个参数定义同一进程组内有多少服务实例运行。例如,可以在同一个Apache Tomcat Server上运行多个Java web应用,或者在同一个OSGI容器内运行多个OSGI捆绑实例。
单主机多服务实例模式也是优缺点并存。主要优点在于资源利用有效性。多服务实例共享服务器和操作系统,如果进程组运行多个服务实例效率会更高,例如,多个web应用共享同一个Apache Tomcat Server和JVM。
另一个优点在于部署服务实例很快。只需将服务拷贝到主机并启动它。如果服务用Java写的,只需要拷贝JAR或者WAR文件即可。对于其它语言,例如Node.js或者Ruby,需要拷贝源码。也就是说网络负载很低。
因为没有太多负载,启动服务很快。如果服务是自包含的进程,只需要启动就可以;否则,如果是运行在容器进程组中的某个服务实例,则需要动态部署进容器中,或者重启容器。
除了上述优点外,单主机多服务实例也有缺陷。其中一个主要缺点是服务实例间很少或者没有隔离,除非每个服务实例是独立进程。如果想精确监控每个服务实例资源使用,就不能限制每个实例资源使用。因此有可能造成某个糟糕的服务实例占用了主机的所有内存或者CPU。
同一进程内多服务实例没有隔离。所有实例有可能,例如,共享同一个JVM heap。某个糟糕服务实例很容易攻击同一进程中其它服务;更甚至于,有可能无法监控每个服务实例使用的资源情况。
另一个严重问题在于运维团队必须知道如何部署的详细步骤。服务可以用不同语言和框架写成,因此开发团队肯定有很多需要跟运维团队沟通事项。其中复杂性增加了部署过程中出错的可能性。
可以看到,尽管熟悉,但是单主机多服务实例有很多严重缺陷。下面看看是否有其他部署微服务方式能够避免这些问题。
单主机单服务实例模式
另外一种部署微服务方式是单主机单实例模式。当使用这种模式,每个主机上服务实例都是各自独立的。有两种不同实现模式:单虚拟机单实例和单容器单实例。
单虚拟机单实例模式
但是用单虚拟机单实例模式,一般将服务打包成虚拟机映像(image),例如一个Amazon EC2 AMI。每个服务实例是一个使用此映像启动的VM(例如,EC2实例)。下图展示了此架构:
Netfix采用这种架构部署video streaming service。Netfix使用Aminator将每个服务打包成一个EC2 AMI。每个运行服务实例就是一个EC2实例。
有很多工具可以用来搭建自己的VMs。可以配置持续集成(CI)服务(例如,Jenkins)避免Aminator将服务打包成EC2
AMI。packer.io是自动虚机映像创建的另外一种选择。跟Aminator不同,它支持一系列虚拟化技术,例如EC2,DigitalOcean,VirtualBox和VMware。?
Boxfuse公司有一个创新方法创建虚机映像,克服了如下缺陷。Boxfuse将java应用打包成最小虚机映像,它们创建迅速,启动很快,因为对外暴露服务接口少而更加安全。
CloudNative公司有一个用于创建EC2
AMI的SaaS应用,Bakery。用户微服务架构通过测试后,可以配置自己的CI服务器激活Bakery。Bakery将服务打包成AMI。使用如Bakery的SaaS应用意味着用户不需要浪费时间在设置自己的AMI创建架构。
每虚拟机服务实例模式有许多优势,主要的VM优势在于每个服务实例都是完全独立运行的,都有各自独立的CPU和内存而不会被其它服务占用。
另外一个好处在于用户可以使用成熟云架构,例如AWS提供的,云服务都提供如负载均衡和扩展性等有用功能。
还有一个好处在于服务实施技术被自包含了。一旦服务被打包成VM就成为一个黑盒子。VM的管理API成为部署服务的API,部署成为一个非常简单和可靠的事情。
单虚拟机单实例模式也有缺点。一个缺点就是资源利用效率不高。每个服务实例战友整个虚机的资源,包括操作系统。而且,在一个典型的公有IaaS环境,虚机资源都是标准化的,有可能未被充分利用。
而且,公有IaaS根据VM来收费,而不管虚机是否繁忙;例如AWS提供了自动扩展功能,但是对随需应用缺乏快速响应,使得用户不得不多部署虚机,从而增加了部署费用。
另外一个缺点在于部署服务新版本比较慢。虚机镜像因为大小原因创建起来比较慢,同样原因,虚机初始化也比较慢,操作系统启动也需要时间。但是这并不一直是这样,一些轻量级虚机,例如使用Boxfuse创建的虚机,就比较快。
第三个缺点是对于运维团队,它们负责许多客制化工作。除非使用如Boxfuse之类的工具,可以帮助减轻大量创建和管理虚机的工作;否则会占用大量时间从事与核心业务不太无关的工作。
那么我们来看看另外一种仍然具有虚机特性,但是比较轻量的微服务部署方法。
单容器单服务实例模式
当使用这种模式时,每个服务实例都运行在各自容器中。容器是运行在操作系统层面的虚拟化机制。一个容器包含若干运行在沙箱中的进程。从进程角度来看,他们有各自的命名空间和根文件系统;可以限制容器的内存和CPU资源。某些容器还具有I/O限制,这类容器技术包括Docker和Solaris
Zones。
下图展示了这种模式:
?使用这种模式需要将服务打包成容器映像。一个容器映像是一个运行包含服务所需库和应用的文件系统?。某些容器映像由完整的linux根文件系统组成,其它则是轻量级的。例如,为了部署Java服务,需要创建包含Java运行库的容器映像,也许还要包含Apache
Tomcat server,以及编译过的Java应用。
一旦将服务打包成容器映像,就需要启动若干容器。一般在一个物理机或者虚拟机上运行多个容器,可能需要集群管理系统,例如k8s或者Marathon,来管理容器。集群管理系统将主机作为资源池,根据每个容器对资源的需求,决定将容器调度到那个主机上。
单容器单服务实例模式也是优缺点都有。容器的优点跟虚机很相似,服务实例之间完全独立,可以很容易监控每个容器消耗的资源。跟虚机相似,容器使用隔离技术部署服务。容器管理API也可以作为管理服务的API。
然而,跟虚机不一样,容器是一个轻量级技术。容器映像创建起来很快,例如,在笔记本电脑上,将Spring Boot 应用打包成容器映像只需要5秒钟。因为不需要操作系统启动机制,容器启动也很快。当容器启动时,后台服务就启动了。
使用容器也有一些缺点。尽管容器架构发展迅速,但是还是不如虚机架构成熟。而且由于容器之间共享host OS内核因此并不像虚机那么安全。
另外,容器技术将会对管理容器映像提出许多客制化需求,除非使用如Google Container Engine或者Amazon EC2 Container Service (ECS),否则用户将同时需要管理容器架构以及虚机架构。
第三,容器经常被部署在按照虚机收费的架构上,很显然,客户也会增加部署费用来应对负载的增长。
有趣的是,容器和虚机之间的区别越来越模糊。如前所述,Boxfuse虚机启动创建都很快,Clear Container技术面向创建轻量级虚机。unikernel公司的技术也引起大家关注,Docker最近收购了Unikernel公司。
除了这些之外,server-less部署技术,避免了前述容器和VM技术的缺陷,吸引了越来越多的注意。下面我们来看看。
Serverless 部署
AWS
Lambda是serverless部署技术的例子,支持Java,Node.js和Python服务;需要将服务打包成ZIP文件上载到AWS
Lambda就可以部署。可以提供元数据,提供处理服务请求函数的名字(一个事件)。AWS
Lambda自动运行处理请求足够多的微服务,然而只根据运行时间和消耗内存量来计费。当然细节决定成败,AWS
Lambda也有限制。但是大家都不需要担心服务器,虚拟机或者容器内的任何方面绝对吸引人。
Lambda 函数 是无状态服务。一般通过激活AWS服务处理请求。例如,当映像上载到S3
bucket激活Lambda函数后,就可以在DynamoDB映像表中插入一个条目,给Kinesis流发布一条消息,触发映像处理动作。Lambda函数也可以通过第三方web服务激活。
有四种方法激活Lambda函数:
- 直接方式,使用web服务请求
- 自动方式,回应例如AWS S3,DynamoDB,Kinesis或者Simple Email Service等产生的事件
- 自动方式,通过AWS API网关来处理应用客户端发出的HTTP请求?
- 定时方式,通过cron响应?--很像定时器方式
可以看出,AWS Lambda是一种很方便部署微服务的方式。基于请求计费方式意味着用户只需要承担处理自己业务那部分的负载;另外,因为不需要了解基础架构,用户只需要开发自己的应用。
然而还是有不少限制。不需要用来部署长期服务,例如用来消费从第三方代理转发来的消息,请求必须在300秒内完成,服务必须是无状态,因为理论上AWS Lambda会为每个请求生成一个独立的实例;必须用某种支持的语言完成,服务必须启动很快,否则,会因为超时被停止。
总结
部署微服务应用也是一种挑战。用各种语言和框架写成的服务成百上千。每种服务都是一种迷你应用,有自己独特的部署、资源、扩充和监控需求。有若干种微服务部署模式,包括单虚机单实例以及单容器单实例。另外可选模式还有AWS Lambda,一种serverless方法。
在下一篇也是本系列最后一篇?博客中,我们来讨论如何将一个单体式应用迁移到微服务架构。
原文链接:Choosing a Microservices Deployment Strategy(翻译:杨峰)
以上是关于微服务微服务架构下你不得不知的3种部署策略的主要内容,如果未能解决你的问题,请参考以下文章