一、企业应用及业务系统开发之痛
传统的企业应用开发过程中存在诸多痛点。比如业务逻辑层面的项目开发、部署、构建和维护,比如服务器使用层面的资源评估、服务器配置、服务器安全管控以及服务器运维等。
另外,从运维层面和成本支出层面,传统应用也都面临着效能与成本的双重挑战。比如持续的运行会产生能量的损耗,长期处于standby状态也会对企业的成本造成损耗。
企业开发的应用往往承载了企业的业务系统。架构选型方面,市面上技术产品和架构理念繁多,需要选择合适的新技术以实现业务快速创新;其次,分布式系统技术复杂,真正投入使用需要较高的学习成本和运维成本,比如集成微服务时如何治理流量、如何控制底层的弹性资源,同时会对业务带来极大的挑战;最后,技术组合集成度不足,缺乏整体规划和一体化端到端的方案。
购买种类繁多的资源也会影响业务系统构建的效率,资源、网络、流量治理、架构设计、资源运维、可观测性、运行时的适配、多语言或任务调度等都会成为研发效能的阻碍。
Serverless能够助力企业从技术升级到降本提效。
那么,Serverless是什么,它做了什么,它能做什么?
Serverless的核心理念有三:按需付费(成本层面)、无服务器运维(DevOps 层面)、极致弹性(基础设施层面)。
早期,Serverless主要依靠极致弹性引领业界的探索。而现在,Serverless要真正落实到解决企业业务系统问题的层面。
Serverless倡导片段化的编程,只关心业务代码,整个结构较为敏捷。平台搭建好上下文,开发者只需做代码的开发,即可快速得到产出,极大提高了开发者的效率。
通过Serverless,可以实现分钟级落地一个中型业务系统,快速完成线上POC,拥有100ms极致弹性,帮助在线业务应对各种突发流量,资源交付能力极强。虽然函数计算的冷启动问题无法避免,但我们也在通过不断迭代尽量解决该问题。此外,资源利用率可达100%,按请求计费,1ms计算粒度,只需为实耗资源买单。
此外,基于函数计算系统构建自己的业务系统,在大层面上,依然需要平台化的运维,免运维仅限于函数计算层面。
Serverless的降本适用于潮汐流量明显的场景,没有明显波峰波谷的业务场景则需要长时间才能得到较好的降本效果。
二、Serverless系统开箱即用的原子化能力
秒杀或在线视频直播活动的一大特点是流量不确定,因此底层必须要有弹性供给资源的能力,而这与启动业务的弹性能力是两个维度。代码的启动主要体现在RT 层面,资源的弹性主要体现在 QPS 层面。
运行一段代码往往需要经过几个阶段,比如下载代码、启动容器、运行时初始化、函数初始化、函数执行等。我们对函数计算进行了优化,实现了百毫秒的启动。
系统侧,为了避免资源重新创建,使得相同租户或函数下资源能够被重复利用,我们实现了实例资源池化以及实例并发预测,通过内存的镜像快速提供通用化的模板。网络方面,为了与用户的 VPC打通 ,提供了即插即用的 VPC 优化方案,快速将网络能力插到函数的运行实例上。最终,函数的执行、profiling 能力以及加速能力将反馈在后续的运行上。
只有每一次业务的请求处理都有效,才能最终反映在整个业务的效能提升上 。Serverless 作为事件驱动型,需要帮助系统与各个数据类的云产品打通,比如 API的网关、Kagka、日志等。打通数据源后,可以利用事件驱动的方式处理沉淀在产品中的数据,最后在函数计算中对数据进行利用,实现系统的业务目标。
除了数据类的产品,研发运维的客户可能关心 ECS 是否磁盘满、云监控是否有问题以及 VPC创建等运维相关事件,同时也希望能够利用运维事件主动调用其他云产品的 SDK 以创建相关资源。
可以通过EventBridge将阿里云的云产品对接到函数计算,基于事件做运维操作。
企业业务系统里最常见的消息中间件是系统解耦的产品。写业务消息的消费端非常容易,而用函数计算去消费是为了让 pull 消息通过平台的服务化能力之后,实现后端的业务消息处理的资源弹性。没有消息来时,函数计算的资源可以进行回收,无需计算费用。
整个函数计算实现了无状态的消费消息能力,类似响应式的模式,有状态的部分由平台的触发能力提供,无状态、与业务相关或自定义的部分沉淀到函数里,保证了业务的自定义,同时也保证了资源的响应式形式。
普通的应用网关通常需要买服务器、写代码、写线程池,以上流程中存在诸多问题需要解决:买多少台机器?每一台机器上运行时的线程池并发为多少?
而函数计算场景下,异步任务处理的请求可以打到Async Service,通过它并发地调度请求。函数类似于无限容量的线程池模型,会进行托管请求,请求可靠执行,能够保证 at least once 的执行。申请函数的弹性配置时,能够进行流量控制。另外,提供了执行管理,可查看每个阶段的执行情况,或在执行过程中取消任务。
执行完毕后,提供了服务化的结果,无需写额外函数,可将结果投递到下一个函数或消息队列等,以便无关的松耦合产品对结果再做进一步处理。
Serverless提供了系统开箱即用的观测性能力,可以查看请求执行的 RT 、 CPU 利用率、内存的使用情况、调用链每个阶段的耗时等。
三、企业如何利用Serverless快速扩展自己的业务系统
企业在扩展自己的业务系统过程中会面临一个问题:是否需要将全量业务迁移至Serverless。如果是较为精简的业务系统,全量迁移可行;而如果是一个多年积累较为庞大的业务系统,则需要对其进行解构,将部分能力迁移至Serverless。针对后者,如何将请求通过松耦合的方式offload 到函数计算?
首先,可以通过HTTP Restful的方式访问函数(事件函数目前暂不支持,后续计划支持URL的访问)。另外,可以投递到 OSS 或消息队列等,由 DB 的松耦合解耦触发下游的业务系统。
业务系统还需要有运行的上下文,可以按照函数计算的 spec 写编程规范,也提供了镜像或自定义 runtime 的方式,将原先的镜像运行在函数计算上(需进行容器化改造)。运行的上下文不变,只是将底层的计算资源移至函数计算。
系统解构时,建议按照以下原则进行。
第一,剥离任务类处理业务逻辑,将其挪至函数计算,可以利用 SDK 、HTTP、定时触发器或事件驱动的提交方式让任务在函数计算上执行,可以实现函数计算按需付费或开发的方便性,对原先的业务系统也没有过多侵入。
第二,剥离 MQ 的业务消息处理类逻辑,利用事件驱动进行业务消息处理即可。
第三,剥离文件类业务逻辑,利用 OSS 事件驱动的方式快速处理,生产完之后将其存在 OSS 上即可完成整个流程,无需再写额外的系统。
第四,剥离轻量级数据处理类业务逻辑,利用Serverless ETL 能力将其投递到下游系统比如 OSS、ElastisSearch、RDS等。
四、企业使用Serverless系统面临的困境解析
企业进行迁移升级,其主要驱动力有三个方面:业务驱动,架构升级;效能驱动,技术升级;降本驱动,技术改造。
而迁移过程中,企业将要面临的困境主要有以下几个方面:
第一,迁移改造难度大,需要适配函数计算的编程规范和运行时要求。
第二,函数运行存在最大时长限制,对存量业务迁移不友好。
第三,函数计算请求模型与传统应用差异较大,并发概念难以理解。函数计算提供了两种方式,分别为一个请求一个实例以及单实例多并发。
第四,计算实例对用户透明,错误处理、问题排查难度大。
第五,计费模型复杂、难以理解,担心费用不可控。
第六,冷启动问题。目前链路延迟为3-5ms。
五、客户场景案例分享
案例一:分众传媒广告效果识别
分众自研了图片识别处理系统。工作人员更换海报后,可通过APP拍照上传至后台服务器。周末为更换高峰,流量峰值与平日相差10倍以上。
案例二:IOT监控视频回传方案
消费电子行业 IoT 的监控视频回传至 OSS,OSS 需要通过函数计算快速处理,截取文件内容等,再将处理结果与业务系统串联,日均调用量约 8w+QPS 。
案例三:微博海量图片处理
微博的海量图片处理主要利用函数计算对图片进行快速处理,利用毫秒级的弹性伸缩,通过事件驱动的模型处理图片。
案例四:直播推流之内容审核
互娱行业的直播推流需要实现在线视频、视频互动的实时、节帧地进行安全审核或鉴别,可以通过函数计算实现。
案例五:客户端数据流式处理分析
游戏行业的数据产生完之后上报到kafka的消息队列,需要用kafka的 ETL 能力进行处理。
案例六:卡牌游戏战斗结算
卡牌游戏场景下,每次战斗完才有计算发生,也非常适合使用Serverless。
案例七:游戏发行渠道打包方案
游戏发行渠道打包的场景,通过事件驱动实现。
案例八:车联网平台
车联网平台从端上采集完数据之后传到Kafka或RabbitMQ 再进行处理。
Q&A
Q:GPU 容器的冷启动时间大约是多少?
A:容器的启动时间与 GPU 里的 reference model size 有关,比如是 3G 的自定义镜像,缓存加速大约为2秒;如果里面还有十几兆文件,可能需要 10-30 秒。
Q:将服务迁移到函数计算上,希望借助Arthas工具查看运行情况,是否可行?
A:目前暂未支持Arthas。Java的动态注入能力相对较强,因此很容易实现Arthsa的支持。而函数计算是多语言的,因此难以针对 Java 或微服场景专门在观测性或诊断上提供支持。后续往 web 场景适配可能会实现Arthas的支持。
Q:微服务场景直接挪到函数计算,是否合适?
A:不合适。在 lambda 架构里通常需要 gateway 再加上 method 角色会更适合。我们针对快捷的web提供了HTTP函数,同时也提供了 URL 或自定义域名,相对比较长尾,因此也较为适合函数计算。而如果是高频的请求,则不适合直接搬运使用。需要先配置gateway的能力,同时配合 method 的调用(method调用不均衡,有些方法比较高频,有些比较低频),提供服务的完整能力。
在并发度上可以用单实例多请求的方式,将冷启动平均的启动耗时降低,因为大部分请求都在一个实例上。