AWS лямбда с мангустом в атлас - MongoNetworkError - PullRequest
1 голос
/ 04 июля 2019

Я пытаюсь соединить MongoDB Atlas с mongoose и aws lambda, но получаю ошибку MongoNetworkError

  • AWS Lambda
  • Mongoose
  • MongoDB Atlas

Тот же код был протестирован с serverless-offline и отлично работает, проблема заключается в том, что я развернул его на AWS Lambda.

Это фрагмент кода

'use strict';
const mongoose = require('mongoose');
const MongoClient = require('mongodb').MongoClient;
let dbuser  = process.env.DB_USER;
let dbpass = process.env.DB_PASSWORD;
let opts = { 
    bufferCommands: false, 
    bufferMaxEntries: 0, 
    socketTimeoutMS: 2000000, 
    keepAlive: true, 
    reconnectTries: 30, 
    reconnectInterval: 500,
    poolSize: 10,
    ssl: true,
 };
const uri = `mongodb+srv://${dbuser}:${dbpass}@carpoolingcluster0-bw91o.mongodb.net/awsmongotest?retryWrites=true&w=majority`;
// simple hello test
module.exports.hello = async (event, context, callback) => {
    const response = {
        body: JSON.stringify({message:'AWS Testing :: '+ `${dbuser} and ${dbpass}`}),
    };
    return response;
};
// connect using mongoose
module.exports.cn1 = async (event, context, callback)  => {
    context.callbackWaitsForEmptyEventLoop = false;
    let conn = await mongoose.createConnection(uri, opts);
    const M = conn.models.Test || conn.model('Test', new mongoose.Schema({ name: String }));
    const doc = await M.find();
    const response = {
        body: JSON.stringify({data:doc}),
    };
    return response;
};
// connect using mongodb
module.exports.cn2 = (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;
    console.log("Connec to mongo using connectmongo ");
    MongoClient.connect(uri).then(client => {
        console.log("Success connect to mongo DB::::");
        client.db('awsmongotest').collection('tests').find({}).toArray()
            .then((result)=>{
                let response = {
                    body: JSON.stringify({data:result}),
                }
                callback(null, response)
            })
    }).catch(err => {
        console.log('=> an error occurred: ', err);
        callback(err);
    });
};

ВЖурналы CloudWatch я вижу эту ошибку

{
    "errorType": "MongoNetworkError",
    "errorMessage": "failed to connect to server [carpoolingcluster0-shard-00-02-bw91o.mongodb.net:27017] on first connect [MongoNetworkError: connection 5 to carpoolingcluster0-shard-00-02-bw91o.mongodb.net:27017 closed]",
    "stack": [
        "MongoNetworkError: failed to connect to server [carpoolingcluster0-shard-00-02-bw91o.mongodb.net:27017] on first connect [MongoNetworkError: connection 5 to carpoolingcluster0-shard-00-02-bw91o.mongodb.net:27017 closed]",
        "    at Pool.<anonymous> (/var/task/node_modules/mongodb-core/lib/topologies/server.js:431:11)",
        "    at Pool.emit (events.js:189:13)",
        "    at connect (/var/task/node_modules/mongodb-core/lib/connection/pool.js:557:14)",
        "    at callback (/var/task/node_modules/mongodb-core/lib/connection/connect.js:109:5)",
        "    at runCommand (/var/task/node_modules/mongodb-core/lib/connection/connect.js:129:7)",
        "    at Connection.errorHandler (/var/task/node_modules/mongodb-core/lib/connection/connect.js:321:5)",
        "    at Object.onceWrapper (events.js:277:13)",
        "    at Connection.emit (events.js:189:13)",
        "    at TLSSocket.<anonymous> (/var/task/node_modules/mongodb-core/lib/connection/connection.js:350:12)",
        "    at Object.onceWrapper (events.js:277:13)",
        "    at TLSSocket.emit (events.js:189:13)",
        "    at _handle.close (net.js:597:12)",
        "    at TCP.done (_tls_wrap.js:388:7)"
    ],
    "name": "MongoNetworkError",
    "errorLabels": [
        "TransientTransactionError"
    ]
}

