Сбой подключения MongoDB на нескольких серверах приложений - PullRequest
0 голосов
/ 09 октября 2018

У нас есть mongodb с драйвером mgo для golang.Есть два сервера приложений, которые подключаются к mongodb, кроме приложений (golang binaries).Mongodb работает как набор реплик, и каждый сервер соединяет два основных или дополнительных в зависимости от текущего состояния реплики.

Мы испытали SocketException handling request, closing client connection: 9001 socket exception на одном из серверов mongo (что привело к гибели соединения с mongodb из наших приложений. После этого набор реплик продолжал функционировать, но наш второй сервер (на которомошибка не произошла) соединение также прервалось.

В логах golang это проявлялось как:

read tcp 10.10.0.5:37698-\u003e10.10.0.7:27017: i/o timeout

Почему это произошло? Как это могло произойти?быть предотвращенным?

Как я понимаю, mgo подключается ко всей реплике по URL (он определяет всю топологию по URL-адресу одного экземпляра), но почему отключено соединение на одном из серверов?это на втором?

Редактировать:

  1. Полный путь к пакету, который используется "gopkg.in/mgo.v2"
  2. К сожалению, здесь нельзя обмениваться файлами монго. Но кроме socketexecptionЖурналы mongo не содержат ничего полезного.Есть указание на некоторую степень конкуренции за блокировку, когда время получения блокировки довольно высокое, но ничего кроме этого
  3. MongoDB делает некоторые тяжелые операции.Несколько раз, но в последнее время не было никаких необычных всплесков, так что нет ничего сверх нормального

1 Ответ

0 голосов
/ 16 октября 2018

Во-первых, драйвер mgo, который вы используете: gopkg.in/mgo.v2, разработанный Густаво Нимейером (размещен на https://github.com/go-mgo/mgo), больше не поддерживается.

Вместо этого используйте поддержку сообщества fork github.com/globalsign/mgo. Этот патч продолжает развиваться и развиваться.

Его список изменений включает в себя: "Улучшенная обработка соединений" , которая, по-видимому, имеет прямое отношение к вашей проблеме.

Его подробности можно прочитать здесь https://github.com/globalsign/mgo/pull/5, который указывает на исходный запрос на извлечение https://github.com/go-mgo/mgo/pull/437:

Если mongoServer не сможет набрать сервер, он закроет все живые сокеты,независимо от того, используются они в настоящее время или нет. Есть два минуса:

  • Запросы в полете будут прерываться грубо.

  • Все сокеты закрыты нав то же время, и, вероятно, одновременно набирает номер сервера. Любой случайный сбой в запросах массового набора (сценарий с высоким параллелизмом) снова закроет все сокеты и повторится ... (Это произошло в нашей производственной среде)

Так что я думаю, что используемые в настоящее время сокеты должны закрываться после простоя.

Обратите внимание, что github.com/globalsign/mgo имеет обратно совместимый API, в основном он просто добавил несколько новых вещей / функций (помимоисправления и исправления), что означает, что вы должны иметь возможность просто изменить пути импорта, и все должно работать без дальнейших изменений.

...