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/

相關文章
相關標籤/搜索