MongoDB Replica Set Connection not created on server - node.js

I am using MongoDB 4.0. I have a Replica Set which run on my machine and different ports that is:
127.0.0.1:27017 (Master)
127.0.0.1:27018 (Slave)
127.0.0.1:27019 (Arbiter)
My replica name is "xdr"
Now on creating the connection on localhost in my nodejs code it will create the connection i.e
const options = {
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
autoReconnect : true
};
mongoose.connect('mongodb://localhost:27017, localhost:27018, localhost:27019/my_db?replicaSet=xdr, options);
mongoose.Promise = global.Promise;
//Get the default connection
var db = mongoose.connection;
//Bind connection to error event (to get notification of connection errors)
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
Everything is fine in this on my local connection but when i will host my mongodb On seperate EC2 Instance on AWS, it will not connect to my replica set.
lets assume that my mongodb AWS IP is 12.12.13.12.
So when i will create the connection it will not be able to connect. My code is
const options = {
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
autoReconnect : true
};
mongoose.connect('mongodb://12.12.13.12:27017, 12.12.13.12:27018, 12.12.13.12:27019/my_db?replicaSet=xdr, options);
mongoose.Promise = global.Promise;
//Get the default connection
var db = mongoose.connection;
//Bind connection to error event (to get notification of connection errors)
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
It will generate an error i.e ""
if I will connect without replicaset then it will connect only to primary i.e
mongoose.connect('mongodb://12.12.13.12:27017/my_db, options);
Is there anything which I am doing wrong on my code?

Have you verified that port 27017 and 27018 are open on your EC2 ?
You don't need to specify the arbitrer.
You have to inform mongo that you use a replicaset, with the replset option.
I use the following for my replicaset :
var config = {
db: "mongodb://myMasterIp:27017/myDb,mySlave1Ip:27018/myDb"
options: {
user: config.db_user,// only if you use username/password for DB authentication
pass: config.db_pass,// only if you use username/password for DB authentication
replset: {
rs_name: "MyReplicaSetName",
ssl: true,// only if you use ssl for your replicaset
sslValidate:false,// only if you use ssl for your replicaset
sslCA: myDbCertificate,// only if you use ssl for your replicaset
ca: myDbCertificate,// only if you use ssl for your replicaset
sslKey: myDbKey,// only if you use ssl for your replicaset
sslCert: myDbKey // only if you use ssl for your replicaset
},
socketOptions : {
keepAlive : 1,
connectTimeoutMS : 5000
},
server: { // only if you use ssl for your replicaset
ssl: true,
sslValidate:false,
sslCA: myDbCertificate,
ca: myDbCertificate
sslKey: myDbKey,
sslCert: myDbKey
},
auth: { // only if you use username/password for DB authentication
authdb: 'myAuthenticationDatabse'
}
}
};
mongoose.connect(config.db, config.options);

Related

Why node.js application auto-disconnect from Atlas MongoDB after some idle period and how to prevent this?

I have node.js app hosted on HEROKU and Atlas MongoDB database cluster.
In node app I connect to this db with standard command
mongoose.connect("mongodb+srv://user:password#cluster0.jzycr.mongodb.net/database?retryWrites=true&w=majority", { useNewUrlParser: true,useFindAndModify: false, useUnifiedTopology: true });
I noticed issue that if there is no activity/no requests from users to app during a few hours my app automatically disconnects from Atlas db, I see it from log using mongoose.connection.readyState, it's equal to 0 (disconnected).
Is that normal behavior even with option useUnifiedTopology: true ?? I supposed that this flag auto-reconnect to database.
How to keep permanent connection to database even if there is long idle period? Should I use timer in my app to periodically check connection and manually re-connect again if mongoose.connection.readyState = 0 ?? What is the best pattern for this issue?
let dbOptions = {
dbName: process.env.MONGO_DATABASE_NAME,
useNewUrlParser: true,
poolSize: process.env.MONGO_POOL_SIZE || 10,
autoReconnect: true,
reconnectInterval: 1000,
reconnectTries: 10,
};
mongoose.connect(process.env.MONGO_URI, dbOptions);
// Create connection object.
const db = mongoose.connection;
Try this configuration

Connect to a remote server mongoDB via ssh through mongoose in nodeJS using tunnel-ssh

I was trying to connect to a remote server mongoDB through SSH and made the configurations as provided
import tunnel from 'tunnel-ssh';
const config = {
username: 'username',
Password: 'password',
host: process.env.SSH_SERVER, //192.168.9.104
port: 22,
dstHost: 'localhost',
dstPort: process.env.DESTINATION_PORT, //27017
localHost: '127.0.0.1',
localPort: 27018
};
This is the config that has been defined where i need to connect to the remote server 192.168.9.104. So the particular is chosen as the SSH host. Username and password for the same is provided. and the connection made is as follows.
class DB {
initDB() {
tunnel(config, (error, server) => {
if (error) {
console.log('SSH connection error: ' + error);
}
const url = 'mongodb://127.0.0.1:27018/myDBname';
mongoose.connect(url, { useNewUrlParser: true });
mongoose.plugin(toJson);
mongoose.plugin(setProperties);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'DB connection error:'));
db.once('open', function() {
console.log('DB connection successful');
});
});
}
}
But when the db.init() function is called following error pops up
events.js:183
throw er; // Unhandled 'error' event
^
Error: All configured authentication methods failed
I am not able to figure out where the config goes wrong. i have tried using 127.0.0.1 for dstHost. as well as put the 192.168.9.104 as the dstHost as well but the error persists. kevin lee suggests a similar approach. this question is used as an example
There was an error with the documentation which suggested the config as mentioned above with the key "Password" but it should be "password" so the config would look something like this
const config = {
username: 'username',
password: 'password',
host: process.env.SSH_SERVER, //192.168.9.104
port: 22,
dstHost: 'localhost',
dstPort: process.env.DESTINATION_PORT, //27017
localHost: '127.0.0.1',
localPort: 27018
};
Rest of the implementation is spot on and tested.

Issue with tunnel-ssh npm for ssh connection to mongo through mongoose

I am trying to establish a connection to remote mongo server through ssh tunnel using mongoose
The implementation code is:
import tunnel from 'tunnel-ssh';
const config = {
username: 'username',
Password: 'password',
host: process.env.SSH_SERVER, //192.168.9.104
port: 22,
dstHost: process.env.DESTINATION_SERVER, //192.168.9.104
dstPort: process.env.DESTINATION_PORT, //27017
localHost: '127.0.0.1',
localPort: 27017
};
this is the config that i have created while the connection is as follows:
class DB {
initDB() {
tunnel(config, (error, server) => {
if (error) {
console.log('SSH connection error: ' + error);
}
const url = 'mongodb://' + process.env.MONGO_URL; //localhost:27017/DBname
mongoose.connect(url, { useNewUrlParser: true });
mongoose.plugin(toJson);
mongoose.plugin(setProperties);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'DB connection error:'));
db.once('open', function() {
console.log('DB connection successful');
});
});
}
}
When the function initDB() is invoked the following error pops up
SSH connection error: ConfigError: host not set
events.js:183
throw er; // Unhandled 'error' event
^
ConfigError: host not set
The host is already set but this error seems to be somewhere in the config part but I doesnt seem to single out to the exact reason
your "host" property at "config" var isn't defined. try using hard coded value instead of env var, if it works it means process can't read env vars which might be caused since you R not importing dotenv module

