Структура кода приложения на основе Mgo, связанная с пулом соединений и тайм-аутами TCP

Мне любопытно, как мне структурировать сервер JSON REST API на языке Go с Mgo. У меня есть десятки коллекций, связанных друг с другом. Я создал суть с образцом файловой структуры в моем текущем подходе.

Он отлично работает, но время от времени я сталкиваюсь с простоями, вызванными этой ошибкой: «чтение tcp 10.168.30.100:37288: тайм-аут ввода-вывода». Я полагаю, что неправильно обрабатываю пул соединений mgo. Есть ли примеры, показывающие, как создавать большие приложения на основе mgo?


person Rafał Sobota    schedule 08.11.2013    source источник
comment
Вы вообще создавали большие приложения в MongoDB? Я имею в виду, может быть проблема, потому что ваша модель данных не так хороша, тогда время, затрачиваемое на загрузку всех данных, которые вам нужны, занимает много времени (просто гость: D)   -  person nvcnvn    schedule 08.11.2013
comment
В большинстве случаев это супер быстро. После перезагрузки сервера эта проблема исчезает.   -  person Rafał Sobota    schedule 08.11.2013
comment
Вы пытаетесь создать новое соединение с mongodb для каждого запроса (я имею в виду cal mgo.Dial в обработчике http). Возможно, профилирование вашей программы поможет вам.   -  person nvcnvn    schedule 08.11.2013
comment
Я нашел несколько ответов от самого автора mgo, которые могут вас заинтересовать: groups. google.com/d/msg/mgo-users/iZeiKgonGDU/2w4jf0V18TgJ groups.google.com/d/msg/mgo-users/oVJcXKPvNbU/L4AxMFDooD8J   -  person Andrea Di Persio    schedule 08.11.2013
comment
У меня есть приложение node.js в производстве с более чем 100 000 пользователей, но оно также борется с тайм-аутами, поэтому, возможно, решение для этого могло бы быть более универсальным. Этот сервер в ходу большую часть времени работает на запросе в 20-200 мс.   -  person Rafał Sobota    schedule 08.11.2013
comment
@nvcnvn Я создаю соединение только один раз при запуске приложения и использую его в каждом обработчике HTTP-запросов.   -  person Rafał Sobota    schedule 08.11.2013


Ответы (1)


Это сообщение об ошибке означает, что обращение к базе данных заняло больше времени, чем заданный вами период ожидания. Простое увеличение этого тайм-аута должно решить проблему, при условии, что у вас нет реальных проблем, из-за которых приложение работает вяло.

Как правило, эта ошибка не означает, что у вас есть какие-либо проблемы с масштабированием, за исключением того факта, что, возможно, у вас увеличивается объем данных в некоторых коллекциях, а некоторые запросы могут выполняться слишком медленно и требуют переосмысления (индексы и т. д.). .

Также нет необходимости перезапускать приложение. Вы можете либо Обновить проблемный сеанс, либо Закрыть и заново создать сеанс, если вы используете копии основного сеанса. Состояние mgo и пула соединений по-прежнему в порядке. Это просто предупреждение о том, что в этом конкретном сеансе обнаружена проблема в сети, и поэтому вы должны подтвердить это, прежде чем сеанс снова станет действительным.

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

person Gustavo Niemeyer    schedule 08.11.2013
comment
Я создаю сеанс один раз при запуске приложения и использую его в каждом обработчике http, как в моей сути - gist.github.com/rafalsobota/7369852#file-database-go-L13 . Может ли это вызвать эту проблему? Если да, могу ли я просто обновить сеанс после разрешения http-запроса или мне следует клонировать сеанс для каждого http-запроса и передавать его логике моей модели (это требует серьезного рефакторинга моего кода)? - person Rafał Sobota; 08.11.2013
comment
Когда эта ошибка возникает в моем приложении, она повторяется несколько раз, и после перезапуска сервера все возвращается к нормальному поведению. - person Rafał Sobota; 08.11.2013
comment
Вы описываете именно то поведение, которое я указал в третьем абзаце. Ошибка не исчезнет, ​​пока вы ее не признаете. Один простой и хороший способ организовать это — скопировать основной сеанс для каждого обработчика и отложить его закрытие, чтобы убедиться, что у вас нет утечек. Таким образом, каждый новый сеанс будет выбирать хороший сокет из пула или устанавливать новое соединение, если это необходимо. - person Gustavo Niemeyer; 08.11.2013
comment
Спасибо Густаво. Есть ли какой-нибудь пост в блоге о том, как этот пул подключений работает под прикрытием? Я не думаю, что все понимаю, и все еще есть некоторые вопросы. 1. Означает ли эта ошибка, что соединение потеряно, а mgo еще не знает об этом и использует его повторно? 2. Когда я закрываю соединение, оно не возвращается в пул, если оно сломано? 3. Рекомендуется ли обновлять сеанс, как только возникает ошибка, и повторять попытку вместо возврата кода состояния 5xx http? - person Rafał Sobota; 08.11.2013
comment
4. Могу ли я использовать только один сеанс во всем моем приложении в нескольких горутинах и обновлять этот глобальный сеанс только при обнаружении этой ошибки? Почему бы и нет? Мои существующие запросы будут убиты? - person Rafał Sobota; 08.11.2013
comment
В списке рассылки есть хорошие недавние темы по этой теме. Пожалуйста, перейдите туда для более открытого разговора. - person Gustavo Niemeyer; 09.11.2013