函数计算3.0和2.0版本差异及兼容性说明

函数计算3.0是产品的一个重大升级版本,在函数管理、函数执行引擎、自定义域名、函数授权及弹性伸缩规则方面进行了多项改进,旨在为用户提供极简的产品体验。本文主要介绍函数计算3.0的功能变化及兼容原有服务和函数的规则。

函数计算3.0功能变化

函数计算3.0功能变化如下:

  • 函数管理变化

    • 移除服务概念,函数成为一级实体,角色、日志和VPC等直接在函数级别配置。

    • 版本和别名直接作用在函数级别,可以对函数进行独立的版本控制。

    详细变化,请参见函数管理变化

  • 函数执行引擎变化

    • 统一请求处理程序(Handler)签名,HTTP请求和事件请求处理程序统一。具体信息,请参见HTTP Trigger行为变化

    • 标准运行时(Runtime)不再支持单实例多并发功能,Custom Runtime仍然支持单实例多并发功能。

    • 函数实例生命周期不再支持PreFreeze回调方法。

  • 自定义域名变化

    自定义域名不再依赖HTTP Trigger,可以直接引流到对应的函数。

  • 函数授权变化

    支持服务关联角色(SLR),简化函数授权体验。更多信息,请参见函数角色变化(SLR)

  • 弹性伸缩规则变化

    按量实例伸缩控制功能升级为函数并发度管理,可以限制预留实例和按量实例的总并发度。

原有的服务和函数配置等保持不变,调用不受影响。例如,原有的函数配置了单实例多并发可以继续使用,但在函数计算3.0中新创建的标准运行时的函数,无法再配置单实例多并发功能。关于兼容原有的服务和函数的规则,请参见兼容原有的服务和函数

函数管理变化

函数计算3.0中,可以直接创建函数,不需要先创建服务。原服务级别的配置例如角色、日志配置、VPC配置等,直接在函数级别配置。以Go SDK为例,代码如下:

resp, err := client.CreateFunction(
    new(fc.CreateFunctionRequest).
        SetBody(&fc.CreateFunctionInput{
            FunctionName: &funcName,
            Runtime:      tea.String("nodejs12"),
            Handler:      tea.String("index.handler"),
            MemorySize:   tea.Int32(128),
            Role:         tea.String("role-arn"),
            VpcConfig: &fc.VPCConfig{
                VpcId:           tea.String("vpc-id"),
                VSwitchIds:      []*string{tea.String("vsw-id")},
                SecurityGroupId: tea.String("sg-id"),
            },
            Code: new(fc.InputCodeLocation).SetZipFile(fx.GetCodeZipBase64()),
        }))

event := "my event"
resp, err = client.InvokeFunction(&funcName,
    new(fc.InvokeFunctionRequest).SetBody(strings.NewReader(event)))
body, err := ioutil.ReadAll(resp.Body)

在函数级别发布版本和创建别名,以Go SDK为例,代码如下:

resp, err := client.PublishFunctionVersion(&funcName,
    new(fc.PublishFunctionVersionRequest).SetBody(&fc.PublishVersionInput{
        Description: tea.String("version desc"),
    }))

aliasName := "my-alias"
routingConfig := map[string]*float32{
    "2": tea.Float32(float32(0.05)),
}

resp, err := client.CreateAlias(&funcName, new(fc.CreateAliasRequest).
    SetBody(&fc.CreateAliasInput{
        AliasName:               &aliasName,
        VersionId:               tea.String("1"),
        AdditionalVersionWeight: routingConfig,
    }))

HTTP Trigger行为变化

函数计算3.0中,处理事件请求和处理HTTP请求的函数入口统一。以Python为例,代码如下:

def handler(event, context):
    return 'hello fc'

对于HTTP Trigger调用,即通过HTTP Trigger的URL访问的请求或者通过自定义域名访问的请求,函数计算会将HTTP请求转换成event,同时将函数的响应转换成HTTP响应。

请求event示例如下:

{
    "version": "v1",
    "rawPath": "/my/path",
    "httpMethod": "POST",
    "headers": {
        "header1": "value1,value2",
        "header2": "value2"
    },
    "queryParameters": {
        "param1": "value1,value2",
        "param2": "value2"
    },
    "body": "hello from client",
    "isBase64Encoded": false,
    "requestContext": {
        "accountId": "12345678",
        "domainName": "my-domain.com",
        "domainPrefix": "prefix",
        "requestId": "abcd-efgh",
        "time": "2023-09-01T14:17:23+08:00",
        "timeEpoch": 1693549043255,
        "http": {
            "method": "GET",
            "path": "/my/path",
            "protocol": "http",
            "sourceIP": "39.40.41.42",
            "userAgent": "go-sdk/1.0"
        }
    }
}