Minimal Mongoose SSL connection code

I need to get a MongoDB connection to Node.js with Mongoose and Express to connect with SSL, but I can't connect even after knowing the keys work by connecting with Robomongo.
'use strict';
var mongoose = require('mongoose'),
fs = require('fs'),
express = require('express');
mongoose.set('debug', true);
// Bootstrap db connection
var db = mongoose.connect('mongodb://localhost/test', {
options: {
ssl: true,
port: 27017,
user: 'xxxxxxxx',
pass: 'xxxxxxxx_',
sslValidate: false,
checkServerIdentity: false,
sslCA: fs.readFileSync('./config/sslcerts/mongodb.pem'),
sslCert: fs.readFileSync('./config/sslcerts/mongodb-cert.crt'),
sslKey: fs.readFileSync('./config/sslcerts/mongodb-cert.key'),
sslPass: 'xxxxxx'
},
},
function(err) {
console.error('Could not connect to MongoDB!');
console.log(err);
});
// Init the express application
var app = require('express')(db);
app.listen(8443);
console.log('MEAN.JS application started on port ' + 8443);
Here is how I fire mongod:
$ mongod --fork --logpath mongodblogs/mongodb.log --dbpath mongodb
--bind_ip 127.0.0.1 --sslMode requireSSL --sslPEMKeyFile /app/website/config/sslcerts/mongodb.pem --sslCAFile
/app/website/config/sslcerts/mongodb-cert.crt -v
Errors:
Could not connect to MongoDB! MongoError: connection 0 to
localhost:27017 closed
same code, sometimes with another different error:
Could not connect to MongoDB! MongoError: read ECONNRESET
Mongoose version: "raw": "mongoose#4.10.8",
Node version 4.8.0
Can someone help?

Mongoose gives error while connecting using mongolab uri ?

It gives the following error-
mongoose connection error: { [MongoError: connect EINVAL] name: 'MongoError', message: 'connect EINVAL' }
/home/user/Documents/oes/node_modules/connect-mongo/node_modules/mongodb/lib/server.js:228
process.nextTick(function() { throw err; })
^
Error: connect EINVAL
at errnoException (net.js:905:11)
at connect (net.js:767:19)
at net.js:846:9
at asyncCallback (dns.js:68:16)
at Object.onanswer [as oncomplete] (dns.js:121:9)
14 Jun 18:04:11 - [nodemon] app crashed - waiting for file changes before starting...
This is a very old problem, But as no one has yet answered it.
We often see that users have problems connecting to MongoLab using the Mongoose driver. The root cause is almost always incorrect configuration of the driver, particularly around timeouts. The following is a connection example using the MongoLab-recommended driver options:
// mongoose 4.3.x
var mongoose = require('mongoose');
/*
* Mongoose by default sets the auto_reconnect option to true.
* We recommend setting socket options at both the server and replica set level.
* We recommend a 30 second connection timeout because it allows for
* plenty of time in most operating environments.
*/
var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } },
replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };
var mongodbUri = 'mongodb://user:pass#host:port/db';
mongoose.connect(mongodbUri, options);
var conn = mongoose.connection;
conn.on('error', console.error.bind(console, 'connection error:'));
conn.once('open', function() {
// Wait for the database connection to establish, then start the app.
});
If this doesn't help, please ensure your password or username doesn't has any special character, Try to connect it via CMD first.
Hope I helped :)

Resources