【scf】云函数层的理解和使用

2022-10-09 19:22:41 浏览数 (2)

云函数产品

云函数产品文档:https://cloud.tencent.com/product/scf

云函数特性

  • 简单易用
  • 高效
  • 稳定可靠
  • 简化管理
  • 降低开销

云函数应用场景

  • 文件处理(cos触发器)
  • 消息处理(消息队列触发器)
  • 音视频处理(推流,页面渲染等)
  • web后端(api网关触发器)
  • AI训练(GPU)

云函数运行流程

层的优势

  1. 减少云函数代码包大小
  2. 可以作为中间件被多个其他云函数绑定依赖调用
  3. 绑定层的云函数,层自动解压到/opt目录下,python,java,nodejs已经把/opt设置为依赖环境变量,可以直接通过相对路径来引用。

层使用java示例

绑定层的云函数,在云函数执行的时候会自动把层解压到/opt目录下。python,java,nodejs已经把/opt目录内置为依赖的环境变量。本次示例以java,nodejs,python为例。

demo简介

示例云函数代码和层代码如附件(本示例为java层使用demo,层和函数都很小)

scf_layer_java_demo.zip

目录结构如下,其中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函数)

scf-layer-python3.zip

目录结构如下,其中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包上传到层

然后在云函数的“层管理”菜单绑定上传好的层

  • 测试

在“函数代码”菜单点击“测试”,发现云函数运行正常,表示层绑定成功

0 人点赞