Wie soll ich von einer AWS Lambda-Funktion aus eine Verbindung zu einer Redis-Instanz herstellen?

Ich versuche, mit @ eine API für eine einseitige Webanwendung zu erstelleAWS Lambda und dieServerless Framework. Ich möchte benutzenRedis Cloud für die Speicherung, hauptsächlich wegen seiner Kombination aus Geschwindigkeit und Datenbeständigkeit. Möglicherweise verwende ich in Zukunft mehr Redis Cloud-Funktionen. Daher würde ich es vorziehen, ElastiCache nicht mehr zu verwenden. Meine Redis Cloud-Instanz wird in derselben AWS-Region ausgeführt wie meine Funktion.

Ich habe eine Funktion namensrelated, das ein Hashtag von einer GET-Anforderung an einen API-Endpunkt überträgt und prüft, ob ein Eintrag in der Datenbank vorhanden ist. Wenn es dort ist, sollte es die Ergebnisse sofort zurückgeben. Wenn nicht, sollte es @ abfrag RiteTag, schreiben Sie die Ergebnisse an Redis und senden Sie sie an den Benutzer zurück.

Ich bin ziemlich neu in diesem Bereich, also mache ich wahrscheinlich etwas sehr naives. Hier ist der Event-Handler:

'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)
    }
  })
}

Hier ist die../lib/related.js Datei

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)
                }
              })
            }
          })
        }
      }
    })
  })
}

All dies funktioniert erwartungsgemäß bis zu einem gewissen Punkt. Wenn ich die Funktion lokal ausführe (mitsls function run related), Ich habe überhaupt keine Probleme - Tags werden wie vorgesehen aus der Redis-Datenbank gelesen und in diese geschrieben. Wenn ich es jedoch bereitstelle (mitsls dash deploy), es funktioniert dasrstmals wird es nach der Bereitstellung ausgeführ und hört dann auf zu arbeiten. Alle nachfolgenden Versuche, es auszuführen, geben einfach @ zurücnull an den Browser (oder Postman oder Curl oder die Web-App). Dies gilt unabhängig davon, ob sich das zum Testen verwendete Tag bereits in der Datenbank befindet oder nicht. Wenn ich dann erneut implementiere und keine Änderungen an der Funktion selbst vornehme, funktioniert sie erneut - einmal.

Auf meinem lokalen Computer protokolliert die Funktion zuerstConnected: true an die Konsole, dann die Ergebnisse der Abfrage, dannConnection closed. Auf AWS protokolliert esConnected: true, dann die Ergebnisse der Abfrage, und das wars. Beim zweiten Durchlauf wird @ protokollierConnection closed. und sonst nichts. Beim dritten und allen folgenden Durchläufen wird überhaupt nichts protokolliert. Keine der beiden Umgebungen meldet jemals Fehler.

Es scheint ziemlich klar, dass das Problem bei der Verbindung zu Redis liegt. Wenn ich es in den Rückrufen nicht schließe, treten bei nachfolgenden Versuchen, die Funktion aufzurufen, nur Zeitüberschreitungen auf. Ich habe auch versucht mitredis.unref Anstatt vonredis.quit, aber das schien keinen Unterschied zu machen.

Jede Hilfe wäre sehr dankbar.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage