共计 12307 个字符,预计需要花费 31 分钟才能阅读完成。
Serverless 是目前比拟热门的技术话题,各大云平台以及互联网大厂外部都在踊跃建设 Serverless 产品。本文将介绍美团 Serverless 产品在落地过程中的一些实践经验,其中包含技术选型的考量、零碎的具体设计、零碎稳定性优化、产品的周边生态建设以及在美团的落地状况。尽管各个公司的背景不尽相同,但总有一些能够互相借鉴的思路或办法,心愿能给大家带来一些启发或者帮忙。
1 背景
Serverless 一词于 2012 年被提出,2014 年因为亚马逊的 AWS Lambda 无服务器计算服务的衰亡,而被大家宽泛认知。Serverless 通常被直译成“无服务器”,无服务器计算是能够让用户在不思考服务器的状况下构建并运行应用程序。应用无服务器计算,应用程序仍在服务器上运行,但所有服务器管理工作均由 Serverless 平台负责。如机器申请、代码公布、机器宕机、实例扩缩容、机房容灾等都由平台帮忙主动实现,业务开发只需思考业务逻辑的实现即可。
回顾计算行业的倒退历程,基础设施从物理机到虚拟机,再从虚拟机到容器;服务架构从传统单体利用架构到 SOA 架构,再从 SOA 架构到微服务架构。从基础设施和服务架构两条主线来看整体技术发展趋势,大家可能会发现,不论是基础设施还是服务架构,都是从大往小或者由巨到微的方向上演进,这种演变的实质准则无非是解决资源老本或者研发效率的问题。当然,Serverless 也不例外,它也是用来解决这两个方面的问题:
- 资源利用率:Serverless 产品反对疾速弹性伸缩能力,可能帮忙业务晋升资源利用率,在业务流量顶峰时,业务的计算能力、容量主动扩容,承载更多的用户申请,而在业务流量下降时,所应用的资源也会同时膨胀,防止资源节约。
- 研发运维效率:在 Serverless 上开发人员个别只须要填写代码门路或者上传代码包,平台可能帮忙实现构建、部署的工作。开发人员不间接面对机器,对于机器的治理,机器是否失常以及流量高下峰的是否须要扩缩容等问题,这些通通不须要去思考,由 Serverless 产品帮忙研发人员去实现。这样就能使他们从繁琐的运维工作中解放出来,从 DevOps 转向 NoOps,更加专一于业务逻辑的实现。
尽管 AWS 在 2014 年就推出了第一个 Serverless 产品 Lambda,但 Serverless 技术在国内的利用始终不温不火。不过近两三年,在容器、Kubernetes 以及云原生等技术的推动下,Serverless 技术迅速倒退,国内各大互联网公司都在踊跃建设 Serverless 相干产品,摸索 Serverless 技术的落地。在这种背景下,美团也于 2019 年初开始了 Serverless 平台的建设,外部项目名称为 Nest。
截止到目前,Nest 平台曾经过两年的建设,回顾整体的建设过程,次要经验了以下三个阶段:
- 疾速验证,落地 MVP 版本:咱们通过技术选型、产品与架构设计、开发迭代,疾速落地了 Serverless 产品的根本的能力,如构建、公布、弹性伸缩、对接触发祥、执行函数等。上线后,咱们推动了一些业务的试点接入,帮忙验证打磨产品。
- 优化核心技术,保障业务稳定性:有了后期的试点业务验证,咱们很快发现产品的存在的一些稳定性相干的问题,次要有弹性伸缩的稳定性、冷启动的速度、零碎与业务的可用性、容器的稳定性。针对这些问题咱们对各个问题波及的技术点做了专项的优化改良。
- 欠缺技术生态,落实收益:优化了核心技术点后,产品逐步成熟稳固,但仍然面临生态性问题,如研发工具欠缺,上下游产品没有买通、平台凋谢能力有余等问题,影响或妨碍了产品的推广应用。因而,咱们持续欠缺产品的技术生态,扫清业务接入应用阻碍,落实产品的业务收益。
2 疾速验证,落地 MVP 版本
2.1 技术选型
建设 Nest 平台,首要解决的就是技术选型问题,Nest 次要波及三个关键点的选型:演进路线、基础设施、开发语言。
2.1.1 演进路线
起初 Serverless 服务次要蕴含 FaaS(Function as a Service)和 BaaS(Backend as a Service),近几年 Serverless 的产品畛域有所扩张,它还蕴含面向利用的 Serverless 服务。
- FaaS:是运行在一个无状态的计算容器中的函数服务,函数通常是事件驱动、生命周期很短(甚至只有一次调用)、齐全由第三方治理的。业界相干 FaaS 产品有 AWS 的 Lambda、阿里云的函数计算等。
- BaaS:是建设在云服务生态之上的后端服务。业界相干 BaaS 产品包含 AWS 的 S3、DynamoDB 等。
面向利用的 Serverless 服务:如 Knative,它提供了从代码包到镜像的构建、部署,以及弹性伸缩等全面的服务托管能力,私有云产品有 Google Cloud Run(基于 Knative)、阿里云的 SAE(Serverless Application Engine)。
在美团外部,BaaS 产品其实就是外部的中间件以及底层服务等,它们通过多年的倒退,曾经十分丰盛且成熟了。因而,在美团的 Serverless 产品演进次要在函数计算服务和面向利用的 Serverless 服务两个方向上。那到底该如何演进呢?过后次要思考到在业界 FaaS 函数计算服务绝对于面向利用的 Serverless 服务来说,更加成熟且确定。因而,咱们决定“先建设 FaaS 函数计算服务,再建设面向利用的 Serverless 服务”这样一条演进路线。
2.1.2 基础设施
因为弹性伸缩是 Serverless 平台必备的能力,因而 Serverless 必然波及到底层资源的调度和治理。这也是为什么以后业界有很多开源的 Serverless 产品(如 OpenFaaS、Fission、Nuclio、Knative 等)是基于 Kubernetes 来实现的,因为这种选型可能充分利用 Kubernetes 的基础设施的治理能力。在美团外部基础设施产品是 Hulk,尽管 Hulk 是基于 Kubernetes 封装后的产品,但 Hulk 在落地之初思考到落地难度以及各种起因,最终未依照原生的形式来应用 Kubernetes,并且在容器层采纳的也是富容器模式。
在这种历史背景下,咱们在做基础设施选型时就面临两种选项:一是应用公司的 Hulk 来作为 Nest 的基础设施(非原生 Kubernetes),二是采纳原生 Kubernetes 基础设施。咱们思考到以后业界应用原生 Kubernetes 是支流趋势并且应用原生 Kubernetes 还能充分利用 Kubernetes 原生能力,能够缩小反复开发。因而,最终考量的后果是咱们采纳了 原生 Kubernetes 作为咱们的基础设施。
2.1.3 开发语言
因为在云原生畛域的支流语言是 Golang,并且 Kubernetes 的生态中,Golang 是相对的主导语言。但在美团,Java 才是应用最宽泛的语言,相比 Golang,Java 在公司外部生态比拟好。因而,在语言的选型上咱们 抉择了 Java 语言。在 Nest 产品开发之初,Kubernetes 社区的 Java 客户端还不够欠缺,但随着我的项目的推动,社区的 Java 客户端也逐步丰盛了起来,目前曾经齐全够用了。另外,咱们也在应用过程中,也奉献了一些 Pull Request,反哺了社区。
2.2 架构设计
基于以上的演进路线、基础设施、开发语言的选型,咱们进行了 Nest 产品的架构设计。
在整体的架构上,流量由 EventTrigger(事件触发源,如 Nginx、利用网关、定时工作、音讯队列、RPC 调用等)触发到 Nest 平台,Nest 平台内会依据流量的特色路由到具体函数实例,触发函数执行,而函数外部代码逻辑能够调用公司内的各个 BaaS 服务,最终实现函数的执行,返回后果。
在技术实现上,Nest 平台应用 Kubernetes 作为根底底座并适当参考了一些 Knative 的优良设计,在其架构外部次要由以下几个外围局部组成:
- 事件网关:外围能力是负责对接内部事件源的流量,而后路由到函数实例上;另外,网关还负责统计各个函数的进出流量信息,为弹性伸缩模块提供伸缩决策的数据撑持。
- 弹性伸缩:外围能力是负责函数实例的弹性伸缩,伸缩次要依据函数运行的流量数据以及实例阈值配置计算函数指标实例个数,而后借助 Kubernetes 的资源控制能力,调整函数实例的个数。
- 控制器:外围能力是负责 Kubernetes CRD(Custom Resource Definition)的管制逻辑实现。
- 函数实例:函数的运行实例。当事件网关流量触发过去,会在函数实例内执行相应的函数代码逻辑。
- 治理平台:面向用户应用的平台,负责函数的构建、版本、公布以及一些函数元信息的治理等。
2.3 流程设计
在具体的 CI/CD 流程上,Nest 又与传统的模式有何区别呢?为了阐明这个问题,咱们先来看一看在 Nest 平台上函数的整体生命周期怎么的?具体有以下四个阶段:构建、版本、部署、伸缩。
- 构建:开发的代码和配置通过构建生成镜像或可执行文件。
- 版本:构建生成的镜像或可执行文件加上公布配置造成一个不可变的版本。
- 部署:将版本公布,即实现部署。
- 伸缩:依据函数实例的流量以及负载等信息,来进行实例的弹性扩缩容。
就这四个阶段来看,Nest 与传统的 CI/CD 流程本质区别在于部署和伸缩:传统的部署是感知机器的,个别是将代码包公布到确定的机器上,但 Serverless 是要向用户屏蔽机器的(在部署时,可能函数的实例数还是 0);另外,传统的模式个别是不具备动静扩缩容的,而 Serverless 则不同,Serverless 平台会依据业务的本身流量须要,进行动静扩缩容。后续章节会具体解说弹性伸缩,因而这里咱们只探讨部署的设计。
部署的外围点在于如何向用户屏蔽机器?对于这个问题,咱们 形象了机器,提出了分组 的概念,分组是由 SET(单元化架构的标识,机器上会带有该标识)、泳道(测试环境隔离标识,机器上会带有该标识)、区域(上海、北京等)三个信息组成。用户部署只需在相应的分组上进行操作,而不必波及到具体机器。可能做到这些的背地,是由 Nest 平台帮忙用户治理了机器资源,每次部署会依据分组信息来实时初始化相应的机器实例。
2.4 函数触发
函数的执行是由事件触发的。实现函数的触发,须要实现以下四个流程:
- 流量引入:向事件源注册事件网关的信息,将流量引入到事件网关。如针对 MQ 事件源,通过注册 MQ 的生产组,引入 MQ 的流量到事件网关。
- 流量适配:事件网关对事件源进入的流量进行适配对接。
- 函数发现:对函数元数据(函数实例信息、配置信息等)的获取过程,相似微服务的服务发现过程。事件网关承受的事件流量须要发送到具体的函数实例,这就须要对函数进行发现。这里发现本质是获取 Kubernetes 中的内置资源或者 CRD 资源中存储的信息。
- 函数路由:事件流量的路由过程,路由到特定的函数实例上。这里为了反对传统路由逻辑(如 SET、泳道、区域路由等)以及版本路由能力,咱们采纳了多层路由,第一层路由到分组(SET、泳道、区域路由),第二层路由到具体版本。同版本内的实例,通过负载均衡器抉择出具体实例。另外,通过该版本路由,咱们很轻松的反对了金丝雀、蓝绿公布。
2.5 函数执行
函数不同于传统的服务,传统的服务是个可执行的程序,但函数不同,函数是代码片段,本身是不能独自执行的。那流量触发到函数实例后,函数是如何执行的呢?
函数的执行的首要问题是函数的运行环境:因为 Nest 平台是基于 Kubernetes 实现的,因而函数肯定是运行在 Kubernetes 的 Pod(实例)内,Pod 外部是容器,容器的外部是运行时,运行时是函数流量接管的入口,最终也是由运行时来触发函数的执行。所有看起来是那么的顺利成章,但咱们在落地时是还是遇到了一些艰难,最次要的艰难是 让开发同学能够在函数内无缝的应用公司内的组件,如 OCTO(服务框架)、Celler(缓存零碎)、DB 等。
在美团的技术体系中,因为多年的技术积淀,很难在一个纯正的容器(没有任何其余依赖)中运行公司的业务逻辑。因为公司的容器中积淀了很多环境或服务治理等能力,如服务治理的 Agent 服务以及实例环境配置、网络配置等。
因而,为了业务在函数内无缝的应用公司内的组件,咱们复用公司的容器体系来升高业务编写函数的老本。但复用公司的容器体系也没那么简略,因为在公司内没有人试过这条路,Nest 是公司第一个基于原生 Kubernetes 建设的平台,“第一个吃螃蟹的人”总会遇到一些坑。对于这些坑,咱们只能在推动过程中“逢山开路,遇水搭桥”,遇到一个解决一个。总结下来,其中最外围的是在容器的启动环节买通的 CMDB 等技术体系,让运行函数的容器与开发同学平时申请的机器用起来没有任何区别。
2.6 弹性伸缩
弹性伸缩的外围问题次要有三个:什么时候伸缩,伸缩多少,伸缩的速度快不快?也就是伸缩机会、伸缩算法、伸缩速度的问题。
- 伸缩机会:依据流量 Metrics 实时计算函数冀望实例数,进⾏扩缩。流量的 Metrics 数据来自于事件网关,这里次要统计函数的并发度指标,弹性伸缩组件每秒中会被动从事件网关获取一次 Metrics 数据。
- 伸缩算法:并发度 / 单实例阈值 = 冀望实例数。依据收集的 Metrics 数据以及业务配置的阈值,通过算法计算出冀望的实例数,而后通过 Kubernetes 接口设置具体实例数。整个算法看起来尽管简略,但十分稳固、鲁棒性好。
- 伸缩速度:次要取决于冷启动工夫,在下个章节会具体解说这块内容。
除了根本的扩缩容能力,咱们还反对了伸缩到 0,反对配置最大、最小实例数(最小实例即预留实例)。伸缩到 0 的具体实现是,咱们在事件网关外部减少了激活器模块,当函数无实例时,会将函数的申请流量缓存在激活器外部,而后立刻通过流量的 Metrics 去驱动弹性伸缩组件进行扩容,等扩容的实例启动实现后,激活器再将缓存的申请重试到扩容的实例上触发函数执行。
3 优化核心技术,保障业务稳定性
3.1 弹性伸缩优化
下面提到的伸缩机会、伸缩算法、伸缩速度这三要素都是现实状况下的模型,尤其是伸缩速度,以后技术基本做不到毫秒级别的扩缩容。因而,在线上理论场景中,弹性伸缩会存在一些不合乎预期的状况,比方实例伸缩比拟频繁或者扩容来不及,导致服务不太稳固的问题。
- 针对实例伸缩比拟频繁问题,咱们在弹性伸缩组件内保护了统计数据的滑动窗⼝,通过计算均值来平滑指标,还通过延时缩容,实时扩容来缓解频繁扩缩问题。另外,咱们减少了基于 QPS 指标的伸缩策略,因为 QPS 指标绝对并发度指标会更加稳固。
- 针对扩容来不及问题,咱们采取提前扩容的伎俩,当达到实例阈值的 70% 就扩容,可能比拟好的缓解这个问题。除此之外,咱们还反对了多指标混合伸缩(并发度、QPS、CPU、Memory),定时伸缩等策略,满足各种业务需要。
下图展现的是线上弹性伸缩的实在案例(其配置的最小实例数为 4,单实例阈值 100,阈值使用率 0.7),其中上半局部是业务每秒的申请数,下半局部是扩缩实例的决策图,能够看到在成功率 100% 的状况下,业务完满应答流量顶峰。
3.2 冷启动优化
冷启动是指在函数调用链路中蕴含了资源调度、镜像 / 代码下载、启动容器、运行时初始化、用户代码初始化等环节。当冷启动实现后,函数实例就绪,后续申请就能间接被函数执行。冷启动在 Serverless 畛域至关重要,它的耗时决定了弹性伸缩的速度。
所谓“天下文治,无坚不破,唯快不破”,这句话在 Serverless 畛域也同样受用。试想如果拉起一个实例足够快,快到毫秒级别,那简直所有的函数实例都能够缩容到 0,等有流量时,再扩容实例解决申请,这对于存在高下峰流量的业务将极大的节俭机器资源老本。当然,现实很饱满,事实很骨感。做到毫秒级别简直不可能。但只有冷启动工夫越来越短,老本天然就会越来越低,另外,极短的冷启动工夫对伸缩时函数的可用性以及稳定性都有莫大的益处。
冷启动优化是个循序渐进的过程,咱们对冷启动优化次要经验了三个阶段:镜像启动优化、资源池优化、外围门路优化。
- 镜像启动优化:咱们对镜像启动过程中的耗时环节(启动容器和运行时初始化)进行了针对性优化,次要对容器 IO 限速、一些非凡 Agent 启动耗时、启动盘与数据盘数据拷贝等关键点的优化,最终将启动过程中的零碎耗时从 42s 优化到 12s 左右。
- 资源池优化:镜像启动耗时优化到 12s,根本曾经快达到瓶颈点,再持续优化空间不大。因而,咱们想是否绕开镜像启动的耗时环节?最终,咱们采纳了一个比较简单思路“空间换工夫”,用资源池计划:缓存一些已启动的实例,当须要扩容时,间接从资源池获取实例,绕开镜像启动容器的环节,最终成果很显著,将启动的零碎耗时从 12s 优化到 3s。这里须要阐明的是资源池本身也是通过 Kubernetes 的 Depolyment 进行治理,池中实例被取走会立刻主动补充。
- 外围门路优化:在资源池优化的根底上,咱们再次精益求精,针对启动流程中的下载与解压代码两个耗时环节进行优化,过程中咱们采纳了高性能的压缩解压算法(LZ4 与 Zstd)以及并行下载和解压技术,成果十分好。另外,咱们还反对了通用逻辑(中间件、依赖包等)下沉,通过预加载的形式,最终将函数端到端的启动耗时优化到 2s,这就意味着扩容一个函数实例只须要 2s(蕴含函数启动)。如果排除掉函数本身的初始化启动耗时,平台侧的耗时已在毫秒级别。
3.3 高可用保障
说到高可用,对于个别的平台,指的就是平台本身的高可用,但 Nest 平台有所不同,Nest 的高可用还蕴含托管在 Nest 平台上的函数。因而,Nest 的高可用保障须要从平台和业务函数两个方面着手。
3.3.1 平台高可用
对平台的高可用,Nest 次要从架构层、服务层、监控经营层、业务视角层面都做了全面的保障。
- 架构层:咱们针对有状态服务,如弹性伸缩模块,采纳了主从架构,当主节点异样时从节点会立刻替换。另外,咱们还实现了架构上的多层隔离。横向地区隔离:Kubernetes 两地两集群强隔离、服务(事件网关、弹性伸缩)集群内两地弱隔离(上海的弹性伸缩只负责上海 Kubernetes 集群内的业务伸缩,事件网关存在两地调用需要,需拜访两地 Kubernetes)。纵向业务线隔离:服务业务线强隔离,不同业务线应用不同集群服务;在 Kubernetes 层的资源用 namespace 实现业务线弱隔离。
- 服务层:次要指的是事件网关服务,因为所有的函数流量都通过事件网关,因而事件网关的可用性尤为重要,这层咱们反对了限流和异步化,保障服务的稳定性。
- 监控经营层:次要通过欠缺系统监控告警、梳理外围链路并推动相干依赖方进行治理。另外,咱们会定期梳理 SOP 并通过故障演练平台施行故障注入演练,发现零碎隐患问题。
- 业务视角层:咱们开发了在线不间断实时巡检服务,通过模仿用户函数的申请流量,实时检测零碎的外围链路是否失常。
3.3.2 业务高可用
对于业务高可用,Nest 次要从服务层、平台层两个层面做了相干的保障。
- 服务层:反对了业务降级、限流能力:当后端函数故障时,可通过降级配置,返回降级后果。针对异样的函数流量,平台反对限度其流量,避免后端函数实例的被异样流量打垮。
- 平台层:反对了实例保活、多层级容灾以及丰盛的监控告警能力:当函数实例异样时,平台会主动隔离该实例并立刻扩容新实例。平台反对业务多地区部署,在同地区将函数实例尽可能打散不同机房。当宿主机、机房、地区故障时,会立刻在可用宿主机、可用机房或可用区重建新实例。另外,平台主动帮业务提供了函数在时延、成功率、实例伸缩、申请数等多种指标的监控,当在这些指标不合乎预期时,主动触发告警,告诉业务开发和管理员。
3.4 容器稳定性优化
前文已提到,Serverless 与传统模式在 CI/CD 流程上是不同的,传统模式都是当时筹备好机器而后部署程序,而 Serverless 则是依据流量的高下峰实时弹性扩缩容实例。当新实例扩容进去后,会立刻解决业务流量。这听起来貌似没什么故障,但在富容器生态下是存在一些问题的:咱们发现刚扩容的机器负载十分高,导致一些业务申请执行失败,影响业务可用性。
剖析后发现次要是因为容器启动后,运维工具会进行 Agent 降级、配置批改等操作,这些操作十分耗 CPU。同在一个富容器中,天然就抢占了函数过程的资源,导致用户过程不稳固。另外,函数实例的资源配置个别比传统服务的机器要小很多,这也加剧了该问题的严重性。基于此,咱们参考业界,联结容器设施团队,落地了轻量级容器,将运维的所有 Agent 放到 Sidecar 容器中,而业务的过程独自放到 App 容器中。采纳这种容器的隔离机制,保障业务的稳定性。同时,咱们也推动了容器裁剪打算,去掉一些不必要的 Agent。
4 欠缺生态,落实收益
Serverless 是个系统工程,在技术上波及到 Kubernetes、容器、操作系统、JVM、运行时等各种技术,在平台能力上波及到 CI/CD 各个流程的方方面面。
为了给用户提供极致的开发体验,咱们为用户提供了开发工具的反对,如 CLI(Command Line Interface)、WebIDE 等。为了解决现有上下游技术产品的交互的问题,咱们与公司现有的技术生态做了交融买通,不便开发同学应用。为了不便上游的集成平台对接,咱们凋谢了平台的 API,实现 Nest 赋能各上游平台。针对容器过重,零碎开销大,导致低频业务函数本身资源利用率不高的问题,咱们反对了函数合并部署,成倍晋升资源利用率。
4.1 提供研发工具
开发工具可能升高平台的应用老本,帮忙开发同学疾速的进行 CI/CD 流程。目前 Nest 提供了 CLI 工具,帮忙开发同学疾速实现创立利用、本地构建、本地测试、Debug、近程公布等操作。Nest 还提供了 WebIDE,反对在线一站式实现代码的批改、构建、公布、测试。
4.2 交融技术生态
仅反对这些研发工具还是不够的,我的项目推广应用后,咱们很快就发现开发同学对平台有了新的需要,如无奈在 Pipeline 流水线、线下服务实例编排平台上实现对函数的操作,这对咱们我的项目的推广也造成了一些妨碍。因而,咱们交融这些公司的成熟技术生态,买通了 Pipeline 流水线等平台,融入到现有的上下游技术体系内,解决用户的后顾之忧。
4.3 开放平台能力
有很多 Nest 的上游解决方案平台,如 SSR(Server Side Render)、服务编排平台等,通过对接 Nest 的 OpenAPI,实现了生产力的进一步解放。例如,不必让开发同学本人去申请、治理和运维机器资源,就可能让用户十分疾速的实现一个 SSR 我的项目或者编排程序从 0 到 1 的创立、公布与托管。
Nest 除了凋谢了平台的 API,还对用户提供了自定义资源池的能力,领有了该项能力,开发同学能够定制本人的资源池,定制本人的机器环境,甚至能够下沉一些通用的逻辑,实现冷启动的进一步优化。
4.4 反对合并部署
合并部署指的是将多个函数部署在一个机器实例内。合并部署的背景次要有两个:
- 以后的容器较重,容器本身的零碎开销较大,导致业务过程资源利用率不高(尤其是低频业务)。
- 在冷启动耗时不能满足业务对时延的要求的状况下,咱们通过预留实例来解决业务的需要。
基于这两个背景,咱们思考反对合并部署,将一些低频的函数部署到同一个机器实例内,来晋升预留实例中业务过程的资源利用率。
在具体实现上,咱们参考 Kubernetes 的设计方案,设计了一套基于 Sandbox 的函数合并部署体系(每个 Sandbox 就是一个函数资源),将 Pod 类比成 Kubernetes 的 Node 资源,Sandbox 类比成 Kubernetes 的 Pod 资源,Nest Sidecar 类比成 Kubelet。为了实现 Sandbox 特有的部署、调度等能力,咱们还自定义了一些 Kubernetes 资源(如 SandboxDeployment、SandboxReplicaSet、SandboxEndpoints 等)来反对函数动静插拔到具体的 Pod 实例上。
除此之外,在合并部署的状态下,函数之间的隔离性 也是不可回避的问题。为了尽可能的解决函数(合并在同一个实例中)之间的相互烦扰问题,在 Runtime 的实现上,咱们针对 Node.js 和 Java 语言的特点采取了不同的策略:Node.js 语言的函数应用不同的过程来实现隔离,而 Java 语言的函数,咱们采纳类加载隔离。采纳这种策略的次要起因是因为 Java 过程占用内存空间相较于 Node.js 过程会大很多。
5 落地场景、收益
目前 Nest 产品在美团前端 Node.js 畛域十分受欢迎,也是落地最宽泛的技术栈。以后 Nest 产品在美团前端已实现了规模化落地,简直涵盖了所有业务线,接入了大量的 B / C 端的外围流量。
5.1 落地场景
具体的落地前端场景有:BFF(Backend For Frontend)、CSR(Client Side Render)/SSR(Server Side Render)、后盾治理平台场景、定时工作、数据处理等。
- BFF 场景:BFF 层次要为前端页面提供数据,采纳 Serverless 模式,前端同学不须要思考不善于的运维环节,轻松实现了 BFF 向 SFF(Serverless For Frontend)模式的转变。
- CSR/SSR 场景:CSR/SSR 指的是客户端渲染和服务端渲染,有了 Serverless 平台,不必思考运维环节,更多的前端业务来尝试应用 SSR 来实现前端首屏的疾速展示。
- 后盾治理平台场景:公司有很多的后盾治理平台的 Web 服务,它们尽管相较于函数是比拟重的,但齐全能够间接托管 Serverless 平台,充沛享受 Serverless 平台极致的公布和运维效率。
- 定时工作场景:公司存在很多周期性工作,如每隔几秒拉取数据,每天 0 点清理日志,每小时收集全量数据并生成报表等,Serverless 平台间接与任务调度零碎买通,只需写好工作的解决逻辑并在平台上配置定时触发器,即实现定时工作的接入,齐全不必治理机器资源。
- 数据处理场景:将 MQ Topic 作为事件源接入 Serverless 平台,平台会主动订阅 Topic 的音讯,当有音讯生产时,触发函数执行,相似定时工作场景,作为用户也只需写好数据处理的逻辑并在平台上配置好 MQ 触发器,即实现 MQ 生产端的接入,齐全不必治理机器资源。
5.2 落地收益
Serverless 的收益是非常明显的,尤其在前端畛域,大量的业务接入已是最好的阐明。具体收益,从以下两个方面别离来看:
- 降老本:通过 Serverless 的弹性伸缩能力,高频业务资源利用率能晋升到 40%~50%;低频业务函数通过合并部署,也能极大升高函数运行老本。
提效率:整体研发研发效率晋升约 40%。
- 从代码开发来看,提供齐备的 CLI、WebIDE 等研发工具,可能帮忙开发同学生成代码脚手架,聚焦编写业务逻辑,疾速实现本地测试;另外,让业务服务零老本具备在线查看日志与监控的能力。
- 从公布来看,通过云原生的模式,业务无需申请机器,公布、回滚都是秒级别的体验。另外,还能利用平台人造能力,配合事件网关,实现切流、实现金丝雀测试等。
- 从日常运维来看,业务无需关注机器故障、资源有余、机房容灾等传统模式该思考的问题,另外,当业务过程异样时,Nest 可能主动实现异样实例的隔离,迅速拉起新实例实现替换,升高业务影响。
6 将来布局
- 场景化解决方案:接入 Serverless 的场景泛滥,如 SSR、后盾治理端、BFF 等,不同的场景有不同的我的项目模板、场景配置,如伸缩配置、触发器配置等,另外,不同的语言,配置也有所不同。这无形中减少了业务的应用老本,给新业务的接入带来了妨碍。因而,咱们思考场景化的思路来建设平台,将平台的能力与场景强关联起来,平台深度积淀各场景的根本配置和资源,这样不同的场景,业务只须要简略的配置就能够将 Serverless 玩转起来。
- 传统微服务 Serverless 化:传统微服务的 Serverless 化即是路线选型中提到的面向利用的 Serverless 服务。在美团应用最广的开发语言是 Java,公司外部存在大量的传统的微服务项目,这些我的项目如果都迁徙到函数模式,显然是不事实的。试想如果这些传统的微服务项目不必革新,也能间接享受 Serverless 的技术红利,其业务价值显而易见。因而,传统微服务的 Serverless 化是咱们将来拓展业务的一个重要方向。在施行门路上,咱们会思考将服务治理体系(如 ServiceMesh)与 Serverless 做技术交融,服务治理组件为 Serverless 提供伸缩指标反对并在伸缩过程中实现精准的流量调配。
- 冷启动优化:以后尽管函数的冷启动优化曾经获得了较好的问题,尤其是平台侧的系统启动耗时,晋升空间曾经十分无限,但业务代码本身的启动耗时还是十分突出,尤其是传统 Java 微服务,根本是分钟级别的启动耗时。因而,后续咱们的冷启动优化会重点关注业务本身的启动耗时,争取极大升高业务本身的启动工夫。在具体优化办法上,咱们会思考采纳 AppCDS、GraalVM 等技术,升高业务本身启动耗时。
其余布局
- 丰盛欠缺研发工具,晋升研发效率,如 IDE 插件等。
- 买通上下游技术生态,深度融入公司现有技术体系,缩小因上下游平台带来应用阻碍。
- 容器轻量化,轻量化的容器可能带来更优的启动耗时以及更佳的资源利用率,因而,容器轻量化始终是 Serverless 的不懈谋求。在具体落地上,筹备联结容器设施团队一起推动容器中的一些 Agent 采纳 DaemonSet 形式部署,下沉到宿主机,晋升容器的有效载荷。
作者简介
- 殷琦、华珅、飞飞、志洋、奕锟等,来自基础架构部利用中间件团队。
- 佳文、凯鑫,亚辉等,来自金融技术平台大前端团队。
招聘信息
美团基础架构团队诚招高级、资深技术专家,Base 北京、上海。咱们致力于建设美团全公司对立的高并发高性能分布式基础架构平台,涵盖数据库、分布式监控、服务治理、高性能通信、消息中间件、根底存储、容器化、集群调度等基础架构次要的技术畛域。欢送有趣味的同学投送简历到:tech@meituan.com。
浏览美团技术团队更多技术文章合集
前端 | 算法 | 后端 | 数据 | 平安 | 运维 | iOS | Android | 测试
| 在公众号菜单栏对话框回复【2020 年货】、【2019 年货】、【2018 年货】、【2017 年货】等关键词,可查看美团技术团队历年技术文章合集。
| 本文系美团技术团队出品,著作权归属美团。欢送出于分享和交换等非商业目标转载或应用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者应用。任何商用行为,请发送邮件至 tech@meituan.com 申请受权。