Main aspects:
- checking MongoDB connection status using the
.isConnected()
method - listening to MongoDB events like:
closed
,reconnect
,timeout
and others - Setting
appname
and checking what applications are connected to a database
Checking if the MongoDB database is connected?
Let’s say that we have a DbClient
class where we have a .connect()
method which looks like that:
public async connect() {
if (this.db === undefined ||
(this.db.serverConfig).isConnected() === false) {
console.log("Connecting to database");
this.db = await MongoClient.connect("mongodb://localhost:27017/test");
} else {
console.log(`Already connected to database: ${this.db.databaseName}`);
}
return this.db;
}
That code preventing us from connecting to the same database many times. But what if we need to detect and react somehow when the application loses the connection? For applications working online, it would be a tough situation. Thankfully MongoDB driver allows us to detect that kind of situations.
Monitoring MongoDB events
By default the Db
object allows listening to a few basics events like: close
, reconnect
, timeout
, error
,authenticated
. That could be used as follow:
this.db.on("close", () => console.log(`CLOSE event on db: ${this.db.databaseName}`));
this.db.on("reconnect", () => console.log(`RECONNECT event on db: ${this.db.databaseName}`));
this.db.on("timeout", () => console.log(`TIMEOUT event on db: ${this.db.databaseName}`));
this.db.on("error", () => console.log(`ERROR event on db: ${this.db.databaseName}`));
this.db.on("timeout", () => console.log(`TIMEOUT event on db: ${this.db.databaseName}`));
Listening to a particular event is very simple. You can log a relevant message with the correct log status (usage of console.log()
is a just an example). If you wish you can also do other actions like sending an email or a push notification to your DevOps team. It’s up to you.
You might also create a dedicated endpoint which will return 200 status when a database is connected, and then use that endpoint in some monitoring tool.
How to automatically reconnect to the database?
While your application loses the connection to the database it would be nice if it could reconnect automatically as soon as it’s possible. To do that we need to set the reconnectTries
option. By default, MongoDB’s driver will try to reconnect 30 times every 1000 ms (1 sec). That time interval can be adjusted by setting the desired value for reconnectInterval
option.
this.db = await MongoClient.connect("mongodb://localhost:27017/test", {
reconnectTries: Number.MAX_VALUE, // try reconnect as long as it's possible (default: 30),
reconnectInterval: 500, // retry every 0.5 second (default value is 1000 ms - 1 sec)
});
To test the above solution we will:
- start MongoDb server
- start our application which:
- connects to MongoDB server
- try to connect again (just to check if we can connect twice to the same database)
- try to save some document
- restart the MongoDb server and observe what happens
Results:
The full source code is available here
How to monitor connections on MongoDB side?
When a few applications connect to the same database sometimes you might need to check what apps are connected to a given database. MongoDB contains a db.currentOp()
method for checking in-progress operations. To return idle connections you need to call it with an argument: db.currentOp($all)
.
You can see that some connections have a clientMetadata
property where you can check what driver and OS was used to establish the connection. There is also an appName
property which contains the application name. We can set value for the appName
in our node application.
const options = {
appname: appName,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
};
this.db = await MongoClient.connect("mongodb://localhost:27017/test", options);
- Please note that the property name used in MongoDB’s node.js driver is
appname
(all lowercase) notappName
. - You might also see an error that property
appname
is not recognized as a valid field ofMongoClientOptions
. Unfortunately, it’s missing in Typescript definitions for MongoDB. The temporary solution for that is casting the options object toany
type (Yes, I know…).
The final results:
The full source code is available here
That’s all I hope that it would be useful for you. If you have any questions please let me know.
'Language > JavaScript' 카테고리의 다른 글
new Date & ISO String (1) | 2019.02.18 |
---|---|
[nodejs] mongoose 커넥션 이벤트 함수 (1) | 2019.02.14 |
node.js express에서 CORS 허용하기 (0) | 2019.02.04 |
[Nodejs] [node.js] express.js 라우트 요청 객체(req), 응답 객체(res) 정리 (0) | 2018.12.13 |
[nodeJs] PM2 - 2 (0) | 2018.12.12 |