开发函数计算的正确姿势——轻松解决大依赖部署

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
容器镜像服务 ACR,镜像仓库100个 不限时长
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 本文介绍了 Fun 通过内置 NAS(阿里云文件存储)解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上,解决函数计算对上传代码包大小的限制问题,而函数计算在运行时,可以自动从 NAS 读取到函数依赖。同时部署步骤简单明了,不需关心额外的配置,展现 Fun 工具对大依赖场景的顺滑体验。

前言

首先介绍下在本文出现的几个比较重要的概念:

函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息 参考buried_point
Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档 参考
NAS: 阿里云文件存储NAS是一个可共享访问,弹性扩展,高可靠,高性能的分布式文件系统。在函数计算的场景中,由于其有代码包的限制,可以使用 NAS 存放一些不经常变动的文件,比如数据模型、静态资源等。参考
ROS: 阿里云资源编排服务(ROS)助您简化云计算资源的管理。您可以遵循ROS定义的模板规范,在模板中定义所需云计算资源的集合及资源间依赖关系。ROS自动完成所有资源的创建和配置,实现自动化部署和运维。更多文档参考

备注: 本文介绍的技巧需要 Fun 版本大于等于 3.4.0。

基本上所有的 faas 平台为了优化函数的冷启动,都会加入代码包的限制。阿里云函数计算(FC)也不例外。FC 要求压缩后的代码包大小不超过 50MB。由于用户的函数代码可能需要大量的依赖库,所以代码包很容易达到函数计算设定的阈值。

传统解决方式

基于平台硬性要求下,依然有很多途径来解决函数计算上传代码包大小受限的问题。下面列举 3 种常见的解决方案。 备注: 包括不局限于以下方案。

1. 提交工单

提交函数计算工单,由后台人员为您账号开通上传限制白名单。但提交工单依然有代码包的限制。部署时代码包上传时间长,并且也增加了函数的冷启动时间,影响函数性能。PS:通过使用预留模式可以完全去除冷启动,由于超出本文范围,这里不再阐述。

2. 利用 OSS 来实现

对代码包进行分类,除项目代码和少量依赖库可以在创建函数时上传到函数计算,用户将部分依赖库预先上传到 OSS,并在函数被触发执行时开始从 OSS 上加载依赖, 这类依赖的加载操作均可定义应用层冷启动,当加载依赖结束后,应用层冷启动才结束,函数的处理逻辑才开始执行,应用层冷启动的开销往往会导致毛刺的产生,影响函数的性能。您可以将从 OSS 加载代码包的代码逻辑放在 initializer 函数中。既可以解决函数计算对上传代码包的限制问题,又不影响函数的性能。但需要用户进行额外的操作。参考使用 initializer 接口解决函数计算上传代码包大小受限问题

3. 基于文件系统 Nas

我们通过 NAS 存放一些体积比较大且不易变动的资源。这使得即使在依赖比较大的场景下依旧适用。NAS 在帮助函数计算解决大依赖问题的同时,由于其自身的配置也比较复杂,也增加了函数计算的使用难度。如何管理 Nas 资源、上传本地资源到Nas 以及服务级别的 Nas 相关配置参考开发函数计算的正确姿势 —— 使用 Fun NAS 管理 NAS 资源

本文旨在介绍第四种方式 -- 使用 Fun 工具来解决函数计算对上传代码包的限制,使得部署步骤简单明了,不需关心额外的配置。同时也展现 Fun 工具对大依赖场景的顺滑体验,Let's go!

:已经获得 fc 支持的 runtime 有 nodejs6,nodejs8,nodejs10,python2.7,python3,java8,php7.2,dotnetcore2.1,custom。目前基于所有 fc 支持的 runtime,大依赖场景下除 php7.2 和 dotnetcore2.1 其他都支持。

环境准备

Fun 安装教程 可以直接在这里下载二进制版本的 Fun,解压后即可使用。
执行 fun --version 检查 Fun 是否安装成功。

$ fun --version
3.4.0

Fun 判定大依赖的标准是什么?

fun install 是 fun 工具的一个子命令,用于安装 pip,apt 依赖等,提供了命令行接口和 Funfile 描述文件两种形式。对于 fun install 安装的依赖,当 fun deploy 部署时会自动处理大依赖。

