mongodb 'failed to connect to server' 错误,尽管之前有相同的连接
mongodb 'failed to connect to server' error despite same connection working previously
更新:
运行 getSections
函数本身与手动提供的参数似乎工作正常。打印出导致错误的参数,每次都是不同的设置...
我有一个 updateCurrentTerm() 函数,它在其中调用几个不同的函数,所有这些函数都更新同一数据库的不同集合。这些中的每一个都以完全相同的方式连接到数据库,如下所示:
MongoClient.connect(MONGOURL + term, (err, db) => {
其中 MONGOURL
是 'mongodb://localhost:27017/'
,term
是 '4650'
。但是,该连接似乎适用于 getSchools
、getSubjects
、getCourses
,但不适用于 getSections
。这是我得到的完整错误:
TypeError: Cannot read property 'collection' of null
at /Users/Joon/sans/app.js:129:26
at connectCallback (/Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:315:5)
at /Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:222:11
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
我进一步调查:MongoClient.connect回调的db参数为null意味着err参数不为null。 err 参数包含:
{ MongoError: failed to connect to server [localhost:27017] on first connect
at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/topologies/server.js:313:35)
at emitOne (events.js:96:13)
at emit (events.js:188:7)
at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/pool.js:271:12)
at g (events.js:286:16)
at emitTwo (events.js:106:13)
at emit (events.js:191:7)
at Socket.<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/connection.js:165:49)
at Socket.g (events.js:286:16)
at emitOne (events.js:96:13)
name: 'MongoError',
message: 'failed to connect to server [localhost:27017] on first connect' }
如有任何帮助,我们将不胜感激。谢谢!
app.js
import { MongoClient } from 'mongodb';
import request from 'request-json';
import { EventEmitter } from 'events';
const API = request.createClient('http://www.northwestern.edu/class-descriptions/');
const MONGOURL = 'mongodb://localhost:27017/';
const EVENT = new EventEmitter();
const makeRequest = (query, type, callback) => {
// Possible types:
// terms
// schools
// subjects
// courses
// sections
// details
// Prepare query with correct ending
if (type === 'terms') {
query = 'index-v2.json';
} else if (type === 'details') {
query += '-v2.json';
} else {
query += '/index-v2.json';
}
API.get(query, (err, response, body) => {
if (err) {
console.log(err);
callback(null, err);
} else {
// Parse out last non-data term
const last = body[body.length - 1];
const lastKeys = Object.keys(last);
if (lastKeys.length === 1 && lastKeys[0] === 'ignore') {
body.pop();
}
callback(body, null);
}
});
}
const getTerms = (callback) => {
// TODO: Refactor to insert only if new term
MongoClient.connect(MONGOURL + 'terms', (err, db) => {
const coll = db.collection('data');
coll.remove(); // Start clean
makeRequest('', 'terms', (data, err) => {
if (!err) {
coll.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSchools = (term, callback) => {
// term is the term id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const schools = db.collection('schools');
makeRequest(term, 'schools', (data, err) => {
if (!err) {
schools.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSubjects = (term, school, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const subjects = db.collection('subjects');
const query = term + '/' + school;
makeRequest(query, 'subjects', (data, err) => {
if (!err) {
subjects.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getCourses = (term, school, subject, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
MongoClient.connect(MONGOURL + term, (err, db) => {
const courses = db.collection('courses');
const query = term + '/' + school + '/' + subject;
makeRequest(query, 'courses', (data, err) => {
if (!err) {
courses.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSections = (term, school, subject, course, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
// course is the course abbv
MongoClient.connect(MONGOURL + term, (err, db) => {
console.log(err);
const sections = db.collection('sections');
const query = term + '/' + school + '/' + subject + '/' + course;
makeRequest(query, 'sections', (data, err) => {
if (!err) {
sections.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getDetails = (term, school, subject, course, section, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
// course is the course abbv
// section is the section id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const details = db.collection('details');
const query = term + '/' + school + '/' + subject + '/' + course + '/' + section;
makeRequest(query, 'details', (data, err) => {
if (!err) {
details.insertMany(data, (err, result) => {
callback(data);
});
} else {
db.close();
}
});
});
};
const updateCurrentTerm = () => {
MongoClient.connect(MONGOURL + 'terms', (err, db) => {
const terms = db.collection('data');
// Find term with max id (not mongodb _id)
terms.find().sort({id:-1}).limit(1).next((err, doc) => {
EVENT.emit('maxTerm', doc.id);
db.close();
});
});
EVENT.on('maxTerm', (term) => {
MongoClient.connect(MONGOURL + term, (err, db) => {
db.collection('schools').remove();
db.collection('subjects').remove();
db.collection('courses').remove();
db.collection('sections').remove();
db.collection('details').remove();
db.close();
EVENT.emit('clean', term);
});
});
EVENT.on('clean', (term) => {
getSchools(term, (data) => {
EVENT.emit('updatedSchools', term, data);
});
});
EVENT.on('updatedSchools', (term, data) => {
data.forEach((school) => {
getSubjects(term, school.id, (newData) => {
EVENT.emit('updatedSubjects', term, school.id, newData);
});
});
});
EVENT.on('updatedSubjects', (term, school, data) => {
data.forEach((subject) => {
getCourses(term, school, subject.abbv, (newData) => {
EVENT.emit('updatedCourses', term, school, subject.abbv, newData);
});
});
});
EVENT.on('updatedCourses', (term, school, subject, data) => {
data.forEach((course) => {
getSections(term, school, subject, course.abbv, (newData) => {
EVENT.emit('updatedSections', term, school, subject, course.abbv, newData);
});
});
});
}
updateCurrentTerm();
每次您 运行 查询时,您都在创建一个新实例,它与您的 mongod 的连接太多了!这是行不通的,因为每个实例都会创建并保持至少一个连接(但默认情况下为 10 个),并且这些连接只会在 Java GC 清理您的 Mongo 实例或当您调用 close().
创建到 Mongo 的新连接成本非常高,而且它也会降低您的 mongod 性能。所以创建一个 Mongo 实例并尽可能长时间地保持它的存活!使用静态方法 getInstance() 实现 MongoFactory,returns 延迟创建的实例可以很好地实现这一目的。
更新:
运行 getSections
函数本身与手动提供的参数似乎工作正常。打印出导致错误的参数,每次都是不同的设置...
我有一个 updateCurrentTerm() 函数,它在其中调用几个不同的函数,所有这些函数都更新同一数据库的不同集合。这些中的每一个都以完全相同的方式连接到数据库,如下所示:
MongoClient.connect(MONGOURL + term, (err, db) => {
其中 MONGOURL
是 'mongodb://localhost:27017/'
,term
是 '4650'
。但是,该连接似乎适用于 getSchools
、getSubjects
、getCourses
,但不适用于 getSections
。这是我得到的完整错误:
TypeError: Cannot read property 'collection' of null
at /Users/Joon/sans/app.js:129:26
at connectCallback (/Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:315:5)
at /Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:222:11
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
我进一步调查:MongoClient.connect回调的db参数为null意味着err参数不为null。 err 参数包含:
{ MongoError: failed to connect to server [localhost:27017] on first connect
at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/topologies/server.js:313:35)
at emitOne (events.js:96:13)
at emit (events.js:188:7)
at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/pool.js:271:12)
at g (events.js:286:16)
at emitTwo (events.js:106:13)
at emit (events.js:191:7)
at Socket.<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/connection.js:165:49)
at Socket.g (events.js:286:16)
at emitOne (events.js:96:13)
name: 'MongoError',
message: 'failed to connect to server [localhost:27017] on first connect' }
如有任何帮助,我们将不胜感激。谢谢!
app.js
import { MongoClient } from 'mongodb';
import request from 'request-json';
import { EventEmitter } from 'events';
const API = request.createClient('http://www.northwestern.edu/class-descriptions/');
const MONGOURL = 'mongodb://localhost:27017/';
const EVENT = new EventEmitter();
const makeRequest = (query, type, callback) => {
// Possible types:
// terms
// schools
// subjects
// courses
// sections
// details
// Prepare query with correct ending
if (type === 'terms') {
query = 'index-v2.json';
} else if (type === 'details') {
query += '-v2.json';
} else {
query += '/index-v2.json';
}
API.get(query, (err, response, body) => {
if (err) {
console.log(err);
callback(null, err);
} else {
// Parse out last non-data term
const last = body[body.length - 1];
const lastKeys = Object.keys(last);
if (lastKeys.length === 1 && lastKeys[0] === 'ignore') {
body.pop();
}
callback(body, null);
}
});
}
const getTerms = (callback) => {
// TODO: Refactor to insert only if new term
MongoClient.connect(MONGOURL + 'terms', (err, db) => {
const coll = db.collection('data');
coll.remove(); // Start clean
makeRequest('', 'terms', (data, err) => {
if (!err) {
coll.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSchools = (term, callback) => {
// term is the term id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const schools = db.collection('schools');
makeRequest(term, 'schools', (data, err) => {
if (!err) {
schools.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSubjects = (term, school, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const subjects = db.collection('subjects');
const query = term + '/' + school;
makeRequest(query, 'subjects', (data, err) => {
if (!err) {
subjects.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getCourses = (term, school, subject, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
MongoClient.connect(MONGOURL + term, (err, db) => {
const courses = db.collection('courses');
const query = term + '/' + school + '/' + subject;
makeRequest(query, 'courses', (data, err) => {
if (!err) {
courses.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getSections = (term, school, subject, course, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
// course is the course abbv
MongoClient.connect(MONGOURL + term, (err, db) => {
console.log(err);
const sections = db.collection('sections');
const query = term + '/' + school + '/' + subject + '/' + course;
makeRequest(query, 'sections', (data, err) => {
if (!err) {
sections.insertMany(data, (err, result) => {
db.close();
callback(data);
});
} else {
db.close();
}
});
});
};
const getDetails = (term, school, subject, course, section, callback) => {
// term is the term id (not the mongodb _id)
// school is the school id (not the mongodb _id)
// subject is the subject abbv
// course is the course abbv
// section is the section id (not the mongodb _id)
MongoClient.connect(MONGOURL + term, (err, db) => {
const details = db.collection('details');
const query = term + '/' + school + '/' + subject + '/' + course + '/' + section;
makeRequest(query, 'details', (data, err) => {
if (!err) {
details.insertMany(data, (err, result) => {
callback(data);
});
} else {
db.close();
}
});
});
};
const updateCurrentTerm = () => {
MongoClient.connect(MONGOURL + 'terms', (err, db) => {
const terms = db.collection('data');
// Find term with max id (not mongodb _id)
terms.find().sort({id:-1}).limit(1).next((err, doc) => {
EVENT.emit('maxTerm', doc.id);
db.close();
});
});
EVENT.on('maxTerm', (term) => {
MongoClient.connect(MONGOURL + term, (err, db) => {
db.collection('schools').remove();
db.collection('subjects').remove();
db.collection('courses').remove();
db.collection('sections').remove();
db.collection('details').remove();
db.close();
EVENT.emit('clean', term);
});
});
EVENT.on('clean', (term) => {
getSchools(term, (data) => {
EVENT.emit('updatedSchools', term, data);
});
});
EVENT.on('updatedSchools', (term, data) => {
data.forEach((school) => {
getSubjects(term, school.id, (newData) => {
EVENT.emit('updatedSubjects', term, school.id, newData);
});
});
});
EVENT.on('updatedSubjects', (term, school, data) => {
data.forEach((subject) => {
getCourses(term, school, subject.abbv, (newData) => {
EVENT.emit('updatedCourses', term, school, subject.abbv, newData);
});
});
});
EVENT.on('updatedCourses', (term, school, subject, data) => {
data.forEach((course) => {
getSections(term, school, subject, course.abbv, (newData) => {
EVENT.emit('updatedSections', term, school, subject, course.abbv, newData);
});
});
});
}
updateCurrentTerm();
每次您 运行 查询时,您都在创建一个新实例,它与您的 mongod 的连接太多了!这是行不通的,因为每个实例都会创建并保持至少一个连接(但默认情况下为 10 个),并且这些连接只会在 Java GC 清理您的 Mongo 实例或当您调用 close().
创建到 Mongo 的新连接成本非常高,而且它也会降低您的 mongod 性能。所以创建一个 Mongo 实例并尽可能长时间地保持它的存活!使用静态方法 getInstance() 实现 MongoFactory,returns 延迟创建的实例可以很好地实现这一目的。