云函数技术细节

权限

在云函数中执行的代码权限等级为超级管理员权限,不受数据表 ACL 的限制。因此开发者可以在云函数中执行一些特权操作,比如:

  • 批量修改用户信息
  • 写入一张所有人不可写的数据表
  • 删除数据表

函数运行时的容器模型

云函数系统接收到云函数任务时将会根据任务的配置信息(如内存大小等)进行资源分配,进行所有函数运行容器的创建、管理和删除清理操作。

分配完成后,云函数代码将在被分配的容器中执行,在第一次执行完以后,容器将保留一段时间,假如这段时间内有同一个函数的新任务被触发,那么新任务将会在同一个容器中被执行,这意味着同一个容器可能会被调度来执行多个云函数任务,这也起到了减少云函数任务执行延迟的作用。

此机制会有以下影响:

  • 用户代码在函数入口外定义的全局变量在复用的容器环境中将被保留,开发者可以在云函数中增加检查代码来确认是否已在全局变量中缓存一些可复用的数据,以减少一些重复的网络请求、数据查询或计算。

  • 被复用的容器在 /tmp 目录下的文件将会被保留至下一个云函数任务中,开发者可以添加额外的代码来检查缓存中是否有存储的数据,以减少一些重复的网络请求。同时,如果任务产生的临时文件较大,为避免影响下次任务执行,可考虑主动删除清理文件。

请勿在云函数代码中假定当前的容器是被复用的容器,容器是新容器或是被复用的容器与每一次调用时系统中的容器情况有关,如果要使用容器中缓存的信息,请务必在云函数代码中增加检查先确认容器中存在缓存。

任务调度策略

当前版本的云函数并发限制如下(如需提升并发额度,请点击提交申请),即只能同时运行 100/10 个云函数任务:

配置并发限制
128M/0.5CPU100
256M/0.75CPU10

若应用正在运行的云函数任务达到并发限制时接收到新任务,将会按照以下策略进行调度:

  • 同步云函数任务:在 2 秒内会重试几次进行调度执行,如果每次调度时应用正在运行的云函数任务都已达限制,则调度失败,云函数任务不会被运行。

  • 异步云函数任务:在 5 分钟内在重试几次进行调度执行,如果每次调度时应用正在运行的云函数任务都已达限制,则调度失败,云函数任务不会被运行。

网络并发请求限制

当前版本的云函数对于对容器外网络请求有并发限制(包括数据表 / 内容库等知晓云操作以及知晓云外的网络请求),当进行并发请求时(如使用 Promise.all),请将并发请求数控制在 50 个以下。

云函数内存限制

当前版本云函数提供 128M/256M 两个版本,如果你有更高级别的要求,请联系微信客服(minsupport3)

其他

GPL Code

云函数的构建离不开开源社区的贡献。在云函数的实现中,知晓云使用了诸多 GPL 协议的源代码并进行了修改。

知晓云团队基于以下工具构建了云函数功能:

  • buildroot
  • busybox
  • Node.js

所有的 GPL 源代码可通过发起工单的方式获取。

云函数的实现

云函数是基于知晓云团队自研的轻量级容器 Iceberg 的,并非基于 docker 或类似方案实现的。每次用户云函数执行完后,容器即立即销毁。

云函数的临时文件存储

临时文件可存储在 /tmp 中。用户有高达 64MB 的高速临时文件存储空间可供使用。临时文件的生命周期限制在云函数的执行周期中,云函数返回后临时文件即时销毁,并将无法找回。

云函数的网络请求

云函数内无法对外界发起直接的网络请求。若希望发起请求,应使用 SDK 中提供的方法进行。

执行环境内的可用工具、资源

为方便使用,知晓云在云函数的执行环境内准备了如下工具/资源:

  • gd
  • ghostscript
  • imagemagick

这里我们可以通过 child_process 模块来调用这些二进制文件

示例代码

  1. // 使用 convert 命令转换图片
  2. const { spawn } = require('child_process');
  3. const cmd = spawn('convert', ['/tmp/1.png', '-resize', '50%', '/tmp/1.jpg']);
  4. cmd.stdout.on('data', (data) => {
  5. console.log(`stdout: ${data}`);
  6. });
  7. cmd.stderr.on('data', (data) => {
  8. console.log(`stderr: ${data}`);
  9. });
  10. cmd.on('close', (code) => {
  11. console.log(`child process exited with code ${code}`);
  12. });

以下 emoji 字体:

  • /usr/share/fonts/google-material/MaterialIcons-Regular.ttf

以下西文字体:

  • /usr/share/fonts/ttf-bitstream-vera/VeraBd.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraBI.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraIt.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraMoBd.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraMoBI.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraMoIt.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraMono.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraSeBd.ttf
  • /usr/share/fonts/ttf-bitstream-vera/VeraSe.ttf
  • /usr/share/fonts/ttf-bitstream-vera/Vera.ttf
  • /usr/share/fonts/cantarell/Cantarell-Regular.otf
  • /usr/share/fonts/cantarell/Cantarell-Oblique.otf
  • /usr/share/fonts/cantarell/Cantarell-Bold.otf
  • /usr/share/fonts/cantarell/Cantarell-BoldOblique.otf
  • /usr/share/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSansMono-Bold.ttf
  • /usr/share/fonts/dejavu/DejaVuSansMono-Oblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSansMono.ttf
  • /usr/share/fonts/dejavu/DejaVuSans.ttf
  • /usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSans-Bold.ttf
  • /usr/share/fonts/dejavu/DejaVuSans-ExtraLight.ttf
  • /usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSerif.ttf
  • /usr/share/fonts/dejavu/DejaVuSerif-BoldItalic.ttf
  • /usr/share/fonts/dejavu/DejaVuSerif-Bold.ttf
  • /usr/share/fonts/dejavu/DejaVuSerif-Italic.ttf
  • /usr/share/fonts/dejavu/DejaVuSansCondensed-BoldOblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSansCondensed-Bold.ttf
  • /usr/share/fonts/dejavu/DejaVuSansCondensed-Oblique.ttf
  • /usr/share/fonts/dejavu/DejaVuSansCondensed.ttf
  • /usr/share/fonts/dejavu/DejaVuSerifCondensed-BoldItalic.ttf
  • /usr/share/fonts/dejavu/DejaVuSerifCondensed-Bold.ttf
  • /usr/share/fonts/dejavu/DejaVuSerifCondensed-Italic.ttf
  • /usr/share/fonts/dejavu/DejaVuSerifCondensed.ttf
  • /usr/share/fonts/liberation/LiberationMono-BoldItalic.ttf
  • /usr/share/fonts/liberation/LiberationMono-Bold.ttf
  • /usr/share/fonts/liberation/LiberationMono-Italic.ttf
  • /usr/share/fonts/liberation/LiberationMono-Regular.ttf
  • /usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf
  • /usr/share/fonts/liberation/LiberationSans-Bold.ttf
  • /usr/share/fonts/liberation/LiberationSans-Italic.ttf
  • /usr/share/fonts/liberation/LiberationSans-Regular.ttf
  • /usr/share/fonts/liberation/LiberationSerif-BoldItalic.ttf
  • /usr/share/fonts/liberation/LiberationSerif-Bold.ttf
  • /usr/share/fonts/liberation/LiberationSerif-Italic.ttf
  • /usr/share/fonts/liberation/LiberationSerif-Regular.ttf

以下中文字体:

  • /usr/share/fonts/arphic-bkai00mp/bkai00mp.ttf
  • /usr/share/fonts/arphic-bsmi00lp/bsmi00lp.ttf
  • /usr/share/fonts/arphic-gbsn00lp/gbsn00lp.ttf
  • /usr/share/fonts/arphic-gkai00mp/gkai00mp.ttf
  • /usr/share/fonts/source-han-sans/SourceHanSans-Bold.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-ExtraLight.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-Heavy.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-Light.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-Medium.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-Normal.ttc
  • /usr/share/fonts/source-han-sans/SourceHanSans-Regular.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-Bold.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-ExtraLight.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-Heavy.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-Light.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-Medium.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-Regular.ttc
  • /usr/share/fonts/source-han-serif/SourceHanSerif-SemiBold.ttc