mongoose 공부하기 [3] - Connections 파헤치기

김진성·2021년 10월 19일
3

MongoDB

목록 보기
3/7

Connections

mongoose를 연결하는 기본적인 구조는 아래와 같다.

// 로컬 서버에 접속할 경우
mongoose.connect('mongodb://localhost:27017/myapp');

// 클라우드 서버에 접속할 때
mongoose.connect('mongodb://username:password@host:port/database?options...');

Operation Buffering

mongoose는 기술적으로 우리가 app을 실행했을 때 바로 mongodb와 연결이 되어 우리가 앱을 작동할 수 있게 한다.

mongoose.connect('mongodb://localhost:27017/myapp');
const MyModel = mongoose.model('Test', new Schema({name: String}));

MyModel.findOne(function(error, result) {/* ... */});

// 연결되지 않으면 에러가 발생하지 않고, 연결되면 에러가 발생한다. 
setTimeout(function() {
	mongoose.connect('mongodb://localhost:27017/myapp');
}, 60000);

mongoose에서 내부적으로 모델 함수를 호출하기 때문에 편리하지만 연결하지 않고 모델 함수를 사용하면 우리는 에러를 알 수 없는 단점이 존재한다.

버퍼링은 우리가 autoCreate를 사용하면 컬렉션을 생성하는 동안 발생한다. 만약 이 경우에도 버퍼링을 작동하지 않게 하려면 createCollection()을 사용하거나 autoCreate 옵션을 변경하면 된다.

const schema = new Schema({
	name: String
}, {
	capped: {size: 1024},
    bufferCommands: false,
    autoCreate: false
});

const Model = mongoose.model('Test', schema);
await Model.createCollection();

Error Handling

연결과정에서 발생하는 오류 유형에는 다음과 같이 존재한다.

  • 초기에 연결할 때 연결에 실패한다면 error 를 호출하고 mongoose.connect()가 거부된다. 이때, 자동적으로 재연결되지 않으니 다시 시도해야 한다.
  • 초기 연결이 끝난 이후 다시 연결을 시도할 때 에러가 발생한다.

이 경우 .catch()try/catch로 해결할 수 있다.

mongoose.connect('mongodb://localhost:27017/test').
	catch(error => handleError(error));

or

try {
	awiat mongoose.connect('mongodb://localhost:27017/test');
} catch (error) {
	handleError(error);
}

연결 이후에 다시 연결 오류가 발생할 경우에는 아래와 같이 error를 호출할 수 있다.

mongoose.connection.on('error', err => {
	logError(err);
})

Options

connect 함수에 options 오브젝트를 이용해 MongoDB에 여러 정보를 전달 할 수 있다.

기본 형태

mongoose.connect(uri, options);

예시

cosnt options = {
	autoIndex: false,
    maxPoolSize: 10,
    serverSelectionTimeoutMS: 5000,
    socketTimeoutMS: 45000,
    family: 4
};
mongoose.connect(uri, options);

Callback

connect 함수에 promise로 콜백 파라미터를 사용할 수 있다.

mongoose.connect(uri, options, function(error){
	초기 에러를 체크하고 콜백을 위한 파라미터가 없다.
});

mongoose.connect(uri, options).then(
	() => { 사용할 준비가 된 경우 }
    err => { 초기 에러가 발생한 경우 }
);

keepAlive (서버 유지)

애플리케이션을 서버에 올리고 작동시킬 때 ms 단위로 서버 환경을 체크하게 되는데 시간이 지나면 서버가 꺼지기 때문에 계속 서버를 유지하기 위해서는 아래와 같이 해야 한다.

mongoose.connect(uri, {keepAlive: true, keepAliveInitialDelay: 300000});

Replica Set Connections (서버 복사)

기본적으로 여러 서버에 복사해 운영하는 법

mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);

mongoose.connect('mongodb://user:pw@host1.com:27017,host2.com:27017,host3.com:27017/testdb');

하나의 서버 복사본과 연결할 때

mongoose.connect('mongodb://host1:port1/?replicaSet=rsName');

Server Selection (서버 탐색)

Mongoose가 uri를 통해 서버를 탐색하는 동안 서버에 연결이 되지 않는 경우 에러가 발생한다.

MongoTimeoutError: Server selection timed out after 30000 ms

따라서, serverSelectTimeoutMS로 일정 시간 이후에 서버 연결이 되지 않으면 에러를 발생시킬 수 있다.

const mongoose = require('mongoose');

const uri = 'mongodb+srv://username:badpw@cluster0-OMITTED.mongodb.net/' + 'test?retryWrites=true&w=majority';

mongoose.connect(uri, {
  serverSelectionTimeoutMS: 5000
}).catch(err => console.log(err.reason));

Multi connections

Multi-connections를 이용하는 이유는 2가지 이다.

  • 하나는 우리가 여러 DB를 사용할 경우
  • 다른 하나는 DB 탐색 시 동시 들어온 요청을 빠르게 처리하고 싶은 경우 (slow trains 이라고 함)

기본 형태

const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);

여기서 봐야하는 것은 module.exports를 진행할 때 Schema 형태로 내보내야 한다는 것이다.

const userSchema = new Schema({ name: String, email: String });

module.exports = userSchema;
const UserModel = conn.model('User', userSchema);

예시) 스키마 패턴을 외부로 꺼내 모델과 연결 시키는 경우

// connections/fast.js
const mongoose = require('mongoose');

const conn = mongoose.createConnection(process.env.MONGODB_URI);
comm.model('User', require('../schemas/user'));

module.exports = conn;

// connections/slow.js
const mongoose = require('mongoose');

const conn = mongoose.createConnection(process.env.MONGODB_URO);
conn.model('User', require('../schemas/user'));
conn.model('PageView', require('../schemas/pageView'));

model.exports = conn;

예시) 의존성 주입 혹은 Inversion of Control(IOC) 패턴으로 연결 시키는 경우

const mongoose = require('mongoose');

module.exports = function connectionFactory() {
	const conn = mongoose.createConnection(process.env.MONGODB_URI);
    
    conn.model('User', require('../schemas/user'));
    conn.model('Pageview', require('../schemas/pageView'));
    
    return conn;
};

Connection Pools

우리가 연결할 때 mongoose.connectmongoose.createConnection 를 사용하는데 이때 기본적인 최대 사이즈는 100으로 설정되어 있다. 그래서 이 최대 pool 사이즈를 수정하기 위해서는 options을 활용하면 된다.

mongoose.createConnection(uri, { maxPoolSize: 10 });

const uri = 'mongodb://localhost:27017/test?maxPoolSize=10';
mongoose.createConnection(uri);
profile
https://medium.com/@jinsung1048 미디엄으로 이전하였습니다.

0개의 댓글