函数计算|如何使用层解决依赖包问题?

2天前 (02-14 12:22)阅读1回复0
zaibaike
zaibaike
  • 管理员
  • 注册排名1
  • 经验值172455
  • 级别管理员
  • 主题34491
  • 回复0
楼主

> 在利用阿里云函数计算平台时,若是您曾经碰到过以下问题,本文应该会对您有所帮忙:

> 1. 第三方依赖包太大,每次更新代码都十分耗时,以至会呈现超越代码包限造的情况,我该怎么办?

> 2. 安拆第三方依赖包后,能够在当地运行胜利,上传到阿里云函数计算平台上就会报错,那是什么情况?

> 3. 有良多常用的依赖包,良多用户应该城市用到,阿里云函数计算官方不克不及间接内置到运行时情况中么?

> 4. 我在多个函数中有不异的依赖包,我该若何办理那些不异的依赖包?

**层**供给了集中办理,跨多个功用且可以共享代码和数据的办法。

2021年1月,阿里云函数计算发布了** “自定义层”**功用,让用户能够自定义层,并撑持跨函数共享。2022年8月,阿里云函数计算发布**“公共层”**功用,供给了官方公共层,供用户间接利用,进一步提拔了用户体验。

接下来先介绍“自定义层”的功用和感化。

# 自定义层

在层功用发布之前,必需将代码与代码的依赖项一路打包和摆设,那些依赖项在差别函数中可能是不异的,良多情况下那些依赖项的大小,远远大于代码的大小。

在层功用发布后,我们能够将代码的依赖项,或者多个函数中共享的部门打包成 Zip 压缩文件,并做为函数计算的自定义层发布,差别函数都能够利用该自定义层。阿里云函数计算会在挪用时将层与函数代码一路加载。可参考文末文档 [1] [创建自定义层](创建自定义层_函数计算-阿里云帮忙中心) [2][在函数中设置装备摆设自定义层](若何在函数中设置装备摆设自定义层_函数计算-阿里云帮忙中心):

## 为什么利用自定义层?

利用自定义层有以下优势:

### 跨函数复用代码

将多个函数中的通用代码或数据提取出来,打包成 Zip 包,做成自定义层,供差别函数引用,制止了在多个处所维护通用的代码或数据。

与此同时,也实现了依赖项和营业逻辑的别离,用户能够专注于核心的营业逻辑。

### 使代码包更小

函数的代码包越来越大时,摆设速度也会越来越慢,招致函数的维护和测试愈加困难。

此外函数代码包大小也有限造,好比阿里云函数计算的代码包限造为 500MB (2022年9月),**层是打破该限造的办法之一**。层也有大小限造,目前单个层的代码包大小限造为 500MB,单个函数最多可设置装备摆设5个层,总大小不克不及超越 2GB。

### 加速代码摆设,简化函数办理

函数代码包越小,代码包的摆设就越快。尤其是一些大型依赖项时,核心功用代码可能只要几兆字节,但依赖项可能有几百兆。好比 Puppeteer 依赖包超越100MB,阿里云的 DataX 依赖包超越 800MB。

一般来讲,那些依赖项很少修改,因而将他们打包成层后,能够制止在核心代码修改时频繁修改那些大型依赖项。对那些依赖项也能够拆分红多个层,每次修改一个功用时,只需要更新此中一个层。好比我们实现了自定义运行时 Python3.10 以及该运行时兼容的科学计算库 SciPy,能够将自定义运行时和依赖包拆成两个层,当需要更新依赖包时,只需要更新依赖包的层,而自定义运行时的层连结稳定。

## 自定义层的窘境

### 造做层有必然门槛

**层的 Zip 包有必然的格局标准,用户需要根据该标准停止造做。**以 Python 的 requests 库为例,依赖打包后的文件构造为:

```bash

my-layer-code.zip

└── python

└── requests

```

为什么有那种要求呢?那个涉及到差别运行时在搜刮第三方依赖包的实现逻辑,以 Python 为例,Python 运行时会在 `sys.path`途径下搜刮依赖包,上面的 Zip 包会解压到函数实例的 `/opt`目次下,解压后 `requests`那个包就放到了 `/opt/python`目次下。

然后,函数计算平台会将一些特定的目次放到运行时语言的依赖搜刮途径上,好比 Python 运行时就会将 `/opt/python`放到 `sys.path`中,如许,代码中就能够间接引用`requests`库了。其他运行时的利用办法可参考文档 [创建自定义层](创建自定义层_函数计算-阿里云帮忙中心)。

当然,你也能够不根据那个格局标准来造做层,此时就需要在代码中添加对应的搜刮途径了,详细办法可参考文档:[若何在Custom Runtime中引用层中的依赖?](CustomRuntime内各语言引用层中依赖的办法_函数计算-阿里云帮忙中心)

**需要在指定操做系统和处置器架构下造做层。**有一些依赖是与操做系统和处置器架构有依赖关系的,好比 Python 的科学计算库 NumPy,假设你在 M1芯片的 MacOS 下安拆,其版本为

```bash

numpy-1.23.3-cp39-cp39-macosx_11_0_arm64

```

可看到兼容的操做系统为 `mac os`, 处置器架构为 `arm64`。但在函数计算平台的实例情况为 `Linux x86_64`,操做系统目前利用的发行版为 `Debian 9`,因而在 M1 Mac下安拆的 NumPy 库不克不及在阿里云函数计算平台利用。

我们保举在 `Debian 9`系统下停止安拆,但用户当地可能没有该情况,您能够利用 **在线构建依赖库 **或者利用函数计算官方运行时镜像来构建,此处不再赘述。

**层需要包罗新增的共享动态库。**有些依赖库需要安拆额外的共享动态库,在构建层的 Zip 包时也需要包罗那些共享动态库。例如 Nodejs 的依赖库 Puppeteer,需要额外安拆二十多个共享动态库(如 libxss1,libnspr4 等),那些依赖库都要打包到层 Zip 包中。若何胜利的安拆 Puppeteer 库并非简单的工作。

共享动态库保举放到 Zip 包的 lib 目次下,函数计算平台会将`/opt/lib`目次添加到 `LD_LIBRARY_PATH`(仅限于内置运行时)。

### 无法跨账号共享

自定义层默认只能在同账号同地区的差别函数之间共享,无法停止跨账号共享。因而,用户A创建的自定义层无法给用户B利用,那不只给用户带来了反复的工做量,也倒霉于宿主机上不异层的复用。

# 公共层

因为自定义层的那些痛点,阿里云函数计算在2022年8月发布了公共层功用。实现层跨账号共享,并供给了一些 [官方公共层](若何通过控造台和ServerlessDevs在函数中设置装备摆设官方公共层_函数计算-阿里云帮忙中心) 供用户间接利用,便利用户快速开发示例原型。

阿里云函数计算平台次要供给了三类官方公共层:

- 自定义运行时(如 Python 3.10、Nodejs17、PHP 8.1、Java17、.NET 6等)

- 常用依赖库 (如 PyTorch、Scipy、Puppeteer等)

- 阿里云SDK (如 Aliyun DataX )

详情可参考官方文档 [在函数中设置装备摆设官方公共层](若何通过控造台和ServerlessDevs在函数中设置装备摆设官方公共层_函数计算-阿里云帮忙中心) ,目前官方公共层仍在持续弥补,若是您有需要的运行时或者依赖库想通过官方公共层的体例利用,可通过[钉钉答疑群](函数计算的钉群入口_函数计算-阿里云帮忙中心)(钉钉群号:11721331)与我们联络,也能够间接在 [github.com/awesome-fc/awesome-layers](https://github.com/awesome-fc/awesome-layers)** **提交 issue**。**

## 若何公开自定义层?

目前,层公开功用在内测中,若有需求欢送通过[钉钉答疑群](函数计算的钉群入口_函数计算-阿里云帮忙中心)(钉钉群号:11721331)联络我们。将自定义层公开的办法请参考 [github.com/awesome-fc/awesome-layers](https://github.com/awesome-fc/awesome-layers)。

同时,我们也十分欢送各人奉献公共层到仓库 [github.com/awesome-fc/awesome-layers](https://github.com/awesome-fc/awesome-layers),我们很快会在该仓库供给公共层奉献的办法和示例。

# 示例展现

官方公共层的最新版本和利用申明可参考 [github.com/awesome-fc/awesome-layers](https://github.com/awesome-fc/awesome-layers)。下面介绍一些利用官方公共层的典型示例。

## 示例一、基于 Nodejs16 + Puppeteer 实现网页截图示例法式

Puppeteer 是一个 Nodejs 库,它供给了高级的 API 并通过 DevTools 协议来控造 Chrome(或Chromium)。通俗来说就是一个 headless chrome 阅读器,能够利用它完成良多主动化的工作,好比:

- 生成网页截图或者 PDF

- 做表单的主动提交、UI的主动化测试、模仿键盘输入等

- more...

本示例利用 Puppeteer 完成一个网页截图示例法式。

起首,我们利用内置运行时 Nodejs16 创建一个函数 start-puppeteer,此中**恳求处置法式类型**选择“**处置 HTTP 恳求**”。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664378536975-f5f66daf-64a5-4fa7-8900-5b34d5912344.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=448&id=ue4a51c82&name=image.png&originHeight=1440&originWidth=2972&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1576772&status=error&style=shadow&taskId=ua409ea36-7994-4da6-8b38-0ef24f1f48b&title=&width=924)

然后,在高级设置装备摆设中将内存规格设置为 `1GB`,示例法式的内存利用大要在`550MB`摆布。

创建胜利后,在控造台上翻开 `index.js`文件,将下面的代码拷贝并笼盖该文件,点击摆设按钮。

```javascript

const fs = require(fs);

const puppeteer = require(puppeteer);

function autoScroll(page) {

return page.evaluate(() => {

return new Promise((resolve, reject) => {

var totalHeight = 0;

var distance = 100;

var timer = setInterval(() => {

var scrollHeight = document.body.scrollHeight;

window.scrollBy(0, distance);

totalHeight += distance;

if (totalHeight >= scrollHeight) {

clearInterval(timer);

resolve();

}

}, 100);

})

});

}

module.exports.handler = function (request, response, context) {

console.log(Node version is: + process.version);

(async () => {

const browser = await puppeteer.launch({

headless: true,

args: [

--disable-gpu,

--disable-dev-shm-usage,

--disable-setuid-sandbox,

--no-first-run,

--no-zygote,

--no-sandbox

]

});

let url = request.queries[url];

if (!url) {

url = Serverless 应用全生命周期办理;

}

if (!url.startsWith(https://) && !url.startsWith(http://)) {

url = http:// + url;

}

const page = await browser.newPage();

await page.emulateTimezone(Asia/Shanghai);

await page.goto(url, {

waitUntil: networkidle2

});

await page.setViewport({

width: 1200,

height: 800

});

await autoScroll(page)

let path = /tmp/example;

let contentType = image/png;

await page.screenshot({ path: path, fullPage: true, type: png });

await browser.close();

response.setStatusCode(200);

response.setHeader(content-type, contentType);

response.send(fs.readFileSync(path))

})().catch(err => {

response.setStatusCode(500);

response.setHeader(content-type, text/plain);

response.send(err.message);

});

};

```

简要介绍一下上述代码的核心逻辑,起首代码会解析 query 参数获取需要截图的 url 地址(若是解析失败则默认利用 Serverless Devs 官网主页),然后利用 Puppeteer 对该网页停止截图,并保留到运行实例的 `/tmp/example`文件中,然后将该文件做为HTTP恳求的返回体间接返回。

然后,我们需要设置装备摆设 Puppeteer 公共层,在**函数设置装备摆设**中找到**层**,点击编纂,选择**添加官方公共层。**

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664379716421-80f145b8-d3ee-4d4f-a382-92c15eccb918.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=297&id=u587c7e88&name=image.png&originHeight=682&originWidth=1996&originalType=binary&ratio=1&rotation=0&showTitle=false&size=517069&status=error&style=shadow&taskId=uc4d7f1e9-03fa-47af-ade5-e833ce98fb0&title=&width=870)

选择官方公共层 Puppeteer17x,目前最新的层版本为1。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664379780070-cb71dea3-0d99-4b03-8543-f992129beef3.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=293&id=uc53264fd&name=image.png&originHeight=672&originWidth=1998&originalType=binary&ratio=1&rotation=0&showTitle=false&size=514209&status=error&style=shadow&taskId=ubfc64250-41bb-4a05-9e0e-d782782b9c5&title=&width=870)

参考官方公共层 [Nodejs-Puppeteer17x README](https://github.com/awesome-fc/awesome-layers/tree/main/docs/Nodejs-Puppeteer17x) 添加情况变量,关于版本1,需要添加 `LD_LIBRARY_PATH=/opt/lib/x86_64-linux-gnu:/opt/lib`情况变量。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664380473979-afa1ecb7-7307-4221-b136-e19e220fcc26.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=156&id=uc8f787c0&name=image.png&originHeight=354&originWidth=2964&originalType=binary&ratio=1&rotation=0&showTitle=false&size=340302&status=error&style=shadow&taskId=u72c10b9a-47fd-4cb6-b1f6-2cbf4f338d3&title=&width=1307)

最初,利用**触发器办理**中的**测试地址**停止测试验证。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664379494924-cac1b5b6-cd2c-4012-8a61-6b76f70d0dfa.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=488&id=ub6f43013&name=image.png&originHeight=1272&originWidth=2082&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1034075&status=error&style=shadow&taskId=u87ff21aa-6b33-4218-aa09-7a2c9100238&title=&width=799)

测试成果如下所示,已胜利将 Serverless Devs 官方停止截图。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664379566527-10152cd8-63b3-4a14-b6a1-a0f59e24652b.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=594&id=ua4f9b0e1&name=image.png&originHeight=1790&originWidth=2442&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2654764&status=error&style=shadow&taskId=u695f226e-398b-48d1-ba3f-efe93e2d3c7&title=&width=810)

