本文记录阿猪使用腾讯云函数搭建Web站点的一些经验总结。

一、云函数运行web站点的原理

  云函数是腾讯云基于Serverless的一款产品,一个函数实例相当于一个可以运行代码的容器环境,用户可以自定义内存容量等配置参数。
  云函数支持用户自定义安装语言环境、版本、依赖环境,并内置对如下语言的支持:

语言 版本
Node.js 6、8(帮助文档未提及)
10.15、12.16、14.18、16.13
Python 2.7、3.6、3.7
PHP 5.6、7.2、7.4、8.0
JAVA 8、11
  云函数支持事件触发和HTTP请求触发两种触发方式。

  在函数的根目录下有一个名为sfc_bootstrap的启动文件,它属于批处理文件。当一个函数被触发后,会逐行执行启动文件中的命令,从而达到既定的目的。云函数的所有应用场景都是基于这个基本原理。
  一个基本的Serverless Web应用包含API网关、云函数这两个组件,用户可以根据需要添加CFS文件系统、COS对象存储、私有网络、Serverless数据库等额外的组件。
  用于Web服务的云函数通常被称为Web函数,Web函数的运行原理如下图所示:

腾讯云web函数运行原理
  当访客访问Web函数绑定的域名时,HTTP请求会通过API网关触发这个函数。函数首先会执行启动文件,按照启动文件中指定的路径启动某种语言的(暂且统称为)解释器,并由这个解释器运行指定的入口文件。

  在PHP应用中,默认的容器环境使用PHP Development Server(而非常见的Apache或者Nginx)作为Web Server程序。它使用一个php文件实现类似于Nginx的转发功能,将外网的HTTP请求转发给容器环境内的Web Server。

二、如何使用自己指定的语言、版本、扩展/依赖

1、使用容器环境的内置语言和版本

  如果你打算使用的是容器环境的内置语言和版本,只需要在启动文件中指定对应语言、版本的解释器的路径即可。可以参考腾讯云函数帮助文档的启动文件说明

2、使用自己上传的语言和版本

  如果容器环境内置的语言和版本没有你需要的,你可以自己上传编译好的二进制文件。编译二进制文件需要具备一定的Linux操作技能。你可以通过任何一种能上传代码的方法进行上传,只要在启动文件中设置好对应的路径即可。方法举例如下:

(1)上传到层

  腾讯云函数提供了“层”功能,允许用户自己创建“层”,将编译好的二进制文件打包并上传到层,然后将层绑定到对应的云函数上。当这个函数被触发时,层中的压缩文件会被释放到容器环境中的/opt目录下,然后通过启动文件被调用。可以参考腾讯云函数帮助文档的层管理
  这个方法的优点是不需要使用额外的文件存储组件,而且函数之间可以共享,缺点是函数冷启动时会增加一个释放文件的步骤,如果文件比较大的话,会比较占用时间。

(2)上传到CFS

  如果你的云函数绑定了CFS,那么你可以直接将编译好的二进制文件上传到CFS文件系统中,然后通过启动文件调用。
  和层相比,这个方法的优点是免去了释放文件的步骤,但是使用CFS会产生额外的费用。

3、安装额外的扩展/依赖

  如果你使用的语言支持单独添加扩展/依赖,那么你可以参考上传语言和版本中的方法上传扩展/依赖,然后在语言解释器的配置文件中指定扩展/依赖的路径并启用。你也可以将扩展/依赖跟随函数代码一同打包上传。可以参考腾讯云函数帮助文档的依赖安装
  注意:有些语言可能不支持单独添加扩展/依赖,需要跟随项目或者解释器一起编译。
  另外你也可以在函数的构建阶段借助CI/CD流程安装所需要的扩展/依赖。这需要具备一定的动手能力,此处不再展开。

三、如何持久化存储文件

  在云函数的容器环境中,只有/tmp目录是可读写的,空间大小为512MB。当实例被释放时,这个临时目录中的文件也会被销毁。如果你的Web站点需要保存文件,那么建议你为Web函数绑定CFS文件系统或者COS对象存储组件。

1、使用CFS存储文件

  创建一个CFS,然后在函数配置中直接挂载即可。可以参考腾讯云函数帮助文档的挂载CFS文件系统
  挂载CFS后,可以像操作原生服务器一样处理CFS中的文件,这对于基于原生服务器而设计业务逻辑的传统应用比较友好。

2、使用COS存储文件

  使用COS对象存储服务存储文件,需要借助API或者SDK。可以参考腾讯云函数帮助文档的COS触发器
  使用COS需要对传统应用的业务流程和代码进行改造适配。

四、如何缩短冷启动的时间

  函数的实例在闲置一段时间后会被释放,再次请求的时候会产生较长的初始化时间(冷启动),这会消耗大约5秒或更长的时间,严重影响访客的用户体验。可以参考以下方法来改善:

1、启用预制并发

  启用预制并发后,系统会根据你的预设参数预留一定的实例,从而避免冷启动的发生。可以参考腾讯云函数帮助文档的预制并发
  这个方法适用于访问量比较大的站点。

2、启用请求多并发,并Keep Warm

  在函数配置界面启用请求多并发,并根据你单实例的负载情况设置一个适当的并发数,例如15。注意:这里的请求多并发和前边的预制并发是不同的两个概念,请求多并发仍然会在空闲一定时间后释放实例,而预制并发始终会保留实例。
  接着新创建一个函数,在函数代码中写一段访问你的站点的代码,然后为函数添加一个触发器,触发方式选择定时触发,触发周期选择5分钟。使用任何你熟悉的语言都可以,以下是一个Python代码的示例:

1
2
3
4
5
6
7
8
import urllib.request
def main_handler(event, context):
url = 'https://yfzhu.cn/' #替换为你的的URL
response = urllib.request.urlopen(url)

#以下代码用于在测试函数时显示返回的结果,删除即可
html = response.read()
print(html)

  这个函数会模拟访客每隔5分钟访问一次站点,确保始终有一个函数实例存活。这个方法适合个人博客等访问量较小的站点。