Serverless 解惑——AWS Lambda 迁移阿里云函数计算指南

概念比较

在 AWS Lambda 中,函数是管理 AWS Lambda 的基本资源单位,用户能够在函数级别上受权、配置 CloudWatch 日志。在阿里云函数计算中,除了有函数外还有服务资源。其中,服务是管理函数计算的基本资源单位,能够在服务级别上受权、配置日志和建立函数等;函数是调度与运行的基本单位,也是一段代码的处理逻辑。
在阿里云函数计算中,一个服务下能够建立多个函数,每一个函数能够设置不一样的内存规格、环境变量等属性,这种服务或者函数层次化的抽象,在系统抽象和实现灵活度上可以取得很好的平衡。例如,实现一个微服务,调用阿里云语音合成服务,将文字转成语音,再把这段语音和一系列图片组合为视频。其中文字转语音函数是调用其余服务,能够设置很小的内存规格。而视频合成函数是计算密集型,须要更大的内存。所以,能够经过组合多个不一样规格的函数实现微服务,优化成本。javascript

免费开通服务php

  1. 免费开通函数计算,按量付费,函数计算有很大的免费额度。

接下来,将经过一张表格的形式来呈现 AWS Lambda 与阿里云函数计算的概念比较:html

概念java

AWS Lambdanode

函数计算python

服务git

github

服务是管理函数计算的基本资源单位,能够在服务级别上受权、配置日志和建立函数等api

函数promise

具备处理事件的代码,以及在 Lambda 与函数代码之间传递请求和响应的运行时

是调度与运行的基本单位,具备处理事件的代码,以及在阿里云函数计算服务与函数代码之间传递请求和响应的运行时

运行时(Runtime)

位于 Lambda 服务和函数代码之间,并在两者之间传递调用事件、上下文信息和响应。支持的运行时清单

位于阿里云函数计算服务和函数代码之间,并在两者之间传递调用事件、上下文信息和响应。支持的运行时清单

并发

在调用函数时,Lambda 会预配置其实例以处理事件。当函数代码完成运行时,它会处理另外一个请求。若是当仍在处理请求时再次调用函数,则预配置另外一个实例,从而增长该函数的并发性。并发限制

在函数计算 1.0 中,一个函数实例最多只能同时处理一个请求,若是当仍在处理请求时再次调用函数,则预配置另外一个实例,从而增长该函数的并发性。在函数计算 2.0 中,函数计算支持了单实例并发处理多请求功能。并发限制

触发器

触发器是调用 Lambda 函数的资源或配置。这包括可配置为调用函数的 AWS 服务、用户开发的应用程序以及事件源映射。事件源映射是 Lambda 中的一种资源,它从流或队列中读取项目并调用函数。触发器列表

触发器是触发函数执行的方式,触发器提供了一种集中的和统一的方式来管理不一样的事件源。在事件源中,当事件发生时,若是知足触发器定义的规则,事件源则调用触发器所对应的函数。触发器列表

开发工具 & SDK

下述表格为 AWS Lambda 与阿里云函数计算的开发工具 & SDK:

类型

AWS Lambda

函数计算

命令行

AWS Command Line Interface (AWS CLI)

Fcli: 阿里云函数计算的命令行工具,帮助用户便捷的管理函数计算中的资源

命令行

SAM CLI

Funcraft: 用于支持 Serverless 应用部署的工具,能帮助用户便捷地管理函数计算、API 网关、日志服务等资源。Funcraft 经过一个资源配置文件(template.yml),协助用户进行开发、构建、部署操做

IDE

AWS Toolkit Extension

Aliyun Serverless VSCode Extension: 结合了 函数计算 Funcraft 工具 以及函数计算 SDK ,是基于 VSCode 的开发调试部署工具;以及其余平台上的Cloud Toolkit

IDE

C9

FC WebIDE

SDK

Node.js:SDK for Javascript

Node.js:fc-nodejs-sdk

SDK

Python:SDK for Python

Python:fc-python-sdk

SDK

PHP:SDK for PHP

PHP:fc-php-sdk

SDK

Java:SDK for Java

Java:fc-java-sdk

SDK

Go:SDK for Go

Go:fc-go-sdk

SDK

