복붙노트

[REDIS] 어떻게 AWS 람다 함수에서 레디 스 인스턴스에 연결해야합니까?

REDIS

어떻게 AWS 람다 함수에서 레디 스 인스턴스에 연결해야합니까?

나는 AWS 람다와 서버를 사용하지 않는 프레임 워크를 사용하여 단일 페이지 웹 응용 프로그램을위한 API를 구축하기 위해 노력하고있어. 나는 주로 속도와 데이터 지속성의 그것의 조합, 스토리지 레디 스 클라우드를 사용하고 싶습니다. 나는 이것에 대한 ElastiCache를 사용하지 않으려는, 그래서 나는 레디 스 클라우드는 미래에 기능 이상을 사용할 수있다. 내 레디 스 클라우드 인스턴스 내 함수와 동일한 AWS 지역에서 실행되고 있습니다.

나는 데이터베이스에 대한 항목이 있는지보기 위해 API 엔드 포인트에 GET 요청에서 해시 태그 소요되며, 검사 관련라는 함수가 있습니다. 그것은이 있다면, 즉시 결과를 반환해야합니다. 그렇지 않을 경우, RiteTag를 조회 레디 스에 결과를 작성한 다음 사용자에게 결과를 반환해야합니다.

아마 adorably 순진 뭔가를하고 있어요, 그래서 나는이 꽤 새로운 해요. 여기에 이벤트 핸들러는 다음과 같습니다

'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는 관련 실행할 기능) 로컬 기능을 실행하면, 나는 무엇이든지-태그를 읽고 그들이해야대로 레디 스 데이터베이스에 기록됩니다 아무 문제가 없습니다. 그러나, 나는 그것이 배포 후 실행 이번이 처음 작동 한 후 작동을 멈 춥니 다 (SLS 대시 배포를 사용)를 배포합니다. 이후의 모든 시도는 단순히 브라우저 (또는 우편 배달부, 또는 컬 또는 웹 응용 프로그램)에 NULL을 반환 실행합니다. 이에 상관없이 내가 테스트를 위해 사용하는 태그가 이미 데이터베이스에 여부의 사실이다. 그때, 함수 자체에 대한 변경을하지-배포를 다시하는 경우, 다시 한 번만 사용할 수 있습니다.

내 로컬 컴퓨터에서 함수를 먼저 로그 연결 : 사실 콘솔, 다음 쿼리의 결과는 다음 연결이 닫힙니다. 쿼리의 진실, 그 결과를, 그리고 그것 뿐이다 : AWS에, 그것은 연결 기록합니다. 두 번째 실행에, 그것은 로그 연결 마감했다. 다른 아무것도 없습니다. 세 번째 이후의 모든 실행, 그것은 전혀 아무것도 기록하지 않습니다. 어느 환경 적 오류를보고합니다.

그것은 문제가 레디 스에 대한 연결 함께 꽤 분명한 것 같다. 나는 가까운 그 콜백에서하지 않으면, 후속 시도는 기능을 단지 시간을 호출합니다. 또한 redis.unref 대신 redis.quit의 사용하여 시도했지만, 그 어떤 차이를 보이지 않았다.

어떤 도움을 크게 감상 할 수있다.

해결법

  1. ==============================

    1.지금은 내 자신의 문제를 해결했습니다, 그리고 나는 앞으로이 문제가 발생하는 사람에게 도움이 될 수 있기를 바랍니다.

    지금은 내 자신의 문제를 해결했습니다, 그리고 나는 앞으로이 문제가 발생하는 사람에게 도움이 될 수 있기를 바랍니다.

    나는 람다 함수에서 위의 코드에서처럼 데이터베이스에 연결할 때 두 가지 주요 고려 사항이 있습니다 :

    여기 내 업데이트 된 코드입니다. 내가 코드를 복제하지 않고 다른 람다 함수로 가져올 수 있도록 참고 또한, 별도의 파일로 내 레디 스 구성을 넣어했다고.

    '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)
        }
      })
    }
    
    module.exports = () => {
      const redis = require('redis')
      const jsonify = require('redis-jsonify')
      const redisOptions = {
        host: process.env.REDIS_URL,
        port: process.env.REDIS_PORT,
        password: process.env.REDIS_PASS
      }
    
      return jsonify(redis.createClient(redisOptions))
    }
    
    'use strict'
    
    const rt = require('./ritetag')
    
    module.exports.respond = function (event, callback) {
      const redis = require('./redis')()
    
      const tag = event.hashtag.replace(/^#/, '')
      const key = 'related:' + tag
      let error, response
    
      redis.on('end', () => {
        callback(error, response)
      })
    
      redis.on('ready', function () {
        redis.get(key, (err, res) => {
          if (err) {
            redis.quit(() => {
              error = err
            })
          } else {
            if (res) {
              // Tag is found in Redis, so send results directly.
              redis.quit(() => {
                response = res
              })
            } else {
              // Tag is not yet in Redis, so query Ritetag.
              rt.hashtagDirectory(tag, (err, res) => {
                if (err) {
                  redis.quit(() => {
                    error = err
                  })
                } else {
                  redis.set(key, res, (err) => {
                    if (err) {
                      redis.quit(() => {
                        error = err
                      })
                    } else {
                      redis.quit(() => {
                        response = res
                      })
                    }
                  })
                }
              })
            }
          }
        })
      })
    }
    

    그것은해야-하고 너무 빨리 타오르는 것 같은이 정확히 작동합니다.

  2. from https://stackoverflow.com/questions/37094695/how-should-i-connect-to-a-redis-instance-from-an-aws-lambda-function by cc-by-sa and MIT license