Serverless
读者须知:
以下是使用 Fastify 在 AWS Lambda 和 Amazon API Gateway 架构上构建无服务器 web 应用/服务的示例。
注:使用 aws-lambda-fastify 仅是一种可行方案。
app.js
你可以简单地把初始化代码包裹于可选的 serverFactory 选项里。
当执行 lambda 函数时,我们不需要监听特定的端口,因此,在这个例子里我们只要导出 函数即可。 在 里,我们会用到它。
当像往常一样运行 Fastify 应用, 比如执行 node app.js
时 (可以用 require.main === module
来判断), 你可以监听某个端口,如此便能本地运行应用了。
const awsLambdaFastify = require('aws-lambda-fastify')
const init = require('./app');
const proxy = awsLambdaFastify(init())
// 或
// const proxy = awsLambdaFastify(init(), { binaryMimeTypes: ['application/octet-stream'] })
exports.handler = proxy;
// 或
// exports.handler = (event, context, callback) => proxy(event, context, callback);
// 或
// exports.handler = (event, context) => proxy(event, context);
// 或
示例
你可以在找到使用 claudia.js 的可部署的例子。
注意事项
- 你没法操作 stream,因为 API Gateway 还不支持它。
- API Gateway 的超时时间为 29 秒,请务必在此时限内回复。
与 AWS Lambda 和 Google Cloud Functions 不同,Google Cloud Run 是一个无服务器容器环境。它的首要目的是提供一个能运行任意容器的底层抽象 (infrastucture-abstracted) 的环境。因此,你能将 Fastify 部署在 Google Cloud Run 上,而且相比正常的写法,只需要改动极少的代码。
参照以下步骤部署 Google Cloud Run。如果你对 gcloud 还不熟悉,请看其。
为了让 Fastify 能正确地在容器里监听请求,请确保设置了正确的端口与地址:
function build() {
const fastify = Fastify({ trustProxy: true })
return fastify
}
async function start() {
// Google Cloud Run 会设置这一环境变量,
const IS_GOOGLE_CLOUD_RUN = process.env.K_SERVICE !== undefined
// 监听 Cloud Run 提供的端口
const port = process.env.PORT || 3000
// 监听 Cloud Run 中所有的 IPV4 地址
const address = IS_GOOGLE_CLOUD_RUN ? "0.0.0.0" : undefined
try {
const server = build()
const address = await server.listen(port, address)
console.log(`Listening on ${address}`)
} catch (err) {
console.error(err)
process.exit(1)
}
}
module.exports = build
start()
}
添加 Dockerfile
你可以添加任意合法的 Dockerfile
,用于打包运行 Node 程序。在 中,你能找到一份基本的 Dockerfile
。
添加 .dockerignore
添加一份如下的 .dockerignore
,可以将仅用于构建的文件排除在容器之外 (能减小容器大小,加快构建速度):
Dockerfile
README.md
node_modules
npm-debug.log
gcloud builds submit --tag gcr.io/PROJECT-ID/APP-NAME
部署镜像
镜像构建之后,使用如下命令部署它:
如此,便能从 Google 云平台提供的链接访问你的应用了。
now 针对 Node.js 应用提供了零配置部署方案。要使用 now,只需要如下配置你的 now.json
文件:
{
"version": 2,
"builds": [
{
"src": "api/serverless.js",
"use": "@now/node",
"config": {
"helpers": false
}
}
],
"routes": [
{ "src": "/.*", "dest": "/api/serverless.js"}
]
}
之后,写一个 api/serverless.js
文件:
'use strict'
const build = require('./index')
const app = build()
module.exports = async function (req, res) {
await app.ready()
app.server.emit('request', req, res)
}
以及一个 api/index.js
文件:
要注意的是,你得在 package.json
中使用 Node 10:
"engines": {