## 示例二、基于公共层快速实现 .NET 6 自定义运行时

起首,通过控造台创建 .NET 6 自定义运行时。在最上层选择 “利用自定义运行时创建”,选择“处置 HTTP 恳求”,选择 `.NET 6`运行时,其他设置装备摆设利用默认值。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664380612576-99410728-1a70-4890-838f-b00f3fded5f2.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=592&id=u82af7c58&name=image.png&originHeight=1618&originWidth=2956&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1786177&status=error&style=shadow&taskId=uc3eb4b82-f016-4685-915c-d60bb6c97c1&title=&width=1082)

创建胜利后,能够通过 WebIDE 看到示例代码 `Program.cs`

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664380793864-4348f9fa-4598-459e-9cba-b6ec0e54d6f5.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=540&id=u6b6750d8&name=image.png&originHeight=1580&originWidth=2970&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1826543&status=error&style=shadow&taskId=u630f8228-5e77-43c0-a9b0-0b93f715a08&title=&width=1015)

示例代码中需要留意四个部门:

- 该示例监听了0.0.0.0的9000端口,Custom Runtime启动的办事必然要监听0.0.0.0:CAPort或*:CAPort端口,不克不及监听`127.0.0.1`或 `localhost`。详情参考文档 [Custom Runtime>根本原理](什么是冷启动CustomRuntime以及HTTPServer设置装备摆设要求_函数计算-阿里云帮忙中心)。

- 添加路由 `/`,间接返回字符串 "Hello World!"

- 添加路由`/invoke`,该路由为利用事务恳求处置法式的途径,可参考文档 [Custom Runtime >事务恳求处置法式(Event Handler)](CustomRuntime中事务恳求处置法式的构造特点和利用示例_函数计算-阿里云帮忙中心)

