转载

用 Node.js 和 AWS Lambda 创建无服务器的微服务

在本文中,我们将使用 Lambda—Amazon Web Services(AWS)套件中的一个新工具—来启动并运行一个微服务。 我们将使用 Lambda 创建一个 HTTP GET 终端,该终端使用 GitHub 的API 发起请求,从 GitHub 中提取存储库信息并返回一个 JSON 响应。

为方便你可以按本文中的步骤进行操作,你将需要一个自己的 AWS 账户。 如果没有,您可以在  https://aws.amazon.com/ 上创建免费的AWS账户。

什么是 AWS Lambda?

Lambda 的口号是:“运行代码不用考虑服务器”。乍一看,这可能让人觉得比较困惑。 代码究竟是在哪里或如何运行的呢?

无服务器与函数即服务

“无服务器”是一个新的软件基础设施术语,你可能有所耳闻。 它用于描述按需执行代码的解决方案。“无服务器”这个术语可能会误导大家,因为事实上,在程序中仍然有服务器。 更好的描述符是 FaaS 或“函数即服务”。

这两个定义用于描述新的开发和部署经验。 这种新体验被认为是“无服务器”的,因为作为开发人员,不再需要管理,监视或扩展正在运行代码的任何服务器。 您只需将代码上传到 FaaS 提供服务的程序(在本例中为 AWS Lambda),FaaS 提供程序将在后台帮你执行代码并管理所有的基础架构。

无服务器架构的利弊

鉴于这一“无服务器”架构扩展的定义,让我们来看看用 Lambda 工作的一些利弊。

优点

  • 按需使用定价

    传统的服务器托管使用重复计费周期。 你的服务器总是启动和运行使用资源和等待输入。  为了保持服务器正常运行,你按月或按年作为账单周期来支付费用。用按需定价,Lambda 按每个函数的使用进行计费。这意味着你的项目利用 Lambda 的功能是不频繁的,相比传统的托管解决方案,你可以节省大量的金钱。

    Lambda 定价如下:

    了解更多: https://aws.amazon.com/lambda/pricing/

    • 每 100 万个请求 0.20 美元

    • 每 GB 秒的计算时间 0.00001667 美元,每次执行时间接近 100ms

  • 内置的自动伸缩功能 

    在一个传统的被托管的基础设施中, 你会进入到这样一个时期,你可能需要担心性能和扩展性。随着应用程序使用量和通信量的增加,您可能需要添加更多的托管服务器基础设施来跟上需求。对于你的用户,这可能导致失败,成为瓶颈。 当需要增加或减少额外的开销时,Lambda 会自动完成扩展性。

缺点

  • 与本地开发工作流程不一致。

    你可以在本地写 Lambda 功能代码,隔离测试,但是在没有创建你的拼装版的 Lambda,你不能在本地模拟生产环境。

Lambda 关键概念

函数代码和触发器

Lambda 有两个主要概念:代码和触发器。 代码是不言自明的。 在我们的示例中,就是那些由您编写并上传到 Lambda 以产生你所需行为的 JavaScript 代码。

一旦你上传后,代码不会自行执行。 Lambda 有一个称为“触发器”的附加概念。触发器是由其他 AWS 服务触发的事件,它们将数据传递到 Lambda 函数以供执行。

一些示例触发器:

  • 用指向 AWS API 网关的 HTTP 请求来触发 Lambda 代码。

  • 用轮循的事件触发,例如来源于 CloudWatch 事件的 corn 任务。

  • 用 DynamoDB 表的更新来触发 Lambda 代码。

Lambda 代码函数签名

你可以从与预期的 Lambda 签名相匹配的 JavaScript 中,通过导出一个常规函数来定义一个 Lambda 函数。

exports.myLambdaFunction = (event, context, callback) => {
   // Use callback() and return 
}

该函数接收3个参数:

  1. event— Lambda 传递给函数的'触发数据'的键值对字典。

  2. context— AWS 内部信息,例如 AWS 请求ID, Lambda 超时时间, 和日志信息.

    更多详细信息请看: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

  3. callback— 一个标准的 JavaScript 异步回调句柄。

    更多详细信息请看: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback

建设Lambda函数

开始创建新的 Lambda 函数。访问 Lambda 仪表盘:

https://console.aws.amazon.com/lambda/home?region=us-east-1#/functions?display=list

然后会看到像这样的界面: 用 Node.js 和 AWS Lambda 创建无服务器的微服务

点击蓝色的按钮 创建 Lambda 函数(Create a Lambda function) 来开始。

选择设计图

下一个界面会提示你 选择一个设计图(Select a blueprint) 并提供一个可过滤的设计图列表。点击 空函数(Blank Function) 选项,它应该是设计图列表中的第一个选项。这个页面可用于将来参考着使用其它工具。

配置触发器

接下来的界面是 配置触发器(Configure Triggers) ,显示成这样:

用 Node.js 和 AWS Lambda 创建无服务器的微服务

点击 下一步(Next) 离开这个界面。我们会在后面,建立起我们的函数之后,再来定义触发器。

配置函数

用 Node.js 和 AWS Lambda 创建无服务器的微服务

在这一部分,需要给 Lambda 函数一个名称。我会使用 GithubGet 这个名称。你也可以填写对这个函数的描述,这是可选的。

指定 Lambda 函数代码

默认情况下,Lambda UI 设置为内联编辑代码。 您应该看到一个内联编辑器,编辑器中有一个样本函数,如下所示:

用 Node.js 和 AWS Lambda 创建无服务器的微服务

内联编辑器需要很少的开销来获取和运行 lambda 代码,但对于本教程,我们将做一些更进阶的事情。

创建复杂的函数依赖关系

在大多数真实环境中,你如果要创建更多的复杂函数,常常需要通过npm来安装第三方的库。

让我们创建一个使用 npm 依赖项的自定义函数,并将其上传到Lambda。 您可以按照下面的步骤,或者可随意使用 示例代码库 中的代码

创建一个新的函数

让我们为我们的新函数设置一个文件夹,并在文件夹中用默认的 package.json 文件初始化 npm:

npm init -f

接下来,我们将安装 GitHub 客户端:

npm install github

创建 index.js 文件,使用以下代码:

var GitHubApi = require('github');
var github = new GitHubApi();

exports.handler = (event, context, callback) => {

  github.search.repos({
    q: 'sitepoint',
    sort: 'stars'
  }, function(err, res){
    if(err){
      callback(err);
    }

    var results = res.items.map((repo) => {
      return {
        url: repo.html_url,
        stars: repo.stargazers_count
      };
    });

    callback(null, {
      statusCode: 200,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(results)
    });
  });

};

下面是这段代码的功能细节:

  1. 引入并初始化了 GitHubAPI

  2. 定义了一个与 Lambda 签名匹配的 handler 函数。

  3. 当 handler 函数被调用时,它会发出一个查询请求到 GitHub,对所有符合‘sitepoint’的数据仓库进行查询。

  4. 在 Github 的应答格式中,创建了一个 map 数据结构,其中包含了每个数据仓库的网址和星标数。

  5. 最后,用 http 响应(如对象)调用 Lambda 的回调函数,好与 API 网关预计集成 相匹配。

将代码上传到AWS Lambda

任意使用一个你熟悉的 zip 工具,创建一个包含函数文件的 zip 压缩包。我在 OS X 系统上使用 zip 命令行是这样的:

zip -r lambdaupload.zip ./index.js ./node_modules/

要将代码上传到 Lambda, 在内联编辑器的 “代码条目类型” 选项上选择 “ 上传 zip 文件 ”,然后使用弹出的窗口上传您的代码。

用 Node.js 和 AWS Lambda 创建无服务器的微服务

配置函数的 handler 和任务

在这一部分下,我们要设置几个值。 Handler 是在上传的 JavaScript 文件中 Lambda 函数的引用。 默认情况下,它设置为 index.handler。hander 函数通过查找 index 文件与我们上传的文件相映射,并为我们 hander 函数检索出与我们 export.handler 文件相对应的的导出语句。

使用以下信息填写“Role”字段,为创建 Lambda 函数的基本角色:

  • Role: 从模板中创建新的 role

  • Role name: Lambda 获取 Role

  • Policy templates: 简单的微服务权限

这部分完成后, 单击“Next” 按钮继续。比可以看到  ‘Review’ 界面的概述配置:

用 Node.js 和 AWS Lambda 创建无服务器的微服务

如果一切正常,单击“创建函数”按钮继续。

为新函数分配触发器

既然我们的函数已经创建并初始化了,我们需要一种方法来调用它。现在是时候为该函数分配触发器了。对于触发器的实现,我们将使用 API 网关。

API 网关是另一种 AWS 服务,它能自动创建可配置响应源的 HTTP 终端。我们将把我们的 Lambda 函数作为 API 网关的响应。

  1. 点击‘Triggers’(触发器)

  2. 点击‘Add trigger’

  3. 点击lambda旁边的空白区域

  4. 选择“API Gateway”

  5. 在安全性中选择“Open”

  6. 点击提交

这些步骤可以在下面动画中看到:

用 Node.js 和 AWS Lambda 创建无服务器的微服务

当成功添加触发器之后,你应该可以在 Triggers 标签中看到触发器和你的函数被关联起来。

用 Node.js 和 AWS Lambda 创建无服务器的微服务

在 API 网关 ID 中会列出一个 URL。你可以访问在浏览器中这个 URL,然后你赢高可以看到一个 JSON 响应,类似下面的日志:

[{"url":"https://github.com/bodrovis/Sitepoint-source","stars":106},
{"url":"https://github.com/Azzurrio/moviestore","stars":80},
{"url":"https://github.com/bodrovis/SitepointMiniChat","stars":54},
{"url":"https://github.com/upchuk/d8-demo-modules","stars":34},

恭喜!你已经成功在 Lambda 上部署和触发代码了。

后续及 Lambda 的未来

希望这个项目能给你在 AWS Lambda 上工作建立一个好的基础。虽然我们在函数代码中整合了第三方客户端(GitHub),但它可以替换为其它客户端 API 或者数据库的客户端链接。

无服务器框架

这篇文章中演示了建立起 Lambda 的这个过程。这过程看起来手工操作比较多,时间也不长。还有另外一个配置和初始化 Lambda 的方法,就是通过 AWS API 来完成。

现在,已经有一些框架基于 AWS API 建立起来了,它们有助于简化这个过程。

  • https://serverless.com/

    Serverless 框架是当前最强大的无服务器框架。在写文本的时候,这个框架进行了重大版本更新,从0.5 更新到官方 1.0 发行版。很不幸,这个更新并不向后兼容。大多数流行的插件当前还是 0.5,未能更新到 1.0,还需要等等待一段时间才能使用。

    Serverless 以及它的插件,承诺提供一个非常全面的 Lambda 体验。它的本地开发环境提供了快速迭代、自动化的 Lambda 代码开发、多个开发平台环境,以及其它功能。

  • https://open-lambda.org/

    OpenLambda 试图通过提供一个本地开发体验来模拟 Lambda 环境。它提供工具来让部署 Lambda 代码变得容易,也提供快速迭代。这弥补了上面列出的 Lambda 的一些缺点。

原文  https://www.oschina.net/translate/getting-started-node-js-aws-lambda
正文到此结束
Loading...