用NodeJS和AWS Lambda实现无服务器化
无服务器架构是对高维护、浪费资源的服务器的一种替代。通过无服务器部署,你只需要为你所使用的东西精确付费。而且,它使你不必处理多个服务器设置及其配置。
因此,今天的开发者蜂拥而至,对他们的应用程序进行无服务器化,这并不奇怪。在AWS Lambda和无服务器框架的帮助下,你可以快速部署可扩展的应用程序。
在本教程中,我们将研究如何使用Node.js、AWS Lambda和Serverless框架部署一个简单的无服务器API。
关于这些技术的一些情况
AWS Lambda是一种基于云的无服务器服务。Lambda函数是无状态函数,由事件触发并在执行结束后过期。
鉴于AWS Lambda的复杂性质,我们使用无服务器框架来简化部署过程。事实上,利用Serverless,你只需几个步骤就能部署你的Node应用。
前提条件
要继续学习本教程,你需要设置好以下东西:
- 一个AWS账户。如果你只是在尝试使用AWS,你可以加入一个免费层,而不需要支付一分钱。
- 在你的AWS控制台创建一个IAM用户。按照这篇文章的步骤创建IAM用户。在进行下一步之前,记得保存访问密钥Id和秘密访问密钥。
安装和设置Serverless
你可以用npm轻松安装Serverless。运行下面的命令来全局安装它:
npm install -g serverless
接下来,使用下面的命令将已安装的Serverless与IAM密钥进行配置。使用创建IAM用户时保存的ID和密钥,分别作为密钥和秘密:
sls config credentials --provider aws --key xxx --secret xxx
创建Node应用程序
我为本教程创建了一个简单的Hello World应用,但你也可以按照同样的逻辑部署更复杂的应用:
const express = require("express");
const sls = require("serverless-http");
const app = express();
app.get("/", (req, res) => {
res.send("Hello World");
});
app.get("/:userName", (req, res) => {
res.send(`Welcome, ${req.params.userName}`);
})
module.exports.handler = sls(app);
正如你在上面看到的,我们使用serverless-http npm包来设置无服务器应用程序,所以要确保你已经安装了该包。你可以通过以下方式安装该库:
npm install --save express serverless-http
创建serverless.yml文件
我们使用一个名为serverless.yml的文件来传递无服务器配置。对于我们的简单应用,它包含以下属性:
service: node-serverless-app
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: eu-central-1
functions:
app:
handler: app.handler
events:
- http:
path: /
method: ANY
- http:
path: /{proxy+}
method: ANY
这里,functions 属性列出了我们应用程序中的所有函数。我们传递一个名为app 的函数,并使用app.js 文件中导出的对处理程序的引用作为函数处理程序。
然后,我们需要添加会触发给定函数的事件。我们传递HTTP请求作为触发事件。我在上面的配置中设置了在每次发送HTTP请求时调用应用程序的函数。
使用/{proxy+} 转发每个请求,允许 Express 应用程序自己处理每个请求,而不是在 API 网关层面处理请求。
部署应用程序
现在我们已经将我们的配置传递给了serverless.yml ,部署应用程序只是一个命令的问题:
sls deploy
它的输出将看起来像这样:
SLS部署输出示例
恭喜你!你已经成功地部署了你的第一个无服务器应用程序。你已经成功地将你的第一个无服务器应用程序部署到AWS。
你可以在端点下提供的链接中访问已部署的应用程序。如果你访问根节点,你会看到 "Hello World "的信息。
路径特定路由
还记得我们是如何将所有的路由代理给Express应用的吗?虽然这种实现方式有一些好处,比如限制冷启动,但我们错过了从一些无服务器架构特性中获益的机会。
我们可以引入由不同Lambda函数处理的特定路径,而不是用一个Lambda函数来路由所有的路径。这可以让我们使用特定路径的指标来更好地了解应用程序的情况。
在这种情况下,像这样更新serverless.yml ,让不同的函数处理每个路径:
functions:
helloWorld:
handler: app.handler
events:
-http:
path: /
method: get
welcome:
handler: app.handler
events:
-http:
path: /{userName}
method: get
添加环境变量
如果你想向应用程序传递环境变量,你可以使用environment 属性。
例如,如果你想传递一个NODE_ENV变量,你可以像这样设置它:
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: eu-central-1
environment:
NODE_ENV: production
如果你想从一个.env文件中传递环境变量,你需要使用serverless-dotenv-plugin 。
首先,将该插件作为开发依赖项安装:
npm install serverless-dotenv-plugin --save-dev
然后,你可以在根目录下创建一个.env文件,将环境变量添加到其中:
STAGE=dev
SECRET=**********
一旦你将dotenv-plugin列在应用插件下,你就可以导入存储的环境变量,并在serverless.yml文件内使用它们:
service: node-serverless-app
provider:
name: aws
runtime: nodejs10.x
stage: ${env:STAGE}
region: eu-central-1
environment:
SECRET: ${env:SECRET}
functions:
helloWorld:
handler: app.handler
events:
- http:
path: /
method: get
welcome:
handler: app.handler
events:
- http:
path: /{userName}
method: get
plugins:
- serverless-dotenv-plugin
离线使用serverless
在这之前,即使是进行最简单的路由测试,我们也必须部署我们的应用。你只需在你的应用中编写两三个新的路由,就能意识到这是多么令人讨厌的事情。
如果有一种方法可以在将你的应用部署到AWS之前对其进行测试呢?
通过使用无服务器离线插件,你就可以做到这一点。你只需要安装一个新的npm包,并在serverless.yml文件中添加一行新的代码,就可以实现这个功能。
首先,安装该包:
npm install serverless-offline --save-dev
然后,更新serverless.yml:
plugins:
- serverless-offline
- serverless-dotenv-plugin
现在,你只需运行以下命令即可在本地启动该应用程序:
sls offline start
它将显示你的应用程序中所有路由的列表。另外,最重要的是,它可以启动你的应用程序在本地3000端口运行。
总结
与服务器相比,无服务器架构仍处于早期阶段。你可以指望它在未来几年内变得更加强大和突出。我希望你对Serverless和AWS Lambda的首次体验能促使你在下次寻找部署方案时给这项技术一个机会。
谢谢你的阅读!