为什么选择 Serverless
早期,高德将所有资源和逻辑都置于端侧,因此它是一个重端App。它在端上依赖于厂商,更新时会涉及到发版。业务变化快,但迭代很慢,迭代生命周期长,因而导致用户体验受损。且代码堆积量很大时,测试成本非常高。因此,很小的改动会引起很多大的变化。因此,客户端瘦身迫在眉睫。
此外,低电量和端云一体化也是大势所趋。最终,为了加速迭代,强化用户体验,让出行变得更加美好,我们决定对架构进行调整。
Serverless的第一个特点为环境统一。早期的容器化为硬隔离,而硬隔离带来的问题在于环境的统一需要通过模板实现,构建模板时间很长,因此无法在短期内做变更。且需要维护多套模板,运维成本非常高。
此外,在环境统一的情况下,依赖的系统底层版本如何维护也需要解决。容器的实现较为简单,但过程比较复杂,它依赖于安全级别隔离、CG group、NameSpace,依然需要构建一套自己的环境。
Docker实现了软隔离,有了Docker后,可以通过编排将线上环境搬到本地,通过 IDE 和 Docker 的挂载将线上环境完整地带到本地,实现环境统一。而环境统一之后带来的好处在于运维更安全、更方便,可以通过镜像直接拉起容器。同时,镜像还可以带来弹性伸缩的能力。
另外,Serverless能够根据业务的潮汐流量特点实现按需付费,节省成本。
Serverless的架构多样化也与我们的业务需求相符。它提供了BaaS、FaaS(粒度较小的函数,只代表请求中的点)、Sff(serverless for front)以及Bff(Backend for front),其中SFF和Bff主要解决前端流量后端化的问题。
👉函数计算 FC :https://www.aliyun.com/product/fc?
我们将端和云区分开,将端上的计算和功能去放在云上,变为云端一体化。早期开发阶段的网关层基本为 API、Gateway等聚合模式,通过路由将接口聚合在一起再返回内容。随着服务越来越多,一个小的改动可能会对链路带来很大问题,测试成本也很高。
而现在,我们通过Serverless替代了这一层,从端请求到云上运行FaaS 函数,将单一的点拆解后运行,可以根据实际流量自动扩缩,无需担心下线或改动影响服务状态。
未来,我们会将大量计算放在云端,使客户端越来越小,性能越来越快,不仅能够实现端云一体化,还能实现产研同频,加快产品迭代速度。
解决了架构问题后,我们还需面临运维成本较大的问题。Serverless架构的免运维仅仅面向容器和函数,每个场景、每个流程的运维依然需要通过体系化的模式来构建,需要完善的CICD。
CICD解决了可观测性和隔离性。可观测性主要用于快速发现问题,包括日志收集、鹰眼、监控等。随着架构的升级,其粒度越来越小,服务治理和环境治理的成本越来越高,可观测性的重要性也日益凸显。
代码管理方面,底层的机制保证了 tag 和代码管理可以走不一样的流程。通过代码管理发布到环境,通过环境隔离的角度进行验证,验证后再通过权限手段控制安全性,并通过环境的隔离实现了安全模式。
完善的 CICD保证了产品的高效迭代,并且降低了试错成本。
有了完善的CICD后,即可进行通用型FaaS的平台架构设计。不同的团队之间相互调用FaaS,SFF 通过调前端的 FaaS 进行请求,解决了 API 聚合问题。业务场景往下是网关和端上 FaaS(自己写逻辑),再往下是业务层,业务层存在相互的之间调用、填充,最终到业务FaaS。
FaaS的周期通过Runtime 进行约束。该套Runtime 设计可以实现小时级的FaaS 开发部署。
架构分为四层,最上层为User Faas,通过 Runtime 叠加自己的逻辑即可;第二层为FaaS SDK ,上行流量和下行流量需要有统一的标准,否则会导致用户不稳定;第三层为Runtime,实现并封装了很多协议,比如长链接协议用于做中间件对外的代理,使用时只需要将 Runtime 引入即可;最底层为FC 函数引擎, FaaS 最大的缺点在于冷启动需要加载状态、实例等,会耗费大量时间,而有些状态可以进行屏蔽,基于此,FC对其进行了优化,可以预留实例,实现秒起。
以上流程可以理解为有了一个 web server 入口来实现函数,再通过平台调度,通过 CICD 流程发布,最终实现高效的迭代。
稳定性保障负责保证日常情况下的函数维护。上线三板斧分别为可灰度、可监控、可回滚。Serverless架构较轻,可以通过version控制其上线流程。比如优化前后的版本分别为version1和version2,可以通过不同的流量机制进行分流,版本可随时增加,增加版本时老版本依然可以正常运行。
可观测性方面,可以通过完整的日志链路挖掘问题,也提供了智能化手段帮助发现业务问题。
预留实例解决了冷启动问题,避免了冷启动对请求时长的影响。完备的流程化链路排查机制指可以在日志上打标签,通过日志在流程上快速挖掘问题、定位问题以及大促保障等。
Serverless在高德的落地场景包括但不限于以上四个,能够保证弹起、开发较快,通过配置化保证卡片可以快速上下线。
FaaS带给我们的最终收益是降本提效,主要体现在以下三个方面:
- 开发提效:Bff&runtime加速开发,快读迭代业务。
- 运维提效:完备的生命周期,完全的弹性。
- 降低成本:潮汐流量,按需计费。
Q&A:
Q:使用Serverless开发相关的功能时,功能的粒度拆分特别细。比如用户请求进来,可能后端有十几个 Serverless相互调用,而Serverless之间的调用延时比较大,如何进行优化?
A:使用异步请求方式,然后汇总元组,将元组再进行解析。它依赖于最大短板,在工具上我们实现了timeout,以异步和超时的方式对不必要的长耗时请求进行快速拦截,进行汇总并最终返回至端上。出于业务上的考虑,我们没有对长耗时请求直接熔断。
Q:函数本身执行速度较快,但函数之间的调用耗时较长,应如何解决?
A:需要平台解决。我们目前把它看作正常请求,暂未对该问题进行优化。此前,我们曾对另一种模式进行过优化,依赖于平台提供函数的路由,在资源重用和调度上做了很大优化。此外,在调用平台时,平台与函数之间的协议沟通也尤为重要,比如慢连接时如何沟通、滑动窗口满了后如何沟通。gRPC可以保障某一时刻不会过慢,但启动的初始阶段依然耗时较长。
🌏更多内容关注 Serverless 微信公众号(ID:serverlessdevs),汇集 Serverless 技术最全内容,定期举办 Serverless 活动、直播,用户最佳实践。