当 Fun 检测打包的代码压缩后超过限制(50M),会根据对应的 runtime 分离大依赖和代码。Fun 会将大依赖目录分为:系统依赖和语言依赖。系统依赖的本地路径为 .fun/root,语言依赖根据函数 runtime 得到,各个 runtime 对应的大依赖目录映射如下:

语言(runtime) 大依赖目录(directory)
nodejs6 node_modules
nodejs8 node_modules
nodejs10 node_modules
python2.7 .fun/python
python3 .fun/python
java8 .fun/build/artifacts
custom /

自定义执行环境 custom 大依赖目录为 /,可以理解为其他 runtime 大依赖目录的合集。例如:函数 runtime 为 custom,若目录下存在 node_modules.fun/python 等,Fun 在部署向导过程中会把它们都认定为大依赖,会分别对其处理。

Fun deploy 对大依赖的支持

函数计算的命令行工具 Fun 现在原生支持了这种大依赖部署,不需要任何额外操作。仅仅执行 fun deploy

$ fun deploy

整体流程如下图所示:

image.png

fun deploy 会自动完成依赖的部署。而当检测到打包的函数目录超过了平台的限制时,会进入到配置向导,帮助用户自动化地配置。即上图可以理解为:Fun 通过内置 NAS(阿里云文件存储)解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。

大依赖向导

大依赖向导部分截图如下:

image.png

Fun 部署当前函数时,检测到压缩后(.zip)依赖超过了 50M,提示配置向导(后续日志省略...)。只需要输入回车或 yes 即可。最后 Fun 会自动完成配置,成功部署资源到函数计算。

体验升级

fun deploy 大依赖向导完成后,函数会部署到函数计算并对外提供服务。此时大依赖和代码通过 NAS 进行了分离,再次部署时打包本地代码目录时由于没有了大依赖,所以部署速度会非常的快。

这里推荐一篇使用 fun deploy 进行大依赖部署的实战案例,展示了 Fun 工具对大依赖场景的顺滑体验Serverless 实战 —— 快速开发一个分布式 Puppeteer 网页截图服务

Fun package 对大依赖的支持

Fun Package 是用来将代码、编译产物、静态资源等本地资源上传到 OSS 的功能。使用 fun Package 的场景,通常是,想仅仅通过一个模板文件进行部署的场景。比如,本地开发完成后,可以通过 fun package,将模板依赖的本地资源上传到 OSS,这样,无论是在其他服务器上部署,还是使用 ROS 部署时,仅仅通过一个文本格式的模板文件,就可以完成了。推荐阅读 Fun Package 功能介绍

非大依赖场景

流程如下图所示:

image.png

通过 Fun Package 可以将模板文件包含的本地资源一键上传到 OSS 上,完成资源的打包操作。

模版文件差异

将打包后的模板文件(template.packaged.yml)与原文件相比较,可以发现,差异仅仅在使用了本地资源的场景,比如:

- CodeUri: './'
+ CodeUri: 'oss://bucket/PackageDemo/function/39ce6e9109a23d313bc267b1a5211273'

大依赖场景

流程如下图所示:

image.png

当遇到打包的函数体积过大时,同样会进入大依赖向导,Fun 内置 Ros 的解决方案,帮你完成自动配置。同时 Fun 会分开大依赖和代码并分别上传到 OSS。这样做的目的下文中会有提到。

模版文件差异

大依赖场景下打包完成后生成的 template.packaged.yml 模版文件会与非大依赖场景下有所不同,除上述 CodeUri 的差异外,还会新增许多资源描述作为使用 Ros 部署时的前置条件,例如 NasCpFunc , 这里只介绍一种,其它不做赘述。

NasCpFunc:
  Type: 'Aliyun::Serverless::Function'
  Properties:
    Handler: index.cpFromOssToNasHandler
    Runtime: nodejs8
    CodeUri: 'oss://ellison-hongkong/9e610f5540e21ace83d5b742241da6aa'
    MemorySize: 3072
    Timeout: 300

