
本文介绍了从 AWS Lambda 迁移阿里云函数计算时需要了解的相关概念以及提供了相应的示例。 概念比较 在 AWS Lambda 中,函数是管理 AWS Lambda 的基本资源单位,用户可以在函数级别上授权、配置 CloudWatch 日志。在阿里云函数计算中,除了有函数外还有服务资源。其中,服务是管理函数计算的基本资源单位,可以在服务级别上授权、配置日志和创建函数等;函数是调度与运行的基本单位,也是一段代码的处理逻辑。在阿里云函数计算中,一个服务下可以创建多个函数,每个函数可以设置不同的内存规格、环境变量等属性,这种服务或者函数层次化的抽象,在系统抽象和实现灵活度上能够取得很好的平衡。例如,实现一个微服务,调用阿里云语音合成服务,将文字转成语音,再把这段语音和一系列图片组合为视频。其中文字转语音函数是调用其他服务,可以设置很小的内存规格。而视频合成函数是计算密集型,需要更大的内存。因此,可以通过组合多个不同规格的函数实现微服务,优化成本。 免费开通服务 免费开通函数计算,按量付费,函数计算有很大的免费额度。 接下来,将通过一张表格的形式来呈现 AWS Lambda 与阿里云函数计算的概念比较: 概念 AWS Lambda 函数计算 服务 无 服务是管理函数计算的基本资源单位,可以在服务级别上授权、配置日志和创建函数等 函数 具有处理事件的代码,以及在 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 运行时的函数代码,在该函数中做了以下三件事: 打印 Event 事件信息 打印 Context 上下文信息 返回 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 运行时函数代码有以下两点不同: 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。 函数返回结果的方式在 AWS Lambda Nodejs10.x 中,函数返回结果的代码为 return response;;而在阿里云函数计算 nodejs10 中,函数返回结果的代码为 callback(null, response);。 上述两点的不同是由于阿里云函数计算 Nodejs 普通函数入口和 AWS Lambda Nodejs 函数入口有所不同,阿里云函数计算 Nodejs 普通函数入口有以下三个参数: event 参数 参数是调用函数时传入的数据,其类型是 Buffer,是函数的输入参数。函数不对它的内容进行任何解释,在函数中可以根据实际情况对 event 进行转换。 context 参数 参数中包含一些函数的运行时信息(例如 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。 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,该函数的主要逻辑如下: 当为 S3 触发器配置的事件源发生了相关事件时,事件源将调用该函数。 从 Event 事件信息中获取到事件相关的 Bucket 以及 Key。 访问 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。相关概念如下: 服务角色 Service Role为服务配置服务角色,即允许该服务下的函数扮演这个角色。假设该角色拥有 OSS 的相关权限,则函数通过扮演该角色可以使用 OSS 上的资源。阿里云函数计算的服务角色和 AWS Lambda 中的 Execution Role 是相同的作用。 触发角色 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 的流程逻辑迁移至阿里云函数工作流服务即可。 其他 参考链接 函数计算计费方式 函数计算开发语言列表 函数计算触发器列表 函数计算监控指标 函数计算 Funcraft 工具 函数计算 VSCode 插件 加入我们 团队介绍 阿里云函数服务是一个全新的,支持事件驱动编程模式的计算服务。 他帮助用户聚焦自身业务逻辑,以 Serverless的方式构建应用,快速的实现低成本,可扩展,高可用的系统,而无需考虑服务器等底层基础设施的管理。 用户能够快速的创建原型,同样的架构能随业务规模平滑伸缩。让计算变得更高效,更经济,更弹性,更可靠。无论小型创业公司,还是大型企业,都受益其中。我们的团队正在迅速扩张,求贤若渴。我们想寻找这样的队友:基本功扎实。既能阅读论文追踪业界趋势,又能快速编码解决实际问题。严谨的,系统化的思维能力。既能整体考虑业务机会,系统架构,运维成本等诸多因素,又能掌控设计/开发/测试/发布的完整流程,预判并控制风险。好奇心和使命感驱动。乐于探索未知领域,不仅是梦想家,也是践行者。坚韧、乐观、自信。能在压力和困难中看到机会,让工作充满乐趣!如果您对云计算充满热情,想要构建一个有影响力计算平台和生态体系,请加入我们,和我们一起实现梦想! 职位描述 构建新一代 Serverless 计算平台,包括: 设计和实现完整可扩展的前端系统,包括身份验证/权限管理,元数据管理,流量控制,计量计费,日志监控等等 设计和实现弹性可靠的后端系统,包括资源调度,负载均衡,容错处理等等 丰富易用的 SDK/Tools/CLI/控制台 用户需求驱动,追踪业界趋势,利用技术推动业务的成长 职位要求 算法/数据结构/操作系统等基础知识扎实,优秀的逻辑思维能力。 至少掌握一门编程语言。例如 Java/Go/C/C#/C++。 有大规模、高可用分布式系统开发经验者优先。 有 Web/Mobile Backends/Microservice 开发经验者优先。 良好的沟通能力和团队合作精神,有一定的组织协调能力。 本科及以上学历 3 年以上工作经验 通过“阿里巴巴编码规范” 认证的同学优先录取,认证地址:https://edu.aliyun.com/certification/cldt02 简历提交 yixian.dw AT alibaba-inc.com
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考 本文将重点介绍如何快速地基于函数计算搭建一个 .NET Core 数据库应用。 开通服务 免费开通函数计算,按量付费,函数计算有很大的免费额度。 快速开始 1. 安装最新版本的 Fun2. Clone 工程到本地 git clone git@github.com:vangie/fc-db.git 3. 部署函数计算和云数据库资源至云端 在项目根目录下执行 cd fc-db/rds-mysql 运行 make build 完成构建 运行 fun package 运行 fun deploy --use-ros --stack-name fc-db 完成部署 注意 由于数据库实例会产生一些费用,所以运行之前请确定账号里有余额。当然为了节省用户的开支,我们选用了最小的按量实例,MySQL 数据库的费用是 ¥0.236/小时,体验完成以后,建议去 ROS 的控制台删除所有云资源实例。4. 部署完成后,通过 make invoke_dotnetcore 调用云端函数 $ make invoke_dotnetcore using template: template.yml ========= FC invoke Logs begin ========= FC Initialize Start RequestId: b3a3c027-2355-4e74-8944-6e90bedbe180 表创建成功! FC Initialize End RequestId: b3a3c027-2355-4e74-8944-6e90bedbe180 FC Invoke Start RequestId: b3a3c027-2355-4e74-8944-6e90bedbe180 数据插入成功! FC Invoke End RequestId: b3a3c027-2355-4e74-8944-6e90bedbe180 Duration: 35.10 ms, Billed Duration: 100 ms, Memory Size: 512 MB, Max Memory Used: 35.28 MB ========= FC invoke Logs end ========= FC Invoke Result: csharp 总结 基于 函数计算 服务搭建了一个简易数据库应用,用于创建表并插入数据。通过 Fun 工具,一键部署 函数计算 以及其他相应的云资源,免去去多平台进行操作的步骤。 相关参考 函数计算 Aliyun Serverless VSCode 插件 Fun 参考示例 fc-db
云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 在通过子账号上手使用函数计算的过程中,往往会疑惑为什么在为子账号配置了 AliyunFCFullAccess 后,在登录函数计算控制台以及使用函数计算命令行工具 Fun 时,有时仍旧会遇到权限相关的报错。 本文将分析通过子账号使用函数计算时遇到的权限问题以及对应解决方法,并提供子账号使用函数计算的最佳实践。 通常,子账号在使用函数计算时会在三个方面遇到权限相关的问题: 子账号本身的权限 为服务配置的服务角色的权限 为触发器配置的触发器角色的权限 免费开通服务 免费开通函数计算,按量付费,函数计算有很大的免费额度。 相关知识 在介绍子账号最佳实践前,让我们先来了解下上面提到的服务角色、触发器角色的作用分别是什么。 服务角色服务角色授予了该函数计算服务下的所有函数访问阿里云服务和资源的权限,具体的权限由授予给该服务角色的权限决定。当函数被调用时,函数计算会代入该角色,如果在函数中有访问其他服务的操作(如访问日志服务 SLS),则需要该服务角色有相关的权限,否则无法访问成功。 触发器角色函数计算提供了一种事件驱动的计算模型。在事件驱动的计算模型中,事件源是事件的生产者,函数是事件的处理者,而触发器提供了一种集中的和统一的方式来管理不同的事件源。事件源需要扮演一个角色来触发函数的执行,要求这个角色有触发函数执行的权限 最佳实践 接下来我们会通过结合场景来介绍子账户的开发函数计算的最佳实践。 假设现在有 A 公司,A 公司的技术负责人 L 在阿里云有一个主账号,现在有新的业务需要架设在函数计算上,该业务的开发人员为新来的 N 同学。 那么,现在技术负责人 L 需要如何为 N 同学配置阿里云账号从而使 N 同学可以开发函数计算呢? 新建子账号并添加 FC 相关权限首先 L 需要做的是在 RAM 控制台上创建一个新的用户,配置该用户是否可以登录控制台、是否可以编程访问。此处我们假设 N 同学使用阿里云函数计算命令行工具 Fun 进行本地开发的,因此 L 需要为 N 配置编程访问。当 L 为 N 配置了 AliyunFCFullAccess 权限后,N 就可以在本地开发函数计算并进行远端部署了。 假设 N 在本地开发了一个简单的 HelloWorld 程序。 Fun 工程的模版文件 template.yml 内容 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demo: Type: 'Aliyun::Serverless::Service' Properties: Description: This is demo service func01: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: nodejs8 Timeout: 60 MemorySize: 512 CodeUri: demo/func01 函数的入口文件 demo/func01/index.js 的文件内容 'use strict'; module.exports.handler = function(event, context, callback) { console.log(new String(event)); callback(null, 'hello world'); } 此时,N 可以通过 fun deploy 将 demo/func01 函数部署到远端。 假设 N 想让该函数的日志能够持久化保存下来,N 这个时候需要为 demo 服务配置日志项目和日志仓库。假设 A 公司在日志服务 SLS 有 logProject01 日志项目和 logStore01 日志仓库。N 在模版文件 template.yml 中为 demo 服务配置了如下内容: 模版文件 template.yml 内容 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demo: Type: 'Aliyun::Serverless::Service' Properties: Description: This is demo service LogConfig: Project: logProject01 # 日志项目 Logstore: logStore01 # 日志仓库 func01: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: nodejs8 Timeout: 60 MemorySize: 512 CodeUri: demo/func01 创建服务角色并为子账号配置 PassRole 权限 此时,N 无法通过 fun deploy 成功部署。为什么呢? 因为此时 N 缺少 RAM 相关权限,无法创建角色并授予 demo 服务。此时,有两种做法可以完成该操作: 第一种方法:向技术负责人 L 申请为 N 的子账号授予 AliyunRAMFullAccess 的权限。这样 N 在使用 fun deploy 的时候,可以成功创建出拥有对 logProject01 和 logStore01 进行操作的 RAM 角色,并将该角色配置给 demo 服务。 第二种方法 由技术负责人 L 创建一个 RAM 角色(假设角色名为 demo-service-role),该角色拥有对 logProject01 和 logStore01 进行操作的权限,并且该角色的受信实体为函数计算。 技术负责人 L 为 N 配置 ram:PassRole 权限,使得 N 有权限为服务配置角色。 N 在模版文件 template.yml 中为 demo 服务配置角色 demo-service-role 在子账号实践中,更加推荐使用第二种方法,相比第一种方法来说更加安全。假设 L 创建了 RAM 角色(demo-service-role),并且给 N 配置了 ram:PassRole。此时,N 在模版文件 template.yml 中为 demo 服务配置角色 demo-service-role。 模版文件 template.yml 内容 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demo: Type: 'Aliyun::Serverless::Service' Properties: Description: This is demo service Role: acs:ram:::role/demo-service-role LogConfig: Project: logProject01 Logstore: logStore01 func01: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: nodejs8 Timeout: 60 MemorySize: 512 CodeUri: demo/func01 此时,N 因为有了 ram:PassRole 权限,可以成功的将 demo-service-role 配置给 demo 服务,部署到线上。这时,demo/func01 函数就可以将日志持久化记录在 SLS 日志服务中了。 假设,N 此时希望为函数 demo/func01 配置一个 OSS 触发器,N 编写的模版文件 template.yml 内容如下: 模版文件 template.yml 内容 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demo: Type: 'Aliyun::Serverless::Service' Properties: Description: This is demo service Role: acs:ram:::role/demo-service-role LogConfig: Project: logProject01 Logstore: logStore01 func01: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: nodejs8 Timeout: 60 MemorySize: 512 CodeUri: demo/func01 Events: ossTrigger: Type: OSS Properties: BucketName: ossBucketName Events: ["oss:ObjectCreated:*"] Filter: Key: Prefix: source/ Suffix: .png 创建触发器角色此时,N 同样无法通过 fun deploy 完成部署。因为 N 想创建的 OSS 触发器,需要为该触发器配置一个有权限调用函数的角色。而在模版文件中未显式声明该角色,Fun 同样会尝试去创建角色,而 N 用的子账户只有 ram:PassRole 权限,没有其他关于 RAM 的权限,所以无法创建成功。这时的解决方法和最初的服务角色差不多: 由技术负责人 L 创建一个 RAM 角色(假设角色名为 oss-trigger-invocation-role),该角色拥有对函数计算中的函数进行调用的权限,并且该角色的受信实体为 OSS 对象存储服务。 技术负责人 L 为 N 配置 AliyunOSSFullAccess 权限,使得 N 可以访问 OSS。 上述配置完成后,N 可以修改模版文件内容为: 模版文件 template.yml 内容 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: demo: Type: 'Aliyun::Serverless::Service' Properties: Description: This is demo service Role: acs:ram:::role/demo-service-role LogConfig: Project: logProject01 Logstore: logStore01 func01: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: nodejs8 Timeout: 60 MemorySize: 512 CodeUri: demo/func01 Events: ossTrigger: Type: OSS Properties: BucketName: ossBucketName Events: ["oss:ObjectCreated:*"] Filter: Key: Prefix: source/ Suffix: .png InvocationRole: acs:ram:::role/oss-trigger-invocation-role 此时,N 可以通过 fun deploy 部署成功。 总结 根据上面最佳实践的例子,我们可以总结出如下几点经验: 若希望函数可以访问其他服务,需要为函数所在的服务配置服务角色,该服务角色其实是 RAM 角色拥有对于其他服务或资源的访问权限,并且受信实体为函数计算。 若希望为函数配置外部事件源,需要为该事件源触发器配置触发器角色,该角色拥有触发函数的权限,并且受信实体为事件源所在的服务。 若希望子账号可以为服务配置服务角色或为触发器配置触发器角色,需要授予子账号 ram:PassRole 权限以及对应事件源的权限。 常见问题梳理: 下述的问题梳理都是基于已经为子账号配置了 AliyunFCFullAccess 后,使用函数计算控制台或命令行工具 Fun 时会遇到的问题。 Q: 控制台首页提示 账号缺少AliyunCloudMonitorReadOnlyAccess权限 。 A: 函数计算控制台首页的监控数据信息:本月执行次数、本月资源使用量、公网流量是来自于云监控 CloudMonitor 服务的,如果子账号希望查看相关数据信息,需要在 RAM 控制台为当前子账号配置 AliyunCloudMonitorReadOnlyAccess 权限。 Q: 控制台应用中心提示 账号缺少AliyunROSFullAccess权限 。 A: 函数计算控制台中应用中心的某些功能是依赖于阿里云资源编排 ROS 服务的,如果子账号希望使用应用中心的功能,需要在 RAM 控制台为当前子账号配置 AliyunROSFullAccess 权限。 Q: 在控制台服务配置中,专有网络配置下的专有网络下拉框没有列举出已有的专有网络。 A: 这是由于子账号缺少查看 VPC 的权限,在 RAM 控制台中为当前子账号配置 AliyunVPCReadOnlyAccess 即可。 Q: 在控制台服务配置中,日志配置下的日志仓库下拉框没有列举出已有的日志仓库。 A: 和专有网络配置时遇到的问题相似,是由于子账号缺少查看日志服务 SLS 的权限,在 RAM 控制台中为当前子账号配置 AliyunLogReadOnlyAccess 即可。 Q: 在控制台服务配置中,角色配置展开提示 获取角色列表权限不足,需要 RAM 相关权限 。 A: 是由于子账号缺少查看 RAM 角色的权限,在 RAM 控制台中为当前子账号配置 AliyunRAMReadOnlyAccess 即可。 Q: 在 Fun 工程的模版文件中为服务配置了 Policies,部署时提示没有相关 RAM 权限。 A: Fun 在遇到为服务配置了 Policies 的情况下,会用当前 Fun 配置下的 AK 信息,使用 RAM 服务做创建角色、为角色授权、为服务配置角色等一系列操作,此时需要子账户有相关操作的 RAM 权限。如果希望子账号可以完成这些操作,需要在 RAM 控制台为当前子账号配置 AliyunRAMFullAccess 权限。这不是特别推荐的做法,上文中的最佳实践有讲述到相关内容。 Q: 子账号拥有访问其他服务的权限,但是创建出来的函数运行时无法访问其他服务。 A: 函数是否能够访问其他服务与子账号本身的权限无关,与该函数所在服务配置的服务角色有关。如果希望函数可以访问 A 服务,则需要为函数所在的服务配置下的服务角色授权访问 A 服务。 参考资料 函数计算 RAM Funcraft Aliyun Serverless VSCode 云栖号在线课堂,每天都有产品技术专家分享立即加入圈子:https://c.tb.cn/F3.Z8gvnK与专家面对面,及时了解课程最新动态! 原文发布时间:2020-01-09本文作者:泽尘本文来自:“阿里云云栖社区”,了解相关信息可以关注“阿里云云栖社区”
快速搭建 Serverless 人脸识别离线服务 简介 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考函数工作流(Function Flow):函数工作流是一个用来协调多个分布式任务执行的全托管云服务。用户可以用顺序,分支,并行等方式来编排分布式任务,FnF 会按照设定好的步骤可靠地协调任务执行,跟踪每个任务的状态转换,并在必要时执行用户定义的重试逻辑,以确保工作流顺利完成。函数工作流更多信息参考 本文将重点介绍如何快速地通过函数计算与函数工作流部署一个定时离线批量处理图片文件并标注出人脸的服务。 开通服务 免费开通函数计算,按量付费,函数计算有很大的免费额度。 免费开通函数工作流,按量付费,目前该产品在公测阶段,可以免费使用。 免费开通对象存储,按量付费。 解决方案 流程如下: 设定定时触发器,定时触发函数计算中的函数。 函数被触发后,调用一次函数工作流中的流程。 函数工作流中的流程被执行: 调用函数计算中的函数,列举出 OSS Bucket 根路径下的图片文件列表。 对于步骤1中列出的文件列表,对每个文件: 调用函数计算中的函数处理,进行人脸识别并标注。将标注后的文件存入 OSS,最后将处理过的文件进行转移。 判断当前 OSS 根路径下是否有更多的文件 如是,继续步骤1 如否,结束流程 快速开始 Clone 工程到本地 git clone git@github.com:ChanDaoH/serverless-face-recognition.git 替换项目目录下 template.yml 文件中的 YOUR_BUCKET_NAME 为在杭州区域的 OSS Bucket (可以不是杭州区域的,需要同步修改 OSS_ENDPOINT) ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: face-recognition: Type: 'Aliyun::Serverless::Service' Properties: Policies: - Version: '1' Statement: - Effect: Allow Action: - 'oss:ListObjects' - 'oss:GetObject' - 'oss:PutObject' - 'oss:DeleteObject' - 'fnf:*' Resource: '*' listObjects: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: python3 Timeout: 60 MemorySize: 128 CodeUri: functions/listobjects EnvironmentVariables: OSS_ENDPOINT: 'https://oss-cn-hangzhou-internal.aliyuncs.com' detectFaces: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: python3 Timeout: 60 MemorySize: 512 CodeUri: functions/detectfaces EnvironmentVariables: OSS_ENDPOINT: 'https://oss-cn-hangzhou-internal.aliyuncs.com' timer: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: python3 Timeout: 60 MemorySize: 512 CodeUri: functions/timer Events: timeTrigger: Type: Timer Properties: CronExpression: '0 * * * * *' Enable: true # replace YOUR_BUCKET_NAME to your oss bucket name Payload: '{"flowName": "oss-batch-process", "input": "{\"bucket\": \"YOUR_BUCKET_NAME\",\"prefix\":\"\"}"}' oss-batch-process: Type: 'Aliyun::Serverless::Flow' Properties: Description: batch process flow DefinitionUri: flows/index.flow.yml Policies: - AliyunFCInvocationAccess 一键部署函数计算和函数工作流资源至云端 安装最新版本的 Fun 在项目根目录下执行 fun deploy 效果验证 在 OSS Bucket 的根目录下放置图片 等待一分钟后,定时触发器触发函数执行函数工作流。 工作流执行完成后,查看 OSS Bucket 标注出人脸的图像放置在 face-detection 目录下 处理过的录像放置在 processed 目录下 总结 通过 函数计算 + 函数工作流,搭建了一个定时批量处理图片进行人脸识别的服务。该服务因为使用了函数工作流的流程,将任务分为了多个步骤,只需要确保每个步骤的函数能够在函数计算限制时间(10分钟)内完成即可。通过 Fun 工具,一键部署 函数计算 + 函数工作流,免去去多平台进行操作的步骤。 相关参考 函数计算 函数工作流 Aliyun Serverless VSCode 插件 Fun 参考示例 serverless-face-recognition oss-batch-process
简介 随着具有不同屏幕尺寸和分辨率设备的爆炸式增长,开发人员经常需要提供各种尺寸的图像,从而确保良好的用户体验。目前比较常见的做法是预先为一份图像存放多份具有不同尺寸的副本,在前端根据用户设备的 media 信息来请求特定的图像副本。 预先为一份图像存放多份具有不同尺寸副本的行为,经常是通过 阿里云函数计算 FC 以及阿里云对象存储 OSS 两大产品实现的。用户事先为 FC 中的函数设置对象存储触发器,当在存储桶中创建了新对象(即 putObject 行为,此处指在 OSS bucket 中存放了图像),通过 OSS 触发器来触发函数对刚刚存放的图像进行处理,处理成不同尺寸的副本后,将这些副本存放进 OSS bucket。 上述方法的特点是预先处理,如果要处理的图像尺寸较多,那么当图像数量非常大的时候,会占用很多存储空间。假设要处理的图像尺寸数目为 x、图像数量为 y、平均每份图像的大小为 z,那么要占用的存储空间为 x y z。 动态调整图像大小为了避免无用的图像占用存储空间,可以使用动态调整图像大小的方法。在 OSS bucket 中预先只为每份图像存放一个副本,当前端根据用户设备的 media 信息来请求特定尺寸图像副本时,再生成相关图像。 步骤: 用户通过浏览器请求 OSS bucket 中特定的图像资源,假设为 800 * 600 的 image.jpg。 OSS bucket 中没有相关的资源,将该请求重定向至生成特定尺寸图像副本的 api 地址。 浏览器根据重定向规则去请求调整图像大小的 api 地址。 触发函数计算的函数来执行相关请求。 函数从 OSS bucket 中下载到原始图像 image.jpg,根据请求内容生成调整后的图像,上传至 OSS bucket 中。 将请求重定向至图像在 OSS bucket 中的位置。 浏览器根据重定向规则去 OSS bucket 中请求调整大小后的图像。 上述方法的特点是: 即时处理。 降低存储成本。 无需运维。 实践 1. 创建并配置 OSS 在 OSS 控制台 中,创建一个新的 Bucket,读写权限选择公共读 (用于本教程示例,可之后更改)。 在 Bucket 的基础设置中,设置镜像回源。 回源类型:重定向 回源条件:HTTP 状态码 404 回源地址:选择添加前后缀,并在回源域名中填写一个已接入阿里云备案的自定义域名。 重定向 Code:302 2. 创建 FC 函数 下载 serverless-image-on-the-fly 项目到本地 git clone git@github.com:ChanDaoH/serverless-image-on-the-fly.git 进入项目目录,执行 npm install 填写 template.yml 文件中的相关内容:OSS_REGION、OSS_BUCKET_NAME、自定义域名 ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: serverless-image: Type: 'Aliyun::Serverless::Service' Properties: Description: This is serverless-image service Policies: - AliyunOSSFullAccess image-resize: Type: 'Aliyun::Serverless::Function' Properties: Handler: src/index.handler Runtime: nodejs10 Timeout: 60 MemorySize: 512 CodeUri: ./ EnvironmentVariables: OSS_REGION: oss-cn-shanghai # oss region, such as oss-cn-shanghai、oss-cn-hangzhou OSS_BUCKET_NAME: images-xxx # oss bucket name Events: httpTrigger: Type: HTTP Properties: AuthType: ANONYMOUS Methods: - GET - POST william.functioncompute.com: # domain name Type: 'Aliyun::Serverless::CustomDomain' Properties: Protocol: HTTP RouteConfig: routes: '/*': ServiceName: serverless-image FunctionName: image-resize 部署函数至云端 可以通过 Serverless VSCode 插件 部署 可以通过 fun 部署 3. 测试动态调整图像 在 OSS bucket 中上传一张图像,假设为 image.jpg 。 此时请求 https://{OSS_BUCKET_NAME}.{OSS_REGION}.aliyuncs.com/{width}*{height}/image.jpg。会有如下效果: 下载到指定 width * height 大小的 image.jpg。 OSS bucket 中有 width * height 命名的目录,该目录下有 image.jpg。 总结 我们通过 FC + OSS 搭建了一个实时按需图像处理服务,该服务拥有以下特点: 即时处理 降低存储成本 无需运维 资料 函数计算 Function Compute Aliyun Serverless VSCode 插件 Fun
2019年11月
2019年10月
2019年09月
2019年08月
2019年07月