Соединения MongoDB, скачущие при соединении с Node + Express - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь создать несколько API для моего мобильного приложения. Я использую Node + Express + Mongo + Firebase. На основе предложений, приведенных в других местах ( Как правильно повторно использовать соединение с Mongodb через приложение и модули NodeJs ), я создал следующую структуру кода:

My code structure looks like this

Это то, что у меня есть в моем mongoUtils.js:

const MongoClient = require('mongodb').MongoClient
const uri = "mongodb+srv://user:password@blabla.azure.mongodb.net/bla?retryWrites=true&w=majority";

let _db

const connectDB = async (callback) => {
    try {
        MongoClient.connect(uri,{ useNewUrlParser: true }, (err, client) => {
            _db = client.db('ABC');
            return callback(err)
        })
    } catch (e) {
        throw e
    }
}

const getDB = () => _db
const disconnectDB = () => _db.close()
module.exports = { connectDB, getDB, disconnectDB }

Это то, что у меня есть в моем index.js:

const functions = require('firebase-functions');
const express = require('express');
const app = express();
var cors = require('cors');
app.use(cors());
const admin = require('firebase-admin');
const bodyParser = require('body-parser')
const assert = require('assert');

const MongoDB = require('./db/mongoUtils')

admin.initializeApp(functions.config().firebase);
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())

app.post('/getUserByPhone',(request,response)=>{

    MongoDB.connectDB(async (err) => {
        assert.equal(null, err);
        console.log("Connected correctly to server");
        const db = MongoDB.getDB();
        const collection = db.collection('users');
        console.log(request.body.phone);
        // Find some documents
        collection.find({/*Query here*/}).toArray(function(err, docs) {
            assert.equal(err, null);
            console.log("Found the following records");
            console.log(docs)
            response.send(docs);
        })
    })
})

app.post('/getUserById',(request,response)=>{
    var ObjectId = require('mongodb').ObjectId; 
    var id = request.body.userId;
    var userId = new ObjectId(id);

    MongoDB.connectDB(async (err) => {
        assert.equal(null, err);
        const db = MongoDB.getDB();
        console.log("Connected correctly to server");
        const collection = db.collection('users');
        collection.find({/*Query*/}).toArray(function(err, docs) {
            assert.equal(err, null);
            console.log("Found the following records");
            console.log(docs)
            response.send(docs);
        })
    })
})

app.post('/moreFunction',async(request,response)=>{
    var currTime = new Date();

    MongoDB.connectDB(async (err) => {
        assert.equal(null, err);
        const db = MongoDB.getDB();
        const collection = db.collection('coll_2');

        collection.find().toArray(function(err, docs) {
            assert.equal(err, null);
            response.send(docs);
        });
    })     
})

app.post('/anotherFunction',async(request,response)=>{
    MongoDB.connectDB(async (err) => {
        assert.equal(null, err);
        const db = MongoDB.getDB();
        console.log("Connected correctly to server");
        const collection = db.collection('coll_name');
        collection.find().toArray(function(err, docs) {
            assert.equal(err, null);
            response.send(docs);
        });
    })     
})

exports.api = functions.https.onRequest(app);

Теперь, когда угодноЯ тестирую свое приложение, запустив его на своем Android-устройстве, и я вижу всплеск соединений в моей консоли MongoDb. Вместо одного соединения я вижу, что приложение использует около 25-30 соединений при навигации между экранами. Что не так с моим подходом? Почему он использует так много подключений?

Это приложение не опубликовано, и я единственный пользователь.

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Я знаю, что это вопрос nodejs, но приведенный ниже дизайн решит эти проблемы независимо от того, какой язык вы выберете.

Независимо от того, какой код вы пишете и на каком языке, если вы создаете новые объекты в каждом скрипте,даже с пулом соединений на стороне MongoDB вы увидите всплеск. У нас была реализация Java, и мы увидели похожий всплеск. Наш пул соединений увеличился до 340 из 350 макс. Подключений в Atlas, даже со статическими объектами соединений, вместе со всеми лучшими практиками.

Что вам нужно сделать, так или иначе создать 1 объект const MongoDB = require('./db/mongoUtils') при запуске сервера,и сохраните его где-нибудь (в кэше / сериализованном ... что угодно) и убедитесь, что он доступен во всем приложении. И заставить все ваши классы / сценарии nodejs использовать этот же объект через какую-то общую функцию / getter.

После того, как мы выполнили это в Java, используя ServletContext для хранения одного объекта соединения, мы увидели, что наши соединения были ограничены до 40-50 макс. одновременно на Атласе MongoDB.

0 голосов
/ 18 октября 2019

У вас есть странное сочетание async / await и обратных вызовов, и, хотя я не собираюсь писать ваш код для вас, я мог бы предложить пару предложений.

В идеале у вас должна быть некоторая инициализация, которая может подключить адаптер MongoDB до того, как вам понадобится вызвать его, чтобы вы не ожидали ранее выполненное обещание (дополнительный код) или каждый раз разрушали и создавали новое соединениеВы получаете запрос (дополнительный код и занимает дополнительное время для трехстороннего рукопожатия TLS). Я написал решение для повторного использования кода подключения и инициализации до здесь .

const MongoClient = require('mongodb').MongoClient
const uri = "mongodb+srv://user:password@blabla.azure.mongodb.net/bla?retryWrites=true&w=majority";

const client = new MongoClient(uri);
// client.connect returns a promise that can be awaited
const connectDB = () => client.connect();


const getDB = () => client.db;
// so does db.close
const disconnectDB = () => client.db.close();
module.exports = { connectDB, getDB, disconnectDB }

const MongoDB = require('./db/mongoUtils')

app.post('/getUserByPhone', async (request,response)=>{
    try {
      await MongoDB.connectDB();
      const db = MongDB.getDB();
      const collection = db.collection('users');
      const docs = await collection.find({/*Query here*/}).toArray();
      response.send(docs);
    } catch (e) {
      // handleErr(e);
      return response.send({ok: false}).status(500);
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...