NasCpFunc 为大依赖场景下 Fun 为用户内置的资源函数,可以将它理解为一个辅助函数。当用 Ros 方式部署时,将自动执行辅助函数。它用于实现从 OSS 上下载大依赖(.zip)以及解压到 Nas 的功能。这也就是为什么上述 fun pakckage 打包时,要将大依赖和代码分离开并分别上传到 OSS 的原因。

Fun Packge + Ros 部署实战

Serverless 实战——使用 Rendertron 搭建 Headless Chrome 渲染解决方案使用 Rendertron + 函数计算快速搭建一个可以直接用于生产的 Headless Chrome 渲染解决方案,以便于帮助网站更好的进行 SEO。基于文章,我们将升级文章中一键部署的体验。您可以参照上述文章中步骤,其中依赖安装项目编译等均无需额外操作。

Rendertron 项目代码依赖过大,基于 Fun 工具对大依赖项目的支持,现将其原 Fun deploy 部署改造为 Fun Packge + Ros 部署方式。Fun package 自动处理大依赖上传到 OSS,Ros 部署将大依赖从 OSS 解压到 Nas,同时模版中描述的资源自动创建成功。基于函数计算,项目的服务架构如下:
image.png

1. Fun pakcage

按照 RenderTron 文章中步骤操作,在一键部署前,执行 fun package 命令:

fun package --oss-bucket aliyun-ellison

这里的 --oss-bucket 名称为自己所拥有读写权限的 OSS 的 Bucket 名称。完整日志如下:

image.png

2. Ros 部署

ROS 通过 Transform 宏实现了将函数计算的模板语法转换为 ROS 支持的语法。这意味着对于 Fun 规范文档 里描述的语法规则,ROS 是同样支持的。同时,ROS 支持的资源 也能在 Fun 模板文件中进行声明了,比如 RAM、函数工作流 等等。

在体验上,由于 ROS 部署,要求资源必须“云化”。也就是没办法直接使用本地的代码资源。必须先通过 fun package 命令将资源上传到 oss。

可见这一步我们已经完成,不管是大依赖场景还是非大依赖场景,fun package 打包完成后,后续的部署操作,只需要完全基于这个打包后的模板文件(template.packaged.yml)即可。不再依赖本地的代码等资源,可以简化部署的难度。

最后将资源通过 ROS 的方式进行部署,推荐阅读开发函数计算的正确姿势 —— 使用 ROS 进行资源编排

fun deploy --use-ros --stack-name bucket-name

--stack-name 表示要部署的环境,可以基于该名称的不同,建立多套开发环境,比如 test、staging、prod。

3. 验证

可通过上述 RenderTron 文章中提到的方式验证,这里不做赘述。

常见问题梳理 FAQ

1. 大依赖被一个服务下的两个函数同时引用,Fun 是怎么处理的呢?

Fun 支持大依赖的场景是函数级别的,即当打包某一函数时发现超过限制才会进入向导。当两个函数处于相同 runtime 和 codeUri,Fun 会在结束第一次向导时,同时自动配置第二个函数,确保部署后,两个函数都部署成功且可用。

2. 大依赖自动配置后,如果我本地添加了新的依赖,部署时会自动将依赖更新到 Nas 吗?

不会。如果添加了新的依赖,比如 node_modules 目录添加了新的依赖库,需要在 template.yml 模版文件所在目录执行 fun nas sync,将本地 nas 资源同步到 nas 服务。如果修改了代码,只需要使用 fun deploy 重新部署即可。由于大依赖和代码通过 NAS 进行了分离,依赖通常不需要频繁变化,所以调用的频率比较低,而 fun deploy 的由于没有了大依赖,部署速度也会非常的快。

3. 为什么 java8 环境 Fun 支持大依赖的目录是 .fun/build/artifacts?

在很多场景,编译型语言从源码距离交付物其实是有一定的距离,比如 java,写完 java 代码后,还要考虑如何编译、打包的问题。Fun build 的职责就是完成从源码到交付产物的构建过程,推荐阅读 《开发函数计算的正确姿势 —— 使用 Fun Build 构建函数》
Fun build 会将编译打包后的交付产物 copy 到 .fun/build/artifacts 目录,在部署时检测到代码大小超过限制,自然会去 .fun/build/artifacts 下查找对应 serviceName/functionName 目录,并将所有的 jar 包上传到 Nas。所以 Fun 大依赖部署支持 java8 是以 Fun build 的场景为基础。未来 Fun 会集成更多的解决方案,敬请期待!

