我正在尝试使用AWS Lambda和Serverless Framework为单页 Web 应用程序构建 API 。我想使用Redis Cloud进行存储,主要是因为它结合了速度和数据持久性。将来我可能会使用更多 Redis Cloud 功能,因此我宁愿避免使用 ElastiCache。我的 Redis Cloud 实例与我的函数在同一 AWS 区域中运行。
我有一个名为的函数related
,它从 GET 请求到 API 端点获取标签,并检查数据库中是否有它的条目。如果它在那里,它应该立即返回结果。如果没有,它应该查询RiteTag,将结果写入 Redis,然后将结果返回给用户。
我对此很陌生,所以我可能正在做一些非常天真的事情。这是事件处理程序:
'use strict'
const lib = require('../lib/related')
module.exports.handler = function (event, context) {
lib.respond(event, (err, res) => {
if (err) {
return context.fail(err)
} else {
return context.succeed(res)
}
})
}
这是../lib/related.js
文件:
var redis = require('redis')
var jsonify = require('redis-jsonify')
var rt = require('./ritetag')
var redisOptions = {
host: process.env.REDIS_URL,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASS
}
var client = jsonify(redis.createClient(redisOptions))
module.exports.respond = function (event, callback) {
var tag = event.hashtag.replace(/^#/, '')
var key = 'related:' + tag
client.on('connect', () => {
console.log('Connected:', client.connected)
})
client.on('end', () => {
console.log('Connection closed.')
})
client.on('ready', function () {
client.get(key, (err, res) => {
if (err) {
client.quit()
callback(err)
} else {
if (res) {
// Tag is found in Redis, so send results directly.
client.quit()
callback(null, res)
} else {
// Tag is not yet in Redis, so query Ritetag.
rt.hashtagDirectory(tag, (err, res) => {
if (err) {
client.quit()
callback(err)
} else {
client.set(key, res, (err) => {
if (err) {
callback(err)
} else {
client.quit()
callback(null, res)
}
})
}
})
}
}
})
})
}
在某种程度上,所有这些都按预期工作。如果我在本地运行该函数(使用sls function run related
),我没有任何问题——标签按应有的方式从 Redis 数据库读取和写入。但是,当我部署它(使用sls dash deploy
)时,它在部署后第一次运行时工作,然后停止工作。所有后续运行它的尝试都只是返回null
到浏览器(或 Postman、curl 或 Web 应用程序)。无论我用于测试的标签是否已经在数据库中,这都是正确的。如果我随后重新部署,不对函数本身进行任何更改,它就会再次工作——一次。
在我的本地机器上,该函数首先记录Connected: true
到控制台,然后是查询结果,然后Connection closed.
在 AWS 上,它记录Connected: true
,然后是查询结果,仅此而已。在第二次运行时,它记录Connection closed.
并没有其他内容。在第三次和所有后续运行中,它根本没有记录任何内容。两种环境都不会报告任何错误。
很明显,问题出在与 Redis 的连接上。如果我不在回调中关闭它,那么随后调用该函数的尝试就会超时。我也尝试过使用redis.unref
而不是redis.quit
,但这似乎没有任何区别。
任何帮助将不胜感激。