Lambda是AWS推出的基于Function-as-a-Service(FaaS)的Serverless服务。我结合项目使用体验,发现Lambda不适合或者说不能独立支撑以下场景:
与此同时,Lambda和其它AWS服务结合起来能为以下场景提供良好的解决方案:
Lambda仅支持单请求模式,可以考虑使用AWS的App Runner或者GCP的Cloud Run替代。
笔者参与的项目大量使用Lambda进行开发,Lambda所承担的角色包括:作为AppServer支撑前端功能、监听第三方系统的Webhook,作为后台程序执行批处理任务,等等。在使用过程中,笔者感觉Lambda并非万能良方,有其设计和功能上的限制,所以根据项目的使用情况和体验,梳理了Lambda适合和不适合的场景,分享给大家,供大家在技术选型时进行参考。
Lambda作为一种Serverless的计算服务,一个很重要的特点就是按需创建实例,即在请求到来时创建实例来处理(冷启动)。当实例处理完成请求后,会保留一段时间,可以响应后续请求(热启动)。如果实例空闲超过一段时间,就会被Lambda回收(AWS未明确提及回收的等待时间)。AWS官方没有给出状态的标准名称,我们这里用非标准的术语来描述生命周期,如下图:
Lambda的函数有同步和异步两种执行模式。在同步模式下,当我们执行函数时,Lambda会创建/复用实例,并等待实例执行完成后再返回结果;在异步模式下,Lambda会将请求加入队列并立即返回,然后在后台创建/复用实例进行处理。使用异步模式时可以设置重试次数,并且如果重试后仍然不能成功,可以通过设置将失败的请求发送到另外的地方,比如SNS的Topic。
很多AWS服务都能与Lambda进行集成,需要查文档来明确调用Lambda的方式,比如API Gateway是以同步模式调用Lambda,CloudWatch Event是以异步模式调用Lambda。
基于Lambda的生命周期,当有请求需要处理时,如果此时无可用实例,Lambda会初始化一个新实例并使用,也就是冷启动。结合Lambda单请求模式的特点,意味着一定会出现相当数量的冷启动,请求的响应时间会掺杂着实例初始化时间,出现延迟的波动。以项目经验来看,一个不复杂的NodeJS实现的函数,启动时间大概在1-3秒区间内波动;这个区间数值来自于CloudWatch的日志输出,实际体感时间可能更长,这部分时间会直接暴露给调用方。所以当一个场景需要提供持续稳定的低延迟响应时,以同步方式调用Lambda并不合适。
顺带一提,实例的启动时间是很重要的,如有些传统Java应用启动就需要几分钟的,建议不要直接放上Lambda。
如果一个请求需要以同步的形式在多个实例中跳转,在最坏情况下,会成倍放大请求的延迟,并且成倍消耗并发数量。以项目经验为例,有一个API Gateway -> Function A -> Function B -> 第三方系统的访问链路,在测试环境(用的人少,流量波动大)中,从页面调用这个接口的时间基本上在8秒以上,有时会超过10秒,让客户怀疑系统的性能有问题。
以网状结构设计的微服务模式应用,服务之间需要频繁同步通信,放上Lambda需慎重。
如果一个接口有大量的调用,那么基于Efficiency和Cost的考虑,Lambda未必是合适的选择。
从一般性原则来讲,如果一个接口存在大量调用,那么为每次调用分配一个独占的实例显然不是一种明智的选择,这样会显著放大单个实例的边际开销。这种情况下,增加单个实例同时能处理的调用数量,能够有效提高系统吞吐量,提升系统的整体效率。
从价格方面来考虑,Lambda使用的是基于调用次数计费的模型,当调用次数增长到一定的阈值以上,其成本有效性必定会低于基于使用资源时长计费的模型。让我们用一个虚拟的场景来对比Lambda和App Runner:假设有一个接口,每天有3个小时的繁忙时段处理600 RPS的调用,另有12个小时非繁忙时段处理60 RPS的调用,其余时间没有调用;每次调用持续时间500ms。两种服务的价格对比如下:
很多第三方系统提供Webhook来进行通知,并且一般Webhook的设计都是异步模式。这种场景可通过API Gateway,SQS和Lambda提供解决方案。
让我们按照AWS的5 Pillars来分析为什么这是一个良好的解决方案:
有时候一个任务需要等待一段时间之后才执行,或者到了一个特定的时间才执行,相比用一个Long-run的服务去定时扫描处理,Step Functions、SQS加上Lambda提供了一种更高效的解决方案。
前述的优点不再重复提及,这里补充一些对Step Functions的说明。Step Functions是AWS提供的Serverless的状态机服务,其中包含了等待的状态,最长可等待1年的时间;AWS保证了等待的可靠性。Step Functions结合Lambda,可以针对单个任务去设置处理时间,不再需要批量扫描处理任务。Step Functions按照状态变化收费,等待时状态并没有发生变化,无需付费,可有效降低费用开销。
Serverless的特性决定了实例无法避免冷启动。Lambda支持同步和异步两种调用模式,以项目经验来看,同步调用模式受冷启动影响更大,有时会通过SQS将调用封装成异步模式。在Serverless工具中甚至提供了Serverless WarmUp Plugin插件,通过定时调用避免冷启动。AWS也提供了Provisioned Concurrency特性来维持热实例,减少冷启动的次数。
Lambda的单请求模式是一个很大的限制,既限制了实例的性能(比如使用NIO),又导致实例需要更频繁初始化。如果能够改变单请求模式,让一个实例接受更多的请求,将会是一个很好的特性。
Lambda有一套独立的生态系统,对代码和部署都有特定的要求,降低了代码可移植性。
有没有更好的选择呢?笔者推荐读者参考下GCP的Cloud Run服务,提供了Container-as-a-Service(CaaS)解决方案,能够将镜像以Serverless形式部署上去,通过指定实例的请求并发度,能显著减少初始化新实例的次数。AWS也提供了类似的服务App Runner,不过目前只在美国、爱尔兰和日本区域提供。
分享标题:什么场景(不)适合使用Lambda
标题路径:http://www.shufengxianlan.com/qtweb/news44/329294.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联