总结

Fun 通过内置 NAS(阿里云文件存储)解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。同时也展现 Fun 工具对大依赖场景的顺滑体验。

如果大家在使用 Fun 的过程中遇到了一些问题,可以在 github 上提 issue,或者加入我们的钉钉群 11721331 进行反馈。

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
17天前
|
人工智能 Java Serverless
阿里云函数计算助力AI大模型快速部署
随着人工智能技术的快速发展,AI大模型已经成为企业数字化转型的重要工具。然而,对于许多业务人员、开发者以及企业来说,探索和利用AI大模型仍然面临诸多挑战。业务人员可能缺乏编程技能,难以快速上手AI模型;开发者可能受限于GPU资源,无法高效构建和部署AI应用;企业则希望简化技术门槛,以更低的成本和更高的效率利用AI大模型。
84 12
|
1月前
|
算法 Serverless
通过函数计算部署ComfyUI以实现一个AIGC图像生成系统
快来报名参与ComfyUI活动,体验一键部署模型,生成粘土风格作品赢取体脂秤。活动时间从即日起至2024年12月13日24:00:00,每个工作日限量50个,先到先得!访问活动页面了解更多详情。
158 54
|
15天前
|
Serverless 开发工具 开发者
活动实践 | 西游再现,函数计算一键部署 Flux 超写实文生图模型部署
这些图片展示了阿里巴巴云开发者生态的多个方面,包括开发工具、技术文档、社区交流、培训认证等内容,旨在为开发者提供全方位的支持和服务。
|
27天前
|
监控 Serverless 云计算
探索Serverless架构:开发实践与优化策略
本文深入探讨了Serverless架构的核心概念、开发实践及优化策略。Serverless让开发者无需管理服务器即可运行代码,具有成本效益、高可扩展性和提升开发效率等优势。文章还详细介绍了函数设计、安全性、监控及性能和成本优化的最佳实践。
|
1月前
|
自然语言处理 搜索推荐 Serverless
基于函数计算部署GPT-Sovits模型实现语音生成
阿里云开发者社区邀请您参加“基于函数计算部署GPT-Sovits模型实现语音生成”活动。完成指定任务即可获得收纳箱一个。活动时间从即日起至2024年12月13日24:00:00。快来报名吧!
|
1月前
|
弹性计算 算法 搜索推荐
活动实践 | 通过函数计算部署ComfyUI以实现一个AIGC图像生成系统
ComfyUI是基于节点工作流稳定扩散算法的新一代WebUI,支持高质量图像生成。用户可通过阿里云函数计算快速部署ComfyUI应用模板,实现个性化定制与高效服务。首次生成图像因冷启动需稍长时间,之后将显著加速。此外,ComfyUI允许自定义模型和插件,满足多样化创作需求。
|
1月前
|
弹性计算 自然语言处理 搜索推荐
活动实践 | 基于函数计算部署GPT-Sovits模型实现语音生成
通过阿里云函数计算部署GPT-Sovits模型,可快速实现个性化声音的文本转语音服务。仅需少量声音样本,即可生成高度仿真的语音。用户无需关注服务器维护与环境配置,享受按量付费及弹性伸缩的优势,轻松部署并体验高质量的语音合成服务。
|
1月前
|
弹性计算 人工智能 自然语言处理
魔搭社区与函数计算:高效部署开源大模型的文本生成服务体验
在数字化时代,人工智能技术迅速发展,开源大模型成为重要成果。魔搭社区(ModelScope)作为开源大模型的聚集地,结合阿里云函数计算,提供了一种高效、便捷的部署方式。通过按需付费和弹性伸缩,开发者可以快速部署和使用大模型,享受云计算的便利。本文介绍了魔搭社区与函数计算的结合使用体验,包括环境准备、部署应用、体验使用和资源清理等步骤,并提出了改进建议。
|
1月前
|
监控 安全 Serverless
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
78 1
|
2月前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。

相关产品

  • 函数计算