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

前言

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

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

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

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

传统解决方式

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

1. 提交工单

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

2. 利用 OSS 来实现

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

3. 基于文件系统 Nas

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

本文旨在介绍第四种方式 -- 使用 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 其余都支持。php7

环境准备

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 工具对大依赖场景的顺滑体验。

查看更多:https://yqh.aliyun.com/detail..._content=g_1000106761

上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/