本文作者:
山猎,阿里云智能技术专家,13年IT领域行业经验,对互联网云原生架构以及大规模分布式技术有着深入理解,实战经验丰富,多次帮助阿里云的行业客户对系统架构完成全面的云原生改造。
前言
在大型分布式IT架构领域,微服务是一项必不可少的技术。从本质上来讲,微服务是一种架构风格,将一个大型的系统拆分为多个拥有独立生命周期的应用,应用之间采用轻量级的通信机制进行通信。这些应用都是围绕具体业务进行构建,可以独立部署、独立迭代,也可能根据业务负载独立的水平扩展。微服务思想以及相关的技术为IT架构的发展带来了一系列深刻的变革:
1、 易于开发和维护:一个应用只会关注一组特定的业务功能,通过服务拆分,能减少应用之间的耦合度,让开发和维护更加简单。
2、 技术栈不受限制:在微服务架构中,可以结合项目业务及团队的特点,合理的选择技术栈。
3、 加快系统演进速度:每一个应用都可以独立的进行版本更新,通过灰度发布等技术手段能确保发布过程中整个系统稳定运行。
4、 突破性能瓶颈:每个应用都能独立的水平伸缩,使系统性能可以根据计算资源的增加而得到线性的扩展。
微服务的挑战
世上没有免费的午餐,微服务技术让IT系统变得更敏捷、更健壮、更高性能的同时,也带来了架构复杂度的提升。对于开发者而言,要想更好的驾驭微服务架构,需要解决持续集成、服务发现、应用通信、配置管理、流量防护等一系列难题。幸运的是,针对这些普遍存在的难题,业界涌现了一系列优秀的开源技术组件和工具,让开发者可以更轻松的构建微服务应用。像Spring Cloud和Dubbo这样的技术框架,经过多年的发展,已经演化为微服务领域的通用标准,极大地降低了微服务的门槛,但这些技术框架依然没有办法解决其中两个最大的挑战,这两个挑战成为摆在开发者面前的两座大山。
挑战一
亟需完善的生命周期管理与服务治理方案:在一个频繁迭代的系统中,每个应用会经常性面临新版本发布需求,需要对应用的上线、下线、更新、回滚等流程进行集中性的管理,并配合精细粒度的灰度发布手段,减少版本迭代对业务造成的影响。
在一个简单的微服务架构中,如果某应用处于整个链路的入口位置,它的前端一般会挂上负载均衡组件(上图中的应用A),以承接来自于最终用户的业务请求。这类应用在进行生命周期管理的时候,复杂度会更高,为了确保应用在新版本发布过程中的平衡稳定,会经过如下的步骤:
在这个流程中,还没有涉及到对于流量精细粒度控制的高级灰度方案,但已经足够体现出其复杂性和操作难度了。如果仅仅依赖于简单的发布脚本进行管理,不但效率很低,还很容易导致顾此失彼,对系统稳定性造成巨大的风险。
挑战二
亟需完善的水平扩容与缩容方案:当某一个应用的性能出现瓶颈,需要通过增加实例数量来进行性能提升的时候,就需要引入新的计算资源。新的计算资源从何而来呢?
对于线下IDC而言,计算资源是需要预先规划的,扩容并不是一件简单的事情,可能会因为各种条件的制约而导致扩容无法实现。当然这种困扰在云计算时代不复存在了,为一个应用扩充计算资源是信手拈来的事情,但光有计算资源是不够的,还得在上面部署应用,并将应用容纳到微服务体系中。
根据这个流程,如果需要扩容一个应用实例,保守估计也需要20分钟以上,其中购买、系统初始化、应用部署都需要占用大量的时间。假设系统流量突增,需要在2分钟之内紧急扩容,这个方案就无用武之地了。
一剂良药:容器化技术
为了解决这两个难题,开发者们尝试了各种各样的方案,新的理念以及技术框架在过去的这五年层出不穷。在一轮轮的优胜劣汰下,以Docker为代表的容器技术,在Kubernetes生态的支撑下,在业界成为了主流,是构建云原生(Cloud Native)应用的必备要素。容器化相关技术能够更大程序的挖掘云计算的价值,在一定程度上帮助开发者解决这两个难题。
在应用生命周期管理以及服务治理方面,Kubernetes提供了比较完善的实现机制,通过构建Deployment资源,配合proStop和postStart脚本,能比较方便的实现滚动发布以及应用的优雅上下线。虽然在灰度发布的过程中,依然没有办法直接对流量进行精细粒度控制(引入ServiceMesh技术能增强流量控制力,不在本文讨论范围),但相比简单的发布脚本,已经有了飞跃性的提升。
在应用的水平扩容与缩容方面,通过容器化技术可以极大程度的减少操作系统安装以及系统级初始化的时间,但购买虚拟机的操作是无法避免的,所以在系统遇到流量增突的时候,依然没有办法实现快速水平扩容。
我们可以预留一部分计算资源,放在资源池中,当应用有扩容需求的时候,就向资源池申请资源,当业务负载下降的时候,再把多余的计算资源归还到资源池中。
这其实并不是一个好主意,每一个计算资源都是需要成本的,资源池虽然能够解决计算资源快速投入使用的问题,却造成了巨大的浪费。另外,到底规划多大的资源池,也是一件很伤脑筋的事情,池子越大,造成的浪费就越大,但池子太小,又可能满足不了扩容的需求。
资源成本更深层次的分析
可能有的开发者会认为,目前的业务运行非常的稳定,在用户流量上并不存在明显的突增,所以扩容和缩容是一个伪需求,在将来也不会有这样的需求。这可能是对互联网业务的一种误解,因为完全没有扩容需求的情况是不存在的。
首先,只要一个系统是为人服务的,就必然存在波峰和波谷。对于一个7*24小时运行的系统,不可能永远保持同样的用户流量,二八原则对于很多业务系统依然适用(80%的用户流量集中在20%的时间段。即便是用户流量相对平衡的系统,在凌晨也存在流量的低谷,如果能更进一步的释放闲置计算资源,提升资源利用率,就能显著的降低资源使用成本。
另外,相比生产环境,开发和测试环境对于扩容和缩容的需求会更加迫切。一套微服务应用由不同的团队进行开发,在理想的情况下,多个团队会共享一套测试环境:
然而,每个团队对于应用的迭代都会有自己的节奏,与此同时,他们又想拥有独立的端到端测试环境,从而实现环境之间的隔离,以避免团队之间的相互影响。这样的话,很有可能会形成多套测试环境:
随着应用、团队、业务功能点数量的增加,所需要的开发测试环境数量还会成倍的增长,造成巨大的资源浪费。对于测试环境的计算资源而言,资源利用率要远低于生产环境。有的时候仅仅是一个简单功能点的验证,为了端对端的跑通业务功能,又避免团队之间的相互影响,就会开启一套包括全部微服务应用的新环境。这样的资源浪费,对于很多企业,都是一个多年都未曾得到解决的难题。
因此,微服务架构在本质上就是对弹性伸缩有着强烈诉求的,在弹性伸缩的过程中,不管是单应用的水平弹性伸缩,还是整套环境的启停,资源利用率都对最终的资源成本起着决定性的作用。如果能想办法提升资源利用率,就能为企业节省大量资源成本。值得我们重视的是,绝大多数的微服务应用的资源利用率都是非常低的。我们可以做一个简单的统计:把所有服务器的CPU利用率每5分钟导出一次,按照天的维度求平均值,就能从整体上了解系统的资源利用率数据。如果把开发测试环境的服务器资源也纳入统计的范围,资源利用率很有可能会更低。
Serverless化探索
资源利用率低的根本原因,在于以服务器为载体的应用架构中,开发者需要将构建好的程序包部署到服务器上,从而对多个用户事件进行响应。为了确保事件响应的及时性,需要让程序长驻于服务器上,而且尽可能保守的规划资源,以避免出现负载过重而导致服务崩溃的情况。在这个过程中,实际的负载在时间上分配并不均衡,从而导致整体的资源利用率偏低。
Serverless技术的出现,为提升资源利用率提供了新的思路。Serverless是一种构建和管理基于微服务架构的完整流程,允许开发者脱离服务器资源而直接部署应用。它与传统架构的不同之处在于,完全由第三方管理,由事件触发,存在于无状态(Stateless)的计算容器内。构建无服务器应用程序意味着开发者可以专注在产品代码上,而无须管理和操作服务器资源,真正做到了部署应用无需涉及基础设施的建设。
Serverless技术存在多种形态,最典型的一种是FaaS(Function as a Service,函数即服务),比如阿里云的函数计算(Function Compute,FC)产品。在函数计算领域,一切计算资源的申请和调度都由具体的业务事件触发,当业务事件所对应的任务完成之后,计算资源会被立即释放。这样的方式真做到了计算资源的按需分配,能显著提升资源利用率,是Serverless技术的终极形态。
另外一种是Serverless化的容器技术,Serverless化的容器实例运行在案例隔离的环境中,每个计算节点通过轻量级虚拟化安全沙箱技术完全强隔离。对于使用者而言,无需购买服务器资源即可直接部署容器应用,也无需对集群进行节点维护和容量规划,可以根据应用配置的CPU和内存资源量进行按需付费。当微服务应用需要扩容的时候,就可以快速获得计算资源,不需要再经过购买服务器这个步骤了,可以帮助开发者降低计算成本,减少闲置资源浪费,平滑应对突发流量高峰。阿里云的Serverless Kubernetes(ASK)就是Serverless化容器技术的代表产品。
更进一步发掘开发者的诉求
Serverless技术无缝是云计算和云原生应用架构的发展方向,但对于微服务应用的开发者而言,不管是FaaS形态,还是Serverless Kubernetes,都存在一定的局限性。
不是每一种业务都适合通过FaaS的方式进行构建,特别是对于链路长,上下游依赖特别明显的应用,根本没有办法进行FaaS化改造。即便某些业务系统的FaaS化改造被证明可行,把现有的微服务架构改造成FaaS架构也需要一定的工作量,并不能做到无缝移植。
Serverless Kubernetes架构虽然能适配所有的业务场景,但对于开发者而言,构建一整套Kubernetes体系,需要掌握一系列跟Kubernetes相关复杂的概念,有着非常陡的学习曲线。而且Kubernetes生态中各种组件的搭建,再加上网络层与存储层的适配,都涉及非常复杂的工作。
造成这种局限性的原因很简单,在以Spring Cloud为代表的微服务技术阵营中,系统的构建都是围绕着应用(也可以理解为单个的服务)而展开,不管是版本更新还是水平扩展,都是针对应用本身。Serverless Kubernetes架构的核心在于Pod,比应用更偏向系统底层,所以使用者需要投入更多的精力用于应用下层资源的管理。而FaaS架构的核心在于函数,比应用更偏向系统上层,因此灵活度会降低,不能适配所有的业务场景。
对于使用主流Spring Cloud体系或Dubbo体系构建微服务应用的开发者而言,如果需要引入一种方案降低资源成本,他的最终诉求一定包含两个方面:
1、 能否0改造成本,或者接近0改造成本。
2、 能否适配所有的业务场景。
应用层Serverless技术
是否有一种介于FaaS和Serverless化容器之间的技术,可以实现上述重要诉求呢?当然有,这就是以阿里云Serverless应用引擎(SAE)为代表的应用层Serverless技术。
图:不同层级的Serverless技术
SAE实现了Serverless 架构 + 微服务架构的完美融合,对于Spring Cloud和Dubbo等主流的微服务架构,可以实现无缝兼容,基本上没有改造成本,并真正按需使用、按量计费,节省闲置计算资源,同时免去 IaaS层运维方面的工作,有效提升开发运维效率。
以Spring Cloud应用为例,如果需要部署一个新的应用,只需要2个步骤:
1、 告诉SAE这个应用需要多少个实例,并指定每个实例需要的CPU/内存规格。
2、 上传应用的JAR包/WAR包,并启动应用。
我们发现,这2个步骤中并不涉及容量评估、服务器购买、操作系统安装、资源初始化等工作,就能让包含多个对等实例的微服务应用运行起来。这是因为在Serverless的世界中,不再具有服务器资源这样的概念,应用的载体是SAE调度出来的沙箱容器,每个实例只有在真正投入使用后,才会按使用时长进行计费。
对于开发者而言,他们不用关心应用到底部署在物理机里面,还是虚拟机里面,或是容器里面,也不需要知道底层的操作系统是什么版本的,只需要关注每个应用实例占据多少运算资源就可以了。如果应用需要从4个实例扩容到6个实例,或者缩容到2个实例,只需要一个指令就可以完成,甚至与SLB的绑定关系,都可以自动的建立或解除,这是Serverless技术为开发者带来的巨大价值。
使用SAE部署微服务应用,因为只是变更了应用运行的载体,所以可以100%的兼容现有的技术架构和业务功能,迁移成本可以忽略不计。
SAE的极致弹性能力
除了手动的扩缩容指令,SAE还支持2种自动弹性机制,可以对微服务应用进行灵活的水平扩展,更进一步的发挥云计算的弹性能力。
1、 定时弹性机制:对于会预期发生的周期性行为,可以设置定时弹性策略。举例:如果每天的上午9点是业务高峰,可以定时每天8点半增加实例数量,并在9点半减少实例数量。
2、 基于指标阈值的弹性机制:对于超出预期的业务流量突增,可以设置基于指标阈值的弹性策略,根据CPU、内存等资源指标,以有QPS等业务指标让应用实现自动的弹性缩。
通过多种弹性机制,能够对系统容量进行精细粒度的管理,使资源的使用量能随着业务流量的变化而调整,从而极大程度的增加资源利用率,大幅降低资源成本。
在计算资源的调度和启动上,SAE做了多项优化,对于扩容出来的新实例,只需要几秒钟的时间就能拉起,这项能力对于一些需要紧急快速扩容的突发场景,是具有重大意义的。
对于开发测试环境而言,SAE的机制弹性能力能体现得更加淋漓尽致,得益于SAE出色的资源调度能力,可以一键启停一整套微服务应用。即便仅对一项简单的新功能进行冒烟测试,也完全可以新启一套完整而隔离的测试环境来进行。新的环境可以在秒级搭建完成,快速投入使用,而测试完毕后,又可以立即释放。从成本上来讲,一套新环境实际投入使用的时间很短,因此只会消耗极少的费用。这对于微服务应用开发过程中的多团队协作,是一个巨大的变革。
成本分析
SAE通过资源的实际使用量来付费,费用由两部分组成,每部分根据统计结果和计算方式进行费用结算,按小时出账单扣款。每个应用使用的资源计量方式如下所示:
1、 应用CPU资源使用量=∑实例CPU规格×本月运行时长(以分钟计),即应用中所有实例的CPU规格乘以本月运行时长的总和。
2、 应用内存资源使用量=∑实例内存规格×本月运行时长(以分钟计),即应用中所有实例的内存规格乘以本月运行时长的总和。
其中CPU部分的价格为0.0021605元/分钟/Core,内存部分的价格为0.0005401元/分钟/GiB。SAE还提供预付费资源包,相当于批发的方式预购计算资源,只要能要有效期内消耗完,就能更进一步的节省使用成本,当资源包扣完以后,系统会自动变更为按量付费的模式。
让我们通过一个实际案例来进一步体会SAE如何帮助微服务应用降低资源成本。假设一个微服务系统包含87个应用实例,每个时间每天的平均运行时长为8小时,实例的配置为2 Core + 4 GiB + 20 G磁盘。
1、 使用包年包月的ECS部署应用:需要购买87台计算型c5,单台的月成本为186元,每月总成本16146元。
2、 使用按量付费的ECS部署应用:单台价格为0.63元/小时,每月累计使用20880小时,总成本13154元。
3、 使用SAE部署应用:购买1个75000元的包年资源包,87个实例每天运行8个小时,刚好把资源包额度用完,折合每月总成本6250元。
从这个对比我们可以得出,只要能够合理的运行SAE的弹性能力,就可以为微服务应用大幅度降低资源成本。
附加能力
SAE除了可以简化运维工作量,降低资源成本以外,还为微服务应用提升了一系列附加的功能,这是应用层Serverless技术为开发者带来的额外价值,我们可以尽可能的利用这些开箱即用的功能,让建设微服务应用变成更加简单。
1、 完整的应用生命周期管理:应用托管至SAE后,可以对应用执行更新、扩缩容、启停、删除、监控启停等应用生命周期管理操作。
2、 开箱即用的注册中心:SAE自带商业版Nacos注册中心,可以免费使用,不需要自行搭建。如果有特殊的需求,比如让部署在SAE的应用和其他应用相互发现,也可以使用微服务引擎(MSE)产品提供的注册中心,或者自建的注册中心。
3、 开箱即用的配置管理中心:SAE集成了ACM(Application Configuration Management,应用配置管理)中的配置管理功能,可以在SAE中使用ACM对应用配置进行集中管理。
4、 应用级流量防护:SAE集成AHAS实现应用级别的流控与降级能力,全面保障应用的高可用性。
5、 监控能力:应用托管到SAE以后,可以免费获得基础资源(包括CPU、内存、负载和网络)以及应用层(包括JVM分析、接口调用分析等方面)的监控能力。如果需要更高级的SQL分析、异常分析、链路上下游和接口快照,可以集成阿里云应用时间监控产品(ARMS)。
6、 CI/CD集成能力:SAE与云效、云效2020、Jenkins等产品进行了深入集成,可以方便开发者将构建好的应用快速部署。
多语言支持
对于非Java语言编写的应用,或者没有使用Spring Cloud等微服务框架的Java应用,SAE能不能完美支持,并帮助企业降低资源成本呢?当然是可以的。SAE提供容器镜像部署方式,这就代表着不管采用哪种编程语言,只要最终的应用能够发布成容器镜像,就可以部署在SAE上。
对于Java系的微服务应用,Java系统的普通应用,以及非Java系应用而言,SAE的极致弹性能力并没有本质的区别,都能通过Serverless技术提供系统的资源利用率。只不过SAE提供的一些附加价值,比如免费的微服务注册中心,就只能为Spring Cloud或Dubbo应用服务罢了。
总结
让我们用这张图回顾Serverless技术的巨大价值:
常见问题
1、 问:应用实例没有固定的机器资源,连固定的ip地址都没有,如何SSH到一台服务器排查问题?
答:并不需要有固定的机器资源和固定的IP地址才能排查问题,在云计算时代,通过SSH登录到一台机器排查问题的方式并不是一个好的实践。相反,SAE提供了完善的监控能力,还可以方便的与云监控、ARMS等新一代监控诊断类产品进行了集成,为排查故障提供了更大的便利。当然,如果一定要登录到某一台机器,SSH依然是可以支持的,也可以利用SAE提供的Webshell工具简化这个流程。
2、 问:磁盘不是计费的维度吗?应用需要大容量磁盘怎么办?应用重启后碰盘中的数据还保留吗?
答:在微服务领域,应用一般是无状态(Stateless)的,不需要保存大量的本地数据。如果在特殊的场景下离不开这个需求,可以集成NAS,使用集中式的存储实现。
3、 问:应用的日志怎么查看?
答:SAE控制台界面提供了对于文件日志的实时查阅能力,相当于免费提供了一个分布式日志采集平台。当然强烈建议接入阿里云日志服务(SLS)产品,更进一步的发挥应用日志的价值。
阿里云专门成立了“互联网架构升级实战课”钉钉群,每周都有阿里云专家在群内进行行业最佳实践直播,每天分享前沿干货,欢迎扫码或钉钉搜索群号加入:35712134。