Вот пример на github для воспроизведения ошибки.

https://github.com/rollrodrig/error-aws-mongo-atlas

Просто клонируйте его, установите npm, добавьте вашПользователь Mongo Atlas, пароль и push для AWS.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 10 июля 2019

У меня есть несколько вопросов относительно вашей конфигурации:

  1. Вы добавили в белый список IP-адрес лямбда-функции AWS в Atlas?Несколько сообщений о SO указывают, что пользователи получают MongoNetworkError, подобный этому, если IP не внесен в белый список.[1] [4]

  2. Вы читали руководство по передовым методам Atlas, в котором говорится, что соединения mongodb должны инициироваться вне лямбда-обработчика?[2] [3]

  3. Используете ли вы публичную лямбда-функцию или лямбда-функцию внутри VPC?Между ними есть существенная разница, и последняя более подвержена ошибкам, поскольку необходимо учитывать конфигурацию VPC (например, NAT).

Мне удалось пропинговать экземпляры вкластеру Atlas и удалось установить соединение через порт 27017. Однако при подключении через оболочку mongo я получаю следующую ошибку:

Невозможно связаться с первичным сервером для набора CarpoolingCluster0-shard-0.

Невозможно достичь каких-либо узлов для установки CarpoolingCluster0-shard-0.Пожалуйста, проверьте подключение к сети и статус устройства.Это произошло для 1 проверки подряд.

Когда я использую ваш пример GitHub из AWS lambda, я получаю точно такое же сообщение об ошибке, как описано в вопросе.

Как ошибкасообщения не связаны с аутентификацией, а связаны с сетью, я предполагаю, что что-то блокирует соединение ... Пожалуйста, дважды проверьте три вопроса конфигурации выше.

[1] Что такое TransientTransactionError в Mongoose(или MongoDB)?
[2] https://docs.atlas.mongodb.com/best-practices-connecting-to-aws-lambda/
[3] https://blog.cloudboost.io/i-wish-i-knew-how-to-use-mongodb-connection-in-aws-lambda-f91cd2694ae5
[4] https://github.com/Automattic/mongoose/issues/5237

0 голосов
/ 11 июля 2019

Ну, спасибо всем. Наконец я нашел решение с помощью поддержки Монго. Вот решение для тех, кто нуждается

  1. Когда вы создаете кластер Mongo Altas, они просят вас добавить ваш локальный ip, и он автоматически добавляется в белый список. Вы можете увидеть это в Your cluster > Network Access > IP Whitelist там в списке вы увидите свой IP. Это означает, что только люди из ВАШЕЙ сети смогут подключиться к вашему MongoAtlas. AWS Lambda НЕ находится в вашей сети, так что лямбда никогда не будет подключаться к вашему Mongo Atlas. Вот почему я получаю ошибку MongoNetworkError.

Fix

  1. Вам нужно добавить AWS Lambda IP в Mongo Atlas WhiteListIP
  2. перейти к вашему Your cluster > Network Access > IP Whitelist
  3. нажмите на кнопку ADD IP ADDRESS
  4. нажмите ALLOW ACCESS FROM ANYWHERE, чтобы добавить ip 0.0.0.0/0 в список, нажмите confirm
  5. Проверьте ваш звонок от AWS Lambda, и я буду работать.

НАКОНЕЦ!

Что вы сделали, так это сказали Монго Атласу, что ЛЮБОЙ из НИКОГДА может подключиться к вашему Монго Атласу.

Конечно, это не очень хорошая практика. Что вам нужно, это добавить только AWS Lambda IP, вот когда VPC выходит на сцену. Создать VPC немного сложно, и в нем много крутых шагов, в других комментариях есть хорошие уроки.

Но, конечно же, эта небольшая направляющая справится с MongoNetworkError

0 голосов
/ 08 июля 2019

Требуются некоторые дополнительные шаги, чтобы лямбда вызывала внешнюю конечную точку

https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/

В вашем атласе также должен быть белый список IP-адресов серверов, с которых будет подключаться лямбда.

Еще один вариант - пиринг VPC между лямбда-VPC и Atlas.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...