使用 Google Cloud 实现无服务器 Node.js 函数
已发表: 2022-03-11创建软件并不以编写好的代码结束。 当软件部署完成并能够正确处理请求并且我们可以在不影响性能和运行成本的情况下进行扩展时,它就完成了。
您可能正在考虑如何使用云计算来处理所有这些事情。 “那么这个新的无服务器的东西是什么,Vignes?”
无服务器计算是一种架构风格,其中代码在云平台中执行,我们无需担心硬件和软件设置、安全性、性能和 CPU 空闲时间成本。 这是云计算的进步,它超越了抽象软件环境的基础设施。 这意味着运行代码不需要任何配置。
使用无服务器,以下将是您的工作方式:
开发代码。
将代码上传到服务提供商。
配置触发器(在我们的例子中是一个 HTTP 请求)。
我们的工作完成了! 现在平台提供商将处理传入的请求和扩展。
无服务器微服务简介
无服务器架构通常与微服务风格设计相结合。 微服务是大型软件的独立部分,用于处理对特定模块的请求。 通过创建可以在无服务器环境中运行的微服务,可以轻松维护代码并加快部署速度。
AWS Lambda 和 GCF 简介,比较
无服务器功能通常称为“后端即服务”或“功能即服务”。 无服务器计算提供商的数量开始增加。 但是,一些传统的大玩家也提供无服务器选项,例如 Amazon Web Services 的AWS Lambda Functions和 Google Cloud 的Google Cloud Functions (GCF),后者目前处于测试阶段,是我正在使用的。 尽管它们的工作方式相似,但它们之间存在一些重要差异。
AWS 拉姆达 | 谷歌云函数 | |
---|---|---|
语言支持 | Node.js、Python、C#、Java | 节点.js |
触发器 | DynamoDB、Kinesis、S3、SNS、API 网关 (HTTP)、CloudFront 等 | HTTP、Cloud PubSub、云存储桶 |
最长执行时间 | 300 秒 | 540 秒 |
在本文中,我们将介绍使用 GCF 实现无服务器代码部署的过程。 Google Cloud Functions 是一种基于事件的轻量级异步计算解决方案,它允许您创建小型、单一用途的函数来响应云事件,而无需管理服务器或运行时环境。
GCF 具有基于触发器分离的三种可能的实现。
HTTP 触发器 将 HTTP 请求路由到云函数
内部 Google 发布/订阅触发器 将发布和订阅请求路由到云功能
云存储桶触发器 将对存储桶所做的任何更改路由到云函数
让我们使用 Google Cloud Functions 创建一个基于 HTTP 触发器的设置
Google Cloud Functions 不需要任何额外的特殊设置或安装。 GCF 确保默认节点环境已设置并准备好执行。 当使用 HTTP 作为触发器创建云函数时,它会提供一个 URL 来触发该函数。 与使用 API 网关作为与其通信的媒介的 AWS Lambda 相比,Google Cloud Functions 会根据projectID
和区域立即提供 URL。
创建无服务器 Node.js 应用程序
为了使我们的代码在 GCF 中可执行,我们应该将代码包装在一个函数中。 每当触发发生时,GCF 都会调用该特定函数。 可能的方法是上传,
单个文件:导出一个默认函数,该函数将根据请求调用其他函数。
多个文件:有一个
index.js
文件需要所有其他文件并导出默认函数作为起点。多个文件:在
package.json
中配置一个主文件,使用"main": "main.js"
作为起点。
以上任何一种方法都可以。
GCF 支持特定的 Node 运行时版本。 确保编写代码以支持该特定版本。 在创建这篇文章时,GCF 支持 Node 版本 v6.11.1。
要创建一个函数,需要考虑的选项很少。
内存这告诉需要多少内存来处理一个运行时间的请求。 以 MB 定义。 对于小型应用程序,128MB 应该足够了,但可以增加到 2GB。
Timeout顾名思义,Timeout 定义了预期的代码执行超时。 在此之后,代码将被杀死并停止。 在此之后的任何执行都将突然停止。 最大超时为 540 秒。
要执行的函数虽然可以从主处理程序文件中导出多个函数,但我们需要配置一个应该触发的函数来处理请求。 这允许开发人员拥有基于 HTTP 方法/URL 的多个入口点。
要上传代码,只需复制粘贴代码即可创建功能门户。 对于多个文件,压缩内容并上传文件。 确保在 ZIP 文件的情况下,应该有一个index.js
文件或一个package.json
文件,其中提到了主文件。
任何 NPM 模块依赖都应该在package.json
中提及。 GCF 尝试在首次安装期间安装package.json
文件中提到的模块。

让我们创建一个简单的处理程序来返回 200 状态和一些消息。 创建一个函数并将以下代码添加到源代码中。
exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); }
创建函数后,打开提供的 URL 以触发函数。 它应该响应如下。
现在,让我们检查日志中的req
对象。 要查看日志,GCF 直接从控制台提供选项。 单击垂直点并打开日志选项。
现在,让我们更新代码以处理/users
的简单路由。
以下代码用于处理/users
路由的简单GET
和POST
请求:
exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } }
更新后,现在让我们在浏览器中测试它,但这次最后使用/users
。
这很酷。 我们创建了一个带有路由的基本 HTTP 服务器。
操作与调试
如果代码是故事结束的地方,那么您就不会研究无服务器 Node.js 应用程序等基础设施选项。 下面简要介绍了如何处理部署和调试等常见任务。 Node.js 开发人员已经为其他应用程序做的事情。
部署:
函数代码可以通过四种方式部署。
复制粘贴代码到控制台
上传 ZIP 文件
从云存储桶部署为 ZIP 文件
从云源存储库部署
显然,最方便的选择是从源存储库进行部署。
调用:
在创建函数时,Console 会提供 HTTP URL 来触发函数,格式为: https://<region>-<project-id>.cloudfunctions.net/<function-name>
AWS Lambda 的函数存在冷启动问题,导致函数执行需要额外的时间才能启动。 一旦开始,以下执行将正常响应。 这个初始的额外启动时间称为冷启动。 虽然我们没有与此主题相关的 GCF 官方文档,但在我们的测试过程中并没有出现冷启动问题。
调试:
GCF 与 Google Cloud 中的 Stackdriver Logging 服务集成。 所有控制台日志和错误都将记录在这里,它有助于调试已经部署的代码。
测试:
控制台提供了通过传递 JSON 作为输入来测试函数的选项。 该函数将以 JSON 作为输入调用,输出将显示在控制台中。 请求(输入)和响应类似于 Express.js 框架,可以在开发过程本身进行单元测试。 如果您需要复习 Node.js 测试,请查看实际进行集成测试的 Node.js 指南
限制和后续步骤
使用无服务器功能有其自身的优势,但也有局限性
供应商锁定:它将我们编写的代码限制在一个特定的服务提供商。 将代码移动到另一个提供商需要在迁移过程中付出巨大的努力来重写代码。 由于这可能是一个大问题,因此我们在选择服务提供商时应该非常小心。
请求数量和硬件资源的限制:提供者通常会限制一个函数一次处理的并行请求的数量。 还有内存限制。 这些类型的限制可以通过与提供商交谈来提高,但它们仍然存在。
谷歌云功能正在成熟和改进很多。 它仍在不断改进和更新,尤其是在它可以支持的语言中。 如果您计划使用 Google Cloud 功能,请密切关注更改日志,以避免在实施过程中出现任何重大更改。
进一步阅读 Toptal 工程博客:
- 使用 TypeScript 和 Jest 支持:AWS SAM 教程