1

我有一个 aws lambda 函数,它在遇到请求时返回 null。在我建立数据库连接之前,我对请求的测试一直有效。关于为什么它没有运行请求的任何想法?

日志将就绪状态显示为 1,然后返回 null。

***编辑

这是第一个问题,一旦我承诺,在执行我的模式方法之前,我遇到了数据库连接消失的问题。下面我来回答。

const request = require('request')
const tickerController = require('./controllers/ticker');

const mongoose = require('mongoose');

let conn = null;

const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/test?retryWrites=true&w=majority`;

exports.handler = async function main(event, context, lambdaCallback) {
  // Make sure to add this so you can re-use `conn` between function calls.
  // See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
    context.callbackWaitsForEmptyEventLoop = false;

    // Because `conn` is in the global scope, Lambda may retain it between
    // function calls thanks to `callbackWaitsForEmptyEventLoop`.
    // This means your Lambda function doesn't have to go through the
    // potentially expensive process of connecting to MongoDB every time.
    if (conn == null) {
      conn = await mongoose.createConnection(uri, {
        // Buffering means mongoose will queue up operations if it gets
        // disconnected from MongoDB and send them when it reconnects.
        // With serverless, better to fail fast if not connected.
        bufferCommands: false, // Disable mongoose buffering
        bufferMaxEntries: 0, // and MongoDB driver buffering
        useUnifiedTopology: true,
        useNewUrlParser: true
      });
      // conn.model('Test', new mongoose.Schema({ name: String }));
      // console.log(conn);
      console.log(conn.readyState);

      runRequest(lambdaCallback);
  // })
  }
};

function runRequest(lambdaCallback) {
  request('https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=BKUH&apikey=' + process.env.apiKey, (err, response, body) => {
        console.log('Request ran');
        if (err) {
          console.error(err);
          done(502, '{"message", "Error retrieving ticker data"}', 'application/json', lambdaCallback);
        } else {
          try {
            .....
4

2 回答 2

1

因此,数据库连接问题的答案是将我的代码重构为一个文件,并使用“conn”变量作为全局对象来创建我的模型,就像这样......

let conn = null;
let Ticker = null;

const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/bakhu?retryWrites=true&w=majority`;

exports.handler = async function main(event, context, lambdaCallback) {
  // Make sure to add this so you can re-use `conn` between function calls.
  // See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
    context.callbackWaitsForEmptyEventLoop = false;

    // Because `conn` is in the global scope, Lambda may retain it between
    // function calls thanks to `callbackWaitsForEmptyEventLoop`.
    // This means your Lambda function doesn't have to go through the
    // potentially expensive process of connecting to MongoDB every time.
    if (conn == null) {
      conn = await mongoose.createConnection(uri, {
        // Buffering means mongoose will queue up operations if it gets
        // disconnected from MongoDB and send them when it reconnects.
        // With serverless, better to fail fast if not connected.
        bufferCommands: false, // Disable mongoose buffering
        bufferMaxEntries: 0, // and MongoDB driver buffering
        useUnifiedTopology: true,
        useNewUrlParser: true
      });
      // conn.model('Test', new mongoose.Schema({ name: String }));
      // console.log(conn);
      console.log(conn.readyState);

      const Schema = mongoose.Schema;
      const moment = require('moment');

      const tickerSchema = new Schema({
        createdAt: { type: Date },
        updatedAt: { type: Date },
        symbol: { type: String },
        latestPrice: { type: String }
      });

      tickerSchema.pre('save', function (next) {
        let ticker = this;

        this.createdAt = ticker.createdAt ? ticker.createdAt : moment().local();
        this.updatedAt = moment().local();

        next();
      })

      Ticker = conn.model('Ticker', tickerSchema);

当我在单独的文件中调用我的模式方法时,它从未共享连接。

于 2020-01-05T18:08:26.250 回答
1

我会开始使用 promises/async/await 而不是回调模式。就像是

const request = require("request");
const tickerController = require("./controllers/ticker");

const mongoose = require("mongoose");

let conn = null;

const uri = `mongodb+srv://${process.env.dbUser}:${process.env.dbPassword}@cluster0-oj6p1.mongodb.net/test?retryWrites=true&w=majority`;

exports.handler = async event => {
  // Make sure to add this so you can re-use `conn` between function calls.
  // See https://www.mongodb.com/blog/post/serverless-development-with-nodejs-aws-lambda-mongodb-atlas
  context.callbackWaitsForEmptyEventLoop = false;

  // Because `conn` is in the global scope, Lambda may retain it between
  // function calls thanks to `callbackWaitsForEmptyEventLoop`.
  // This means your Lambda function doesn't have to go through the
  // potentially expensive process of connecting to MongoDB every time.
  if (conn == null) {
    conn = await mongoose.createConnection(uri, {
      // Buffering means mongoose will queue up operations if it gets
      // disconnected from MongoDB and send them when it reconnects.
      // With serverless, better to fail fast if not connected.
      bufferCommands: false, // Disable mongoose buffering
      bufferMaxEntries: 0, // and MongoDB driver buffering
      useUnifiedTopology: true,
      useNewUrlParser: true
    });
    // conn.model('Test', new mongoose.Schema({ name: String }));
    // console.log(conn);
    console.log(conn.readyState);

    const body = await runRequest();
    return body;
    // })
  }
};

function runRequest() {
  return new Promise((resolve, reject) => {
    request(
      "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=BKUH&apikey=" +
        process.env.apiKey,
      (err, response, body) => {
        console.log("Request ran");
        if (err) {
          console.error(err);
          reject(err);
        }
        resolve(body);
      }
    );
  });
}

于 2020-01-05T11:08:51.933 回答