C#:SDK for .NET

C#:fc-csharp-sdk

简单示例

迁移 Hello World 函数

接下来将介绍如何将 AWS Lambda 的一个简单示例迁移至阿里云函数计算服务。

exports.handler = async (event, context) => {
    console.log(`Event: ${JSON.stringify(event)}`);
    console.log(`Context: ${JSON.stringify(context)}`);
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
    };
    return response;
};

上述为 AWS Lambda Nodejs10.x 运行时的函数代码,在该函数中作了如下三件事:

  1. 打印 Event 事件信息
  2. 打印 Context 上下文信息
  3. 返回 Response 对象,内容为

    {
       "statusCode": 200,
       "body": "\"Hello World!\"",
    }

    咱们将其迁移至阿里云函数计算服务,根据快速入门/HelloWorld 示例中的内容建立好 nodejs10 运行时的函数代码,修改代码内容以下:

module.exports.handler = function(event, context, callback) {
  console.log(`Event: ${JSON.stringify(JSON.parse(event))}`);
  console.log(`Context: ${JSON.stringify(context)}`);
  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello World!'),
  };
  callback(null, response);
}

上述为阿里云函数计算 nodejs10 运行时的函数代码。注意,该函数代码和 AWS Lambda Nodejs10.x 运行时函数代码有如下两点不一样:

  1. event 参数的输出方式
    在 AWS Lambda Nodejs10.x 中,输出 event 的代码为console.log(`Event: ${JSON.stringify(event)}`);;而在阿里云函数计算 nodejs10 中,输出 event 的代码为console.log(`Event: ${JSON.stringify(JSON.parse(event))}`);。在 AWS Lambda 中,事件 Event 传入的类型是 JSON 对象;而在阿里云函数计算中,事件 Event 传入的类型是 Buffer。
  2. 函数返回结果的方式
    在 AWS Lambda Nodejs10.x 中,函数返回结果的代码为return response;;而在阿里云函数计算 nodejs10 中,函数返回结果的代码为callback(null, response);

上述两点的不一样是因为阿里云函数计算 Nodejs 普通函数入口和 AWS Lambda Nodejs 函数入口有所不一样,阿里云函数计算 Nodejs 普通函数入口有如下三个参数:

  1. event 参数
  2. 参数是调用函数时传入的数据,其类型是 Buffer,是函数的输入参数。函数不对它的内容进行任何解释,在函数中能够根据实际状况对 event 进行转换。
  3. context 参数
  4. 参数中包含一些函数的运行时信息(例如 request id / 临时 AK 等),其类型是 object。包含如下信息:

    • requestId: 本次调用请求的惟一 id。
    • function: 当前调用的函数的一些基本信息如函数名 / 函数入口 / 函数内存 / 超时时间
    • credentials: 函数计算服务经过扮演用户提供的服务角色得到的一组临时密钥,其有效时间是 6 小时。能够在代码中使用它去访问相应的服务( 例如 OSS )
    • service: 当前调用的函数所在的 service 的信息,包括 service 的名字,接入的 SLS 的 logProject 和 logStore 信息,service的版本信息qualifier和version_id,qualifier表示调用函数时指定的service版本或别名,version_id表示实际调用的service版本。
    • region: 当前调用的函数所在区域,如 cn-shanghai。
    • accountId: 当前调用函数用户的阿里云 account id。
  5. callback 参数

    • callback 参数用于返回调用函数的结果,其签名是 function(err, data),与 Node.js 中惯用的 callback 同样,它的第一个参数是 error ,第二个参数 data 。若是调用时 err 不为空,则函数将返回 HandledInvocationError ,不然将返回 data 的内容。若是 data 是 Buffer 类型则它的数据将直接被返回,若是 data 是 object ,则会将其转换成 JSON 字符串返回,其余类型将被转换成 string 返回。

更多内容能够参考Node.js 函数入口

复杂示例

迁移 S3 触发 Lambda 的函数

接下来将介绍如何将 AWS Lambda 带有 S3 触发器并访问 S3 的简单示例函数迁移至阿里云函数计算服务。

console.log('Loading function');

const aws = require('aws-sdk');

const s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = async (event, context) => {
    // Get the object from the event and show its content type
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };
    try {
        const result = await s3.getObject(params).promise();
        console.log(result);
        return result;
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(err);
    }
};

上述为 AWS Lambda Nodejs10.x 运行时的函数代码,该函数配置了 S3 触发器以及相应的 Execution Role,该函数的主要逻辑以下:

  1. 当为 S3 触发器配置的事件源发生了相关事件时,事件源将调用该函数。
  2. 从 Event 事件信息中获取到事件相关的 Bucket 以及 Key。
  3. 访问 S3 获取到相关对象。

咱们将其迁移至阿里云函数计算服务,根据快速入门/HelloWorld 示例中的内容建立好 nodejs10 运行时的函数代码,修改代码内容以下:

const oss = require('ali-oss');

module.exports.handler = async (event, context) => {
    // Get the object from the event and show its content type
    const event = JSON.parse(event);
    const bucket = event.events[0].oss.bucket.name;
    const key = event.events[0].oss.object.key;
    let client = new OSS({
      bucket: bucket,
      accessKeyId: context.credentials.accessKeyId,
      accessKeySecret: context.credentials.accessKeySecret,
      stsToken: context.credentials.securityToken,
    });
    try {
        const result = await client.get(key);
        console.log(result);
        callback(null, result);
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}.`;
        console.log(message);
        callback(err);
    }
};

上述为阿里云函数计算 nodejs10 运行时的函数代码,代码逻辑和 AWS Lambda 大体相同。其中,OSS 为阿里云对象存储服务。除此以外,还须要为该函数配置 OSS 触发器以及相应的 ServiceRole 和 InvocationRole。相关概念以下:

  1. 服务角色 Service Role
    为服务配置服务角色,即容许该服务下的函数扮演这个角色。假设该角色拥有 OSS 的相关权限,则函数经过扮演该角色可使用 OSS 上的资源。阿里云函数计算的服务角色和 AWS Lambda 中的 Execution Role 是相同的做用。
  2. 触发角色 Invocation Role
    触发角色,事件源须要扮演一个角色来触发函数的执行,要求这个角色有触发函数执行的权限。关于事件源角色的详细信息请参考文章权限简介

除了上述的服务角色和触发角色外,还须要注意的一点是,在函数中是经过以下的代码片断生成了 OSS client:

let client = new OSS({
  bucket: bucket,
  accessKeyId: context.credentials.accessKeyId,
  accessKeySecret: context.credentials.accessKeySecret,
  stsToken: context.credentials.securityToken,
});

context 参数中包含了credentials信息,函数计算服务经过扮演用户为服务配置的服务角色得到的一组临时密钥。用户能够在代码中使用它去访问相应的服务( 例如 OSS ),这就避免了把本身的 AK 信息写死在函数代码里。

迁移 AWS Step Functions 调用 AWS Lambda

接下来将介绍如何将 AWS Step Functions 调用 AWS Lambda 的简单示例迁移至阿里云函数工做流和函数计算服务。

{
  "StartAt": "Hello",
  "States": {
    "Hello": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-southeast-1::function:helloworld",
      "End": true
    }
  }
}

上述为 AWS Step Functions 的流程代码,该流程调用了 AWS Lambda 的函数,假设调用的函数代码为简单示例中的 Hello World 函数。

咱们将其迁移至阿里云函数工做流服务,根据快速入门/建立流程中的内容建立好 函数工做流的流程,修改流程代码内容以下:

version: v1beta1
type: flow
steps:
  - type: task
    name: helloworld
    resourceArn: acs:fc:cn-hangzhou::services/helloworld/functions/sayHello

上述为阿里云函数工做流服务的流程代码,代码逻辑和 AWS Step Functions 大体相同。能够看到,当将 AWS Lambda 成功迁移至阿里云函数计算服务后,若是有迁移 AWS Step Functions 调用 AWS Lambda 的需求,只须要将 AWS Step Functions 的流程逻辑迁移至阿里云函数工做流服务便可。

查看更多:https://yqh.aliyun.com/detail..._content=g_1000106528

上云就看云栖号:更多云资讯,上云案例,最佳实践,产品入门,访问:https://yqh.aliyun.com/

相关文章
相关标签/搜索