- 添加路由 `/initialize`,该路由为函数初始化回调法式对应的途径,该办法会在示例初始化时施行一次,可参考文档 [Custom Runtime >函数实例生命周期回调](CustomRuntime实现函数实例生命周期回调的办法_函数计算-阿里云帮忙中心)

起首,我们间接利用**触发器办理**页面中的**测试地址**停止测试,此时不添加任何 PATH 信息,成果如下图所示:

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664381200610-73936e6c-8e65-41f5-9f15-4c4555118c26.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=85&id=ahUXG&name=image.png&originHeight=170&originWidth=1548&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102644&status=error&style=shadow&taskId=u4cd9b652-ce07-46d3-a481-a78038ccf6b&title=&width=774)

然后,我们测试添加 `/invoke`途径停止测试,因为该路由办法为 POST,我们间接利用 `curl -XPOST`测试:

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664381799821-a16a146f-c14a-4b65-a702-2f1bd83fc103.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=47&id=u6ce8525f&name=image.png&originHeight=102&originWidth=1948&originalType=binary&ratio=1&rotation=0&showTitle=false&size=99644&status=error&style=shadow&taskId=u955c27a3-f77e-4fdc-9d29-bd0b1dafc5a&title=&width=906)

同样,我们用那种办法测试一下`/initialize`

> 留意:此处只是做测试,初始化回调函数不需要主动挪用,函数计算平台会在实例启动后主动挪用该回调办法(不要忘记在设置装备摆设里启用 initializer 回调法式)

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664381861365-a65bf625-3bbe-417c-bf04-ef2f4090a12b.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=49&id=u338b8550&name=image.png&originHeight=106&originWidth=2022&originalType=binary&ratio=1&rotation=0&showTitle=false&size=92146&status=error&style=shadow&taskId=u96f00e93-2f9a-4f32-91aa-c6a347f6b4d&title=&width=941)

最初,我们再做一个小测试,在**触发器办理**页面将**HTTP触发器**删除,删除后该函数类型会转换成**事务恳求处置法式**,在函数设置装备摆设中,将 Initializer 回调法式启用

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664382168735-37c8506a-797f-43b5-8222-272657c8e3e5.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=86&id=u7ee3a2ab&name=image.png&originHeight=172&originWidth=2082&originalType=binary&ratio=1&rotation=0&showTitle=false&size=129132&status=error&style=shadow&taskId=u7ac2528e-b2c5-41ef-87c1-2b9e9973618&title=&width=1041)

在控造台上测试该函数,成果如下图所示:

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664382445079-df5599c2-0e0d-42ea-ac9a-818ae1e785be.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=527&id=ub6683f97&name=image.png&originHeight=1054&originWidth=2230&originalType=binary&ratio=1&rotation=0&showTitle=false&size=870915&status=error&style=shadow&taskId=ueaebbf1c-9cee-427e-a4c5-318b6c11c46&title=&width=1115)

点击**实时日记**按钮,能够看到在该恳求施行前,已经施行了 Initialize 回调办法。

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2022/png/18456742/1664382378725-63427566-35da-4838-8cc7-80b56d62b332.png#clientId=u526045d2-aba3-4&errorMessage=unknown%20error&from=paste&height=146&id=u3982b4ad&name=image.png&originHeight=292&originWidth=1642&originalType=binary&ratio=1&rotation=0&showTitle=false&size=255670&status=error&style=shadow&taskId=u7f1329e4-cffa-4a06-a6db-003e1e38d36&title=&width=821)

# 层的更佳理论是什么?

前文介绍了什么是自定义层,为什么利用自定义层,什么是公共层,并介绍了两个官方公共层的示例。但我们对层的利用仍然还有一些疑惑,好比什么场景下保举利用层?层与代码包有什么区别?有没有与层类似的功用?与那些类似功用比拟,层的优缺点是什么?接下来测验考试答复一下那些问题。

## 什么场景下保举利用层?

目前,利用层的场景次要有两类,一类是自定义运行时,另一类是各类语言的依赖库。强烈**保举通过层来构建并利用自定义运行**时,但关于各类语言的依赖库,能够参考下面那些建议:

- 保举优先利用官方公共层

- 非编译型语言的依赖库保举利用层来办理,对编译行语言需要按照现实情况停止判断(好比,对自定义运行时,若是利用JAR包的体例运行 Java 法式,则无法引入层中的依赖,可参考文档 [若何在Custom Runtime中引用层中的依赖?](CustomRuntime内各语言引用层中依赖的办法_函数计算-阿里云帮忙中心))

- 若是依赖库较大,而且没有超越层的限造大小,保举利用层

- 若是依赖库需要额外安拆共享动态库,保举利用层(若是构建比力复杂,可联络函数计算团队造做)

- 若是在多个函数、多个账号之间有共享代码或数据的需求,保举利用层

## 层与代码包有什么区别?

曲不雅上看,层就是把本来代码包的一部门内容拆分出来,再从头建一个代码包罢了,那为什么又成立一个层的概念呢?**那里的次要区别是层与代码包的设想理念差别。**

- **层有更简洁的版本办理计划**

层的版本是从 1 起头主动递增的,目前一个层更大撑持 100 个可用版本(不包罗已删除的版本);而对代码包来讲没有版本的概念,只要在办事层面上有版本概念,相对层的版本会愈加复杂。

- **-层版本是只读的,不成变的**

一个层的版本在创建后内容是无法改动的(权限除外),若是想修改层的内容,只能发布一个新的版本。层版本的只读特征可以制止层的改动对函数的影响。

- **层的共享才能**

层能够跨函数、跨账号停止共享,而代码包不撑持。

- **层版本的软删除战略**

层版本删除后,不会影响已经设置装备摆设改层版本的函数的一般运行。因为在层版本删除是,阿里云函数计算平台其实不会间接将层版本的代码删掉,而是先辈行一次软删除操做,制止新的函数利用已删除的层版本,当该层版本没有函数引用时,才会彻底删除该层版本。

## 阿里云函数计算中有没有与层类似的功用?与类似功用比拟,层的优缺点是什么?

在阿里云函数计算平台中,与层类似的功用是办事设置装备摆设中的“[挂载NAS文件系统](若何在办事上设置装备摆设NAS文件系统_函数计算-阿里云帮忙中心)”和“挂载 OSS 对象存储”功用,层与挂载NAS/OSS在功用和应用场景上有一些明显的差别:

| # | 层 | 挂载 NAS/OSS |

| --- | --- | --- |

| 性能 | 高(层是在挪用前预先下载,运行时当地拜候,性能高) | 低(运行时通过收集拜候,会共享机器带宽,跟着并发增大,延时会有明显增加) |

| 共享才能 | 高(撑持跨账号、跨函数共享) | 低(只撑持跨函数共享,不撑持跨账号) |

| 存储限造 | 单个层 Zip 包限造 500MB,单个函数最多可设置装备摆设 5 个层,总大小不克不及超越 2GB | 无限造 |

| 版本控造 | 有 | 无 |

| 利用体例 | 层版本是只读的,不撑持内容修改。

因而,统一个函数设置装备摆设的层中的数据是稳定的,包管在运行期间层数据的一致性。 | NAS/OSS 是可写的,撑持内容修改。

在办事中设置装备摆设的 NAS/OSS 中的数据是可变的,无法包管在运行期间数据的一致性。 |

| 费用 | 无额外费用 | 有额外的 NAS/OSS 利用费用 |

| 其他限造 | 无 | NAS 挂载只撑持私有 VPC 情况 |

简单总结一下,若是代码或数据的大小超越层的限造,则保举利用挂载 NAS/OSS 的体例;若是代码或数据会镜像改动,或者有运行时修改数据的需求,那么那里也保举利用挂载 NAS/OSS 的体例。

# 结语