HTTP响应示例如下:

def handler(event, context):
    return {
        'body': 'hello FC',
        'headers': {
            'my-custom-header': 'foo'
        },
        'statusCode': 400
    }

以上代码将被转换成如下的HTTP响应:

HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
My-Custom-Header: foo
X-Fc-Request-Id: 64e866c9-69902fbc525fd10989e7299c
Date: Fri, 25 Aug 2023 10:18:06 GMT
Content-Length: 8

hello FC

详细的请求和响应格式转换请参考HTTP触发器概述

函数角色变化(SLR)

在使用函数计算提供的日志、VPC、异步调用目标服务等功能时,函数计算需要访问其他的云服务。例如配置函数日志时,用户需要授权函数计算对指定日志Logstore的写入权限,函数计算才能够将函数日志写入到用户的Logstore。原来这个授权是通过服务角色进行授权,服务角色一方面用于函数计算访问其他的云服务,另一方面也用于函数执行时用户代码访问其他云服务。这样可能会导致服务角色的权限过大的问题。

函数计算3.0,函数计算支持了服务关联角色,专门用于授权函数计算访问其他的云服务,而用户代码访问其他云服务,则由函数角色来授权,用户可以根据函数的需要,细粒度地控制函数角色的授权。

在用户一次性授权后,在函数计算3.0创建的函数,默认将使用服务关联角色(SLR)。函数不需要配置角色即可使用日志、VPC、异步调用目标服务等功能。

兼容原有的服务和函数

函数计算3.0提供了一套全新的API和控制台操作界面,针对用户原有的服务和函数,也能够兼容。兼容的规则如下:

类别

兼容规则

示例

服务配置

原有的服务和函数将被统一转换成函数,函数名为<serviceName>$<functionName>

服务的配置,例如服务角色、日志配置、VPC配置等将被转换成函数配置。

原有服务s1,s1中有2个函数f1和f2,在函数计算3.0中,将被转换成2个函数,函数名分别为s1$f1s1$f2

更新函数配置,不改变服务配置,也不会影响服务下的其他函数。

原有服务s1有2个函数f1和f2,更新s1$f1的VPC配置,只会对s1$f1生效,s1和s1$f2的VPC配置不受影响。

使用函数计算2.0API更新服务配置,则服务下所有函数的对应配置会被更新。

原有服务s1有2个函数f1和f2,更新s1的VPC配置,则s1$f1s1$f2的VPC配置均会被更新。

版本和别名

原有的服务版本和别名会被转换成函数版本和别名。

原有的服务s1有2个版本1和2,有1个别名prod,在函数计算3.0版中,s1$f1s1$f2将都有2个版本1和2,并都有1个别名prod。

对函数发布一个版本,同时也会对服务和服务下的其他函数发布一个版本。

s1$f1发布一个版本3,则s1和s1$f2也会增加一个版本3。

对函数创建别名,同时也会对服务和服务下的其他函数也会增加一个别名。

s1$f1创建一个版本test,则s1和s1$f2也会增加一个别名test。

不允许对函数删除版本或别名,因为函数版本和别名是服务及其服务下的其他函数共同的版本和别名。

删除s1$f1的版本3,会收到DeleteVersionNotAllowed错误。

更新函数别名,不改变服务别名,也不影响服务下的其他函数。

更新s1$f1的prod别名,让它从指向版本1变成指向版本2,则只会对s1$f1的别名prod生效,s1和s1$f2的别名prod仍然指向版本1。

使用函数计算2.0API更新服务别名,则服务下的所有函数的别名配置都会被更新。

更新s1的prod别名,让它从指向版本1变成指向版本2,则s1$f1s1$f2的别名prod都被更新成指向版本2.

重要

已有函数在函数计算3.0控制台操作后,函数将具有独立的服务级别配置,之后在函数计算3.0控制台对此函数的操作都只会更新此函数的配置,不会影响同服务下的其他函数。在函数计算2.0控制台,修改服务级别的配置,则会更新该服务下的所有函数对应配置。