Обработка MongoDB отключение / повторное подключение от узла
Когда мое соединение MongoDB простаивает в течение нескольких минут, следующий запрос заканчивается ошибкой. От mongo
клиент командной строки, это выглядит так:
> db.users.find()
Sat Jan 12 23:42:35 Socket recv() errno:54 Connection reset by peer 107.22.25.25:47207
Sat Jan 12 23:42:35 SocketException: remote: 107.22.25.25:47207 error: 9001 socket exception [1] server [107.22.25.25:47207]
Sat Jan 12 23:42:35 DBClientCursor::init call() failed
Sat Jan 12 23:42:35 query failed : chowology.users {} to: ds047207.mongolab.com:47207
Error: error doing query: failed
Sat Jan 12 23:42:35 trying reconnect to ds047207.mongolab.com:47207
Sat Jan 12 23:42:35 reconnect ds047207.mongolab.com:47207 ok
Я вижу проблему с экземплярами песочницы MongoHQ и MongoLab.
Следующий запрос проходит нормально из-за переподключения. Это проблема в моем веб-приложении, потому что после нескольких минут бездействия эта ошибка возникнет во время веб-запроса. Есть две вещи, которые меня удивляют:
- Что подключения MongoDB разрушаются так регулярно и часто, и
- То, что драйвер просто вызывает исключение, в отличие от автоматической повторной попытки после повторного подключения (я использую connect-mongo, который использует mongoose, который, в свою очередь, использует node-mongodb-native).
Это опыт всех остальных? Как это должно быть обработано? Я был бы удивлен, если бы разработчики приложений включили свои операции с базой данных в какую-то ерунду с обработкой повторных попыток.
3 ответа
Вы хотите посмотреть на документы для объекта сервера
http://mongodb.github.com/node-mongodb-native/api-generated/server.html
Особенно в socketOptions, где вы можете установить keepAlive и время ожидания соединения. По умолчанию keepalive отключен, а тайм-аут равен 0 или никогда, что означает, что тайм-аут сокета os по умолчанию действует (изменяется от os к os). Keep alive отправит пакет раз в какое-то время по соединению tcp socket, чтобы поддерживать его в рабочем состоянии. Иногда брандмауэры плохо настроены и не отправляют конечный пакет, когда они закрывают соединение, оставляя соединение мертвым и находящимся в подвешенном состоянии, о чем говорят монологи (чаще всего, если честно, они ужасно настроены).
- Убедитесь, что ваш компьютер не будет спать
- Убедитесь, что ваш маршрутизатор / брандмауэр не прерывает неактивные соединения
Первой проблемой оказался мой компьютер, спящий и неосознанно обрывающий сетевое соединение. Это новый компьютер, и я не осознавал, что не отключил сон:-P
Джаред из MongoLab помог мне решить эту проблему, и я благодарен за это. Он сказал, что такое поведение распространено при прохождении через брандмауэр (как предложил mjhm в своем комментарии). Таким образом, один тест должен был бы обойти это.
Все еще проходя через мой маршрутизатор, я получаю другую ошибку после нескольких часов простоя:
db.users.find()
Sun Jan 13 14:55:02 Socket say send() errno:32 Broken pipe 107.22.25.25:47207
Error: 9001 socket exception [2] server [107.22.25.25:47207]
Sun Jan 13 14:55:02 trying reconnect to ds047207.mongolab.com:47207
Sun Jan 13 14:55:02 reconnect ds047207.mongolab.com:47207 ok
Я попробую это снова с сервера, который не проходит через мой маршрутизатор / брандмауэр.
Поведение драйвера, вызывающего исключение в текущем операторе, является ожидаемым и приемлемым, поскольку разрыв соединения является действительно исключительным случаем.
Обновление: ни одна из этих проблем не возникает, когда я обхожу свой маршрутизатор, и не возникает в моем экземпляре Nodejitsu, который, я считаю, работает в центре обработки данных Joyent.
У меня была такая же проблема, и я думаю, что это потому, что я захожу в Интернет через прокси-сервер