[Mongoose] Connections과 srv 레코드
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.connect와 mongoose.createConnection 를 사용하는데 이때 기본적인 최대 사이즈는 100으로 설정되어 있다. 그래서 이 최대 pool 사이즈를 수정하기 위해서는 options을 활용하면 된다.
mongoose.createConnection(uri, { maxPoolSize: 10 });
const uri = 'mongodb://localhost:27017/test?maxPoolSize=10';
mongoose.createConnection(uri);
https://velog.io/@guri_coding/mongoose-공부하기-3-Connections-파헤치기
[mongoose 공부하기 [3] - Connections 파헤치기
mongoose의 핵심인 Connection을 공부하고 정리했습니다.
velog.io](https://velog.io/@guri_coding/mongoose-공부하기-3-Connections-파헤치기)
위의 내용을 가져왔습니다.
SRC 레코드
위를 공부하면서 mongodb uri에 src가 붙거나 안붙거나 무슨 차이일지 궁금해졌습니다.
스택오버플로우의 답변에 의하면 다음과 같습니다.
MongoDB 3.6에는 DNS 레코드, 특히 SRV 및 TXT 레코드를 사용하여 지정되는 시드 목록 개념이 도입되었습니다.
연결 시 클라이언트가 적어도 하나의 복제본 세트 구성원을 지정해야 한다는
MongoDB와 함께 복제본 세트를 사용하는 것을 기억할 것입니다(여러 개를 지정할 수도 있음).
이렇게 하면 클라이언트가 지정한 노드 중 하나를 사용할 수 없는 경우에도 클라이언트가 복제 세트에 연결할 수 있습니다.
SRV레코드란 무엇인가
서비스 레코드 ( SRV 레코드 ) 는 지정된 서비스에 대한 서버의 위치(예: 호스트 이름 및 포트 번호)를
정의하는 도메인 이름 시스템 의 데이터 사양입니다 .
SRV는 우리가 db와 커넥팅할때 입력해주는 도메인주소의 일정 규격을 의미 합니다 SRV를 붙이는 이유는 해당 규격을 명시 해주는것 입니다.
다음과 같은 내용이 담겨 있습니다.