在阿里云函数计算中,**层的定位是一种不成变的根底设备,通过层版本的只读特征包管层的一致性和可靠性。**本文起首介绍了自定义层的特点和窘境,然后介绍了近期发布的公共层功用,详细陈说了基于官方公共层实现的两个示例法式,最初切磋了层的更佳理论是什么,希望通过本文能让读者更好的理解层的概念及其应用场景。

层的功用仍在持续完美中,接下来我们会在一下几个标的目的停止重点优化:

- 完美官方公共层体验,弥补更多的常用依赖库或自定义运行时做为官方公共层,并供给完美的应用示例。

- 供给公共层奉献的办法和示例,促进公共层的开源共建。

若是对层的利用有任何的疑惑或者建议,欢送搜刮(群号:11721331)进入阿里云函数计算钉钉群联络我们。

![lADPJw1WT5eVeHvNBFLNA-I_994_1106.jpg](https://intranetproxy.alipay.com/skylark/lark/0/2022/jpeg/22456429/1665628355458-7fd9c251-3607-48cb-a929-62d8012b20a2.jpeg#clientId=u4bd80533-128b-4&errorMessage=unknown%20error&from=paste&height=233&id=u76def2c2&name=lADPJw1WT5eVeHvNBFLNA-I_994_1106.jpg&originHeight=1106&originWidth=994&originalType=binary&ratio=1&rotation=0&showTitle=false&size=194741&status=error&style=shadow&taskId=uee425414-a1f3-4a2e-90fe-cf1cb5ddc02&title=&width=209)

## 延申阅读:

- [创建自定义层](创建自定义层_函数计算-阿里云帮忙中心) :

[https://help.aliyun.com/document_detail/193057.html](创建自定义层_函数计算-阿里云帮忙中心)

- [在函数中设置装备摆设自定义层](若何在函数中设置装备摆设自定义层_函数计算-阿里云帮忙中心):

[若何在函数中设置装备摆设自定义层_函数计算-阿里云帮忙中心](若何在函数中设置装备摆设自定义层_函数计算-阿里云帮忙中心)

- [若何在Custom Runtime中引用层中的依赖?](CustomRuntime内各语言引用层中依赖的办法_函数计算-阿里云帮忙中心)

[CustomRuntime内各语言引用层中依赖的办法_函数计算-阿里云帮忙中心](CustomRuntime内各语言引用层中依赖的办法_函数计算-阿里云帮忙中心)

- 在函数中设置装备摆设官方公共层

[若何通过控造台和ServerlessDevs在函数中设置装备摆设官方公共层_函数计算-阿里云帮忙中心](https://help.aliyun.com/document_detail/451191.html)

- 阿里云函数计算 公共层github:

[github.com/awesome-fc/awesome-layers](https://github.com/awesome-fc/awesome-layers)

- 官方公共层

[Nodejs-Puppeteer17x README](https://github.com/awesome-fc/awesome-layers/tree/main/docs/Nodejs-Puppeteer17x)

- [Custom Runtime 根本原理](什么是冷启动CustomRuntime以及HTTPServer设置装备摆设要求_函数计算-阿里云帮忙中心)

[什么是冷启动CustomRuntime以及HTTPServer设置装备摆设要求_函数计算-阿里云帮忙中心](什么是冷启动CustomRuntime以及HTTPServer设置装备摆设要求_函数计算-阿里云帮忙中心)

- Custom Runtime 事务恳求处置法式

[CustomRuntime中事务恳求处置法式的构造特点和利用示例_函数计算-阿里云帮忙中心](https://help.aliyun.com/document_detail/191342.html)

- Custom Runtime 函数实例生命周期回调

[https://help.aliyun.com/document_detail/425056.html](CustomRuntime实现函数实例生命周期回调的办法_函数计算-阿里云帮忙中心)

**点击领会函数计算 FC!**

[国内独一入选Forrester指导者象限](https://www.aliyun.com/product/fc)

0
回帖

函数计算|如何使用层解决依赖包问题? 期待您的回复!

取消