АКТУАЛИЗИРАНЕ :Нашата статия за поддръжка за тази тема (по същество копие на тази публикация) се премести в нашия документ за отстраняване на неизправности при връзката.
Известен е проблем, че мрежата Azure IaaS налага изчакване на неактивност от приблизително тринадесет минути (емпирично достигнато). Работим с Azure, за да видим дали не можем да направим нещата по-удобни за потребителя, но междувременно други постигнаха успех, като конфигурираха опциите на драйверите си, за да заобиколят проблема.
Максимално време на престой на връзката
Най-ефективното решение, което открихме при работата с Azure и нашите клиенти, беше да зададем максималното време на престой на връзката под четири минути. Идеята е драйверът да рециклира неактивни връзки, преди защитната стена да предизвика проблема. Например, един клиент, който използва C# драйвера, зададе MongoDefaults.MaxConnectionIdleTime
до една минута и това изясни проблемите им.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
Самият код на приложението не се промени, но сега зад кулисите драйверът агресивно рециклира неактивни връзки. Резултатът може да се види и в регистрационните файлове на сървъра:много прекъсване на връзката по време на неактивни периоди в приложението.
Има повече подробности за този подход в свързаната нишка mongo-user, SocketException, използващ C# драйвер на azure.
Keepalive
Можете също да заобиколите проблема, като направите връзките си по-малко неактивни с някакъв вид поддържане на активност. Това е малко трудно за прилагане, освен ако вашият драйвер не го поддържа от кутията, обикновено като се възползва от TCP Keepalive. Ако трябва да пуснете своя собствена, не забравяйте да вземете всяка неактивна връзка от пула на всеки няколко минути и да издадете някаква проста и евтина команда, вероятно пинг.
Обработването на прекъсвания
Прекъсванията на връзката могат да се случват от време на време дори без агресивна настройка на защитната стена. Преди да започнете производството, трябва да сте сигурни, че ги боравите правилно.
Първо, не забравяйте да активирате автоматично повторно свързване. Как да направите това варира от драйвер до драйвер, но когато драйверът открие, че операцията е неуспешна, защото връзката е била лоша, включването на автоматично повторно свързване казва на драйвера да се опита да се свърже отново.
Но това не решава напълно проблема. Все още имате проблем какво да правите с неуспешната операция, която задейства повторното свързване. Автоматичното повторно свързване не прави повторно неуспешни операции. Това би било опасно, особено за писателите. Така че обикновено се хвърля изключение и приложението се иска да се справи с него. Често повторният опит за четене е безсмислен. Но повторното записване трябва да се обмисли внимателно.
Сесията на mongo shell по-долу демонстрира проблема. Обвивката mongo по подразбиране има активирано автоматично повторно свързване. Вмъквам документ в колекция с име stuff
след това намерете всички документи в тази колекция. След това зададох таймер за тридесет минути и опитах отново да намеря същото. Не успя, но обвивката автоматично се свърже отново и когато веднага опитах отново, открих, че работи според очакванията.
% mongo ds012345.mongolab.com:12345/mydatabase -u *** -p ***
MongoDB shell version: 2.2.2
connecting to: ds012345.mongolab.com:12345/mydatabase
> db.stuff.insert({})
> db.stuff.find()
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }
> db.stuff.find()
Fri Jan 18 13:29:28 Socket recv() errno:60 Operation timed out 192.168.1.111:12345
Fri Jan 18 13:29:28 SocketException: remote: 192.168.1.111:12345 error: 9001 socket exception [1] server [192.168.1.111:12345]
Fri Jan 18 13:29:28 DBClientCursor::init call() failed
Fri Jan 18 13:29:28 query failed : mydatabase.stuff {} to: ds012345.mongolab.com:12345
Error: error doing query: failed
Fri Jan 18 13:29:28 trying reconnect to ds012345.mongolab.com:12345
Fri Jan 18 13:29:28 reconnect ds012345.mongolab.com:12345 ok
> db.stuff.find()
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }
Тук сме, за да помогнем
Разбира се, ако имате въпроси, не се колебайте да се свържете с нас на [email protected] Ние сме тук, за да помогнем.