亚马逊AWS官方博客

无服务器模式和创业公司,美好友谊的开端

来自 AWS 无服务器精英 Slobodan Stojanović 的客座博文。Slobodan 是 Serverless Applications with Node.js 这本书的联合作者;是软件开发工作室 Cloud Horizon 的 CTO;也是基于 Slack 的休假管理 APPVacation Tracker 的 CTO。Slobodan 对于无服务器领域非常感兴趣,因为这可以使他更快更便宜地开发软件。他经常撰写关于无服务器的文章,也经常在会议中谈及。

无服务器对创业公司而言似乎很完美。对早期创业公司而言,按次计费的定价模式以及无人使用您的 APP 时便无基础设施成本,这是非常便宜的。

另一方面,它可以实现全面管理和自动扩展,所以您完全不用担心大型营销活动或意外流量。这就是我们在开始创建第一个产品 Vacation Tracker 时决定采用无服务器模式的原因。

Vacation Tracker 是一款基于 Slack 的 APP,帮助您追踪和管理团队的假期和休息日。我们的 Slack APP 和基于网络的控制面板都需要 API,因此带有 Amazon API Gateway 触发器的 AWS Lambda 功能是逻辑出发点。API 网关提供公共 API。每次 API 接收请求时,便触发 Lambda 功能回应请求。

我们的 APP 主要用于小到中等规模的团队,是一款每天只需使用不到几分钟的 APP。定期用量促成了按次计费,无服务器定价模式为我们赢得了空间,因为初期 API 网关和 Lambda 没有成本。

从小开始,积极成长

我们决定从小开始,以简单原型开始。我们的原型是真正的 Slack APP,带有一些硬编码操作和一个小日历。使用 Claudia.js 和 Bot Builder 进行创建。Claudia.js 是将 Node.js 无服务器功能部署到 Lambda 和 API 网关的简单工具。

完成原型后,我们发布了登陆页面。但即使在有用户登入进行关闭测试访问时,我们还在继续创建产品。

几个月后,我们有了一串无服务器功能投入使用:聊天机器人、控制面板 API、Slack 通知和条纹计费的几项任务等。其中的每项功能有自己的触发器和角色。我们的 APP 正常运行时,部署新阶段变得越来越难。

显然,我们必须更好地整理 APP。因此,Vacation Tracker 考拉遇见了 AWS SAM 松鼠。

集成 Lambda 功能

我们开始映射我们所有的服务。然后,尝试将其分成流。我们决定逐渐迁移到 AWS 无服务器应用程序模型 (AWS SAM),一个用于在 AWS 上创建无服务器 APP 的开源框架。因为 AWS SAM 与语言无关,也不知道如何处理 Node.js 相关性。我们使用了 Claudia 的 pack 命令作为构建步骤。

无服务器 APP 的分组服务带回了更简单的部署。只需一个简单的命令,我们有了等待测试的新环境。

不久后,我们有了针对 Slack 聊天机器人、API、基于条纹账单支付流、通知流和其他流的用于我们的 APP 的 AWS CloudFormation 模板。

像其他创业公司一样,Vacation Tracker 的目标是能够快速发展,适应用户需求。为了实现目标,经常需要运行实验,在高速运转中进行变更。牢记于心,我们的目标是从 APP 流中提取一些常用功能到可复用组件中。

例如,因为我们在一些实验中使用了多个 Slack 削减命令,所以我们将它从 Slack 聊天机器人流中提取到可复用组件中。

Slack 削减命令组件由几个要素组成:

  • API 网关,有 Slack 削减命令和信息操作网络连接路径的 API
  • 处理削减命令的 Lambda 功能
  • 处理信息操作的 Lambda 功能
  • 针对被解析的 Slack 数据的 Amazon SNS 主题

有了这个组件,我们可以更快运行削减命令实验。添加新的 Slack 削减命令到 APP 需要部署削减命令。我们还写入了一些由 SNS 主题触发的 Lambda 功能或处理业务逻辑的 Lambda 功能。

运行 Vacation Tracker 时,我们实现了可复用组件的潜在价值。想象一下,如果可以使用其他人创建的标准组件,那您将以多快的速度集成您的 MVP? 创建 APP 需要重用部分之间的写入黏合,还需要专注于可以使 APP 变得独特的业务逻辑。

可以用 AWS Serverless Application Repository 实现梦想,它是开源无服务器组件的仓库。

事实上,我们决定发布一些可复用组件到无服务器应用程序库,从 Slack 削减命令 APP 开始。但为了做到这点,我们不得不好好测试 APP,这也为我们带来了下一个挑战:如何架构和测试可复用的无服务器 APP?

用于救援的六角形基础架构

我们的答案很简单:六角形基础架构或端口和适配器。这是允许用户、程序、自动化测试或批处理脚本平等驱动的模式。可以离开其最终运行设备和数据库,单独进行开发和测试。这使得六角形基础架构对微服务架构和无服务器 APP 完美适用。

将其应用于 Vacation Tracker,我们以与下列图解相似的设置结束。由以下部分组成:

  • lambda.js 和 main.js 文件。 lambda.js 无测试,因为它简单将相关性连线,例如 sns-notification-repository.js,并调用 main.js。
  • main.js 有自己的单元和集成测试。集成测试使用本地集成。
  • 每个库有自己的单元和集成测试。在其集成测试中,库连接到 AWS 服务。例如,sns-notification-repository.js 集成测试连接到 Amazon SNS。

每个功能至少有两个文件:lambda.jsmain.js。第一个文件很小,仅调用有所有相关性(适配器)的main.js。该文件无自动化测试,看起来与以下代码片段相似:

const {
httpResponse,
SnsNotificationRepository
} = require('@serverless-slack-command/common')
const main = require('./main')
async function handler(event) {
const notification = new SnsNotificationRepository(process.env.notificationTopic)
await main(event.body, event.headers, event.requestContext, notification)
return httpResponse()
}

exports.handler = handler

第二个,也是每个功能更为关键的文件,是 main.js。该文件包含功能的业务逻辑,必须进行完善的测试。在我们的案例中,该文件有自己的单元和集成测试。但业务逻辑经常依赖于外部集成,如发送 SNS 通知。并非测试所有外部通知,我们用其他适配器测试该文件,如本地通知库。

该文件看起来与以下代码片段相似:

const qs = require('querystring')

async function slashCommand(slackEvent, headers, requestContext, notification) {
const eventData = qs.parse(slackEvent);
return await notification.send({
type: 'SLASH_COMMAND',
payload: eventData,
metadata: {
headers,
requestContext
}
})
}

module.exports = slashCommand

外部集成的适配器有自己的单元和集成测试,包括检查与 AWS 服务集成状况的测试。用这一方式,我们将依赖于 AWS 服务的测试数量最小化,但仍然保持我们的 APP 覆盖了全部所需测试。

它们从此开始正常运行……

迁移到 AWS SAM 使我们的部署流程变得简化,同时也提升了部署流程。现在设置一个新的环境需要几分钟,将来嵌套 AWS CloudFormation 堆栈后可以大大缩减这一过程。使用六角形基础架构开发和测试我们的组件非常容易。可复用组件和无服务器应用程序库为我们的无服务器模式锦上添花。

这是无服务器模式和创业公司之间美好友谊的开端。有了无服务器模式,您的创业公司基础架构得以全面管理,仅需在有人使用您的 APP 时付费。无服务器定价模型允许您廉价运营。凭借无服务器应用程序库,您可以更快地创建 MVP,因为可以重复使用现有组件。这些连环福利为您带来超强力量和速度,以与更大团队和预算的其他产品展开竞争。

我们很高兴可以看到创业公司使用无服务器应用程序库所实现(和外包)的成就。

同时,您还可以在 GitHub 上看到我们第一个开源无服务器组件:https://github.com/vacationtracker/serverless-slack-slash-command-app。

如果您想尝试 Vacation Tracker,请访问 https://vacationtracker.io,您也可以使用优惠代码 AWS_IS_AWESOME 为您的免费试用延期一倍。