云函数产品
云函数产品文档:https://cloud.tencent.com/product/scf
云函数特性
- 简单易用
- 高效
- 稳定可靠
- 简化管理
- 降低开销
云函数应用场景
- 文件处理(cos触发器)
- 消息处理(消息队列触发器)
- 音视频处理(推流,页面渲染等)
- web后端(api网关触发器)
- AI训练(GPU)
云函数运行流程
层
层的优势
- 减少云函数代码包大小
- 可以作为中间件被多个其他云函数绑定依赖调用
- 绑定层的云函数,层自动解压到/opt目录下,python,java,nodejs已经把/opt设置为依赖环境变量,可以直接通过相对路径来引用。
层使用java示例
绑定层的云函数,在云函数执行的时候会自动把层解压到/opt目录下。python,java,nodejs已经把/opt目录内置为依赖的环境变量。本次示例以java,nodejs,python为例。
demo简介
示例云函数代码和层代码如附件(本示例为java层使用demo,层和函数都很小)
目录结构如下,其中layer目录下存放层的pom.xml和层源码,function目录下存放云函数的pom.xml和云函数源码,并且云函数pom.xml设置了层依赖:
代码语言:javascript复制# tree
.
|-- function
| |-- pom.xml
| `-- src
| `-- main
| `-- java
| `-- example
| `-- Hello.java
`-- layer
|-- pom.xml
`-- src
`-- main
`-- java
`-- layer
`-- java
`-- demo
`-- Demo.java
云函数配置
- pom配置
pom.xml依赖信息如下,可以看到依赖的层为groupId为layer.java.demo,artifactId为scf-demo-layer,版本为1.0-SNAPSHOT
代码语言:javascript复制...
<dependencies>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>scf-java-events</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>layer.java.demo</groupId>
<artifactId>scf-demo-layer</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
并且pom.xml打包时会排除层的依赖(配置excludes为layer.java.demo:*),这样的话函数打包不会把层依赖打进去。
代码语言:javascript复制...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<excludes>
<exclude>layer.java.demo:*</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
...
- 代码块
代码会导入层并调用层的LayerDemo函数
代码语言:javascript复制package example;
import com.qcloud.scf.runtime.Context;
import layer.java.demo.Demo;
public class Hello {
public String mainHandler(String name, Context context) {
System.out.println("Hello world!");
String layerInvoke = Demo.LayerDemo("layer invoke");
System.out.println(layerInvoke);
return String.format("Hello %s.", name);
}
}
- 打包代码并上传云函数
需要在centos7机器上,并安装有java,mvn等,然后到function目录下执行 mvn package,成功后会显示“BUILD SUCCESS”并在target目录下生成<artifactId>-<version>.jar包
然后在云函数控制台创建云函数并把jar包上传上去
- 测试
点击测试后云函数运行错误,报错“NoClassDefFoundError”,表示缺少依赖的层
层配置
- pom配置
pom.xml信息简略如下,这里可以看到层的groupId,artifactId以及version,因为层的代码只是个简单的demo,并没有其他依赖项
代码语言:javascript复制...
<groupId>layer.java.demo</groupId>
<artifactId>scf-demo-layer</artifactId>
<version>1.0-SNAPSHOT</version>
...
- 代码块
代码里公开了云函数调用的LayerDemo函数。
代码语言:javascript复制package layer.java.demo;
public class Demo {
public static String LayerDemo(String name) {
System.out.println("This is a demo layer!");
return String.format("Hello, daemo layer %s.", name);
}
}
- 打包层代码并上传到层
需要在centos7机器上,并安装有java,mvn等,然后到layer目录下执行 mvn package,成功后会显示“BUILD SUCCESS”并在target目录下生成<artifactId>-<version>.jar包
然后在控制台把jar包(scf-demo-layer-1.0-SNAPSHOT.jar)上传到层里
并且把该层版本绑定到云函数里
- 测试
再次测试云函数,查看执行结果。发现测试成功,说明java云函数绑定层测试成功。
层使用nodejs示例
层参考文档:https://cloud.tencent.com/document/product/583/45760
demo简介
nodejs层依赖示例参考腾讯云官方demo:https://github.com/tencentyun/scf_layer_demo
目录结构如下:
代码语言:javascript复制[root@VM-0-15-centos scf_layer_demo-master]# tree
.
|-- LICENSE
|-- README.md
|-- function
| |-- index.js
| `-- package.json
`-- layer
`-- node_modules
`-- underscore
|-- LICENSE
|-- README.md
|-- modules
| |-- index-all.js
| |-- index-default.js
| `-- index.js
|-- package.json
|-- underscore-min.js
|-- underscore-min.js.map
|-- underscore.js
`-- underscore.js.map
其中function目录下是云函数源码js和依赖package.json,layer目录下则是云函数依赖的层
云函数配置
- 依赖package.json
云函数代码依赖层里面的underscore
代码语言:javascript复制{
"name": "scf_layer_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"underscore": "^1.10.2"
},
"devDependencies": {},
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"repository": {
"type": "git",
"url": "git https://github.com/tencentyun/scf_layer_demo.git"
},
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/tencentyun/scf_layer_demo/issues"
},
"homepage": "https://github.com/tencentyun/scf_layer_demo#readme"
}
- 代码块
云函数代码依赖层中的underscore并调用now()函数
代码语言:javascript复制'use strict';
const _ = require("underscore");
exports.main_handler = async (event, context, callback) => {
console.log("timestamp: " _.now());
return event;
};
- 上传云函数
到function目录下,使用命令: zip nodejs-function.zip ./* 将js文件和package.json文件打成zip包
创建nodejs云函数并把zip包上传上去(如果源码文件少,也可以使用在线编辑把源码和package.json贴到云函数中)
- 测试
在“函数代码”菜单测试后报错,报错原因“Cannot find module 'underscore'”
层配置
- 层代码
层代码在layer下,执行命令: zip xx.zip -r ./* 把层里面的node_modules打包
- 上传层并绑定到云函数
新建层并把zip包上传到层里
在云函数的“层管理”菜单绑定创建的层
- 测试
在云函数“函数代码”菜单,点击测试,可以看到云函数测试成功
层使用python3示例
demo简介
示例云函数代码和层代码如附件(本示例为python3调用cos函数的简单demo,层为cos sdk,云函数调用cos sdk函数)
目录结构如下,其中function目录下存放云函数源码源码中依赖cos-python-sdk-v5
,layer目录下存放cos-python-sdk-v5源码(https://github.com/tencentyun/cos-python-sdk-v5)
代码语言:javascript复制[root@VM-0-15-centos python3]# tree
.
|-- function
| `-- index.py
|-- layer
| |-- CHANGELOG.md
| |-- LICENSE
| |-- MANIFEST.in
| |-- README.rst
| |-- demo
| | |-- batch_operation_demo.py
| | |-- ci_compress.py
| | |-- ci_doc_preview.py
| | |-- ci_image.py
| | |-- ci_media.py
| | |-- ci_speech_recognition.py
| | |-- ci_watermark.py
| | |-- demo.py
| | |-- dir_download_demo.py
| | |-- fetch_demo.py
| | `-- tce_demo.py
| |-- qcloud_cos
| | |-- __init__.py
| | |-- cos_auth.py
| | |-- cos_client.py
| | |-- cos_comm.py
| | |-- cos_encryption_client.py
| | |-- cos_exception.py
| | |-- cos_threadpool.py
| | |-- crypto.py
| | |-- demo.py
| | |-- resumable_downloader.py
| | |-- select_event_stream.py
| | |-- streambody.py
| | |-- tce_demo.py
| | |-- version.py
| | `-- xml2dict.py
| |-- requirements.txt
| |-- setup.py
| `-- ut
| `-- test.py
注意:layer里是直接从github下载的cos-python-sdk-v5,本身还有其他依赖项(requirements.txt)
云函数配置
- 代码块
函数代码依赖层中qcloud_cos包,代码如下,其中secret_id, secret_key以及bucket需要从腾讯云获取
代码语言:javascript复制# -*- coding: utf8 -*-
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from qcloud_cos import CosServiceError
from qcloud_cos import CosClientError
import sys
import logging
import json
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
secret_id = '<secretid>'
secret_key = '<secretkey>'
region = 'ap-guangzhou'
token = None
scheme = 'http'
config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
client = CosS3Client(config)
test_bucket = '<bucket>-<appid>'
def main_handler(event, context):
print("Hello world")
response = client.put_async_fetch_task(
Bucket=test_bucket,
FetchTaskConfiguration={
'Url': '<source-url>',
'Key': '<source-key>'
}
)
print('response:', response)
return("Hello World")
- 创建云函数并上传代码
在腾讯云控制台创建云函数,使用python3.7运行函数并直接把function里的源码贴到“在线编辑”里的index.py里
- 测试
云部署成功点击“函数代码”菜单下面的“测试”,测试运行失败,原因是“ModuleNotFoundError”
层配置
- 依赖项
cos-python-sdk-v5有依赖项,在layer目录下的requirements.txt中
代码语言:javascript复制[root@VM-0-15-centos layer]# cat requirements.txt
dicttoxml
six
crcmod
pycryptodome
- 代码块
层提供的接口都在qcloud_cos目录下,上传层的时候需要本地安装下依赖项。安装依赖项命令: pip3 install -r requirements.txt -t .
- 上传层并绑定云函数
依赖安装好之后把层打包,打包命令: zip scf-layer-python3.zip -r ./*
控制台创建层并把打包好的zip包上传到层
然后在云函数的“层管理”菜单绑定上传好的层
- 测试
在“函数代码”菜单点击“测试”,发现云函数运行正常,表示层绑定成功