OPDATERING :Vores supportartikel for dette emne (i det væsentlige en kopi af dette indlæg) er flyttet til vores forbindelsesfejlfindingsdokument.
Der er et kendt problem, at Azure IaaS-netværket gennemtvinger en inaktiv timeout på omkring tretten minutter (empirisk nået frem til). Vi arbejder med Azure for at se, om vi ikke kan gøre tingene mere brugervenlige, men i mellemtiden har andre haft succes ved at konfigurere deres driverindstillinger til at omgå problemet.
Maksimal inaktiv forbindelsestid
Den mest effektive løsning, vi har fundet i arbejdet med Azure og vores kunder, har været at indstille den maksimale inaktive forbindelsestid til under fire minutter. Ideen er at få driveren til at genbruge inaktive forbindelser, før firewallen fremtvinger problemet. En kunde, der bruger C#-driveren, indstiller f.eks. MongoDefaults.MaxConnectionIdleTime
til et minut, og det løste deres problemer.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
Selve applikationskoden ændrede sig ikke, men nu bag kulisserne genbruger chaufføren aggressivt inaktive forbindelser. Resultatet kan også ses i serverloggene:masser af forbindelsestab i inaktive perioder i appen.
Der er flere detaljer om denne tilgang i den relaterede mongo-brugertråd, SocketException ved hjælp af C# driver på azure.
Keepalive
Du kan også omgå problemet ved at gøre dine forbindelser mindre inaktive med en slags keepalive. Dette er lidt vanskeligt at implementere, medmindre din driver understøtter det ud af boksen, normalt ved at drage fordel af TCP Keepalive. Hvis du har brug for at rulle din egen, skal du sørge for at få fat i hver ledig forbindelse fra poolen hvert par minutter og afgive en simpel og billig kommando, sandsynligvis et ping.
Håndtering af afbrydelser
Afbrydelser kan ske fra tid til anden, selv uden en aggressiv firewall-opsætning. Før du går i produktion, vil du være sikker på at håndtere dem korrekt.
Først skal du sørge for at aktivere automatisk genforbindelse. Hvordan man gør det varierer fra chauffør til chauffør, men når chaufføren registrerer, at en handling mislykkedes, fordi forbindelsen var dårlig, beder chaufføren om at tænde for automatisk genforbindelse, om at forsøge at oprette forbindelse igen.
Men dette løser ikke helt problemet. Du har stadig spørgsmålet om, hvad du skal gøre med den mislykkede handling, der udløste genforbindelsen. Automatisk gentilslutning forsøger ikke automatisk at udføre mislykkede handlinger igen. Det ville være farligt, især for skrivere. Så normalt bliver der kastet en undtagelse, og appen bliver bedt om at håndtere den. Ofte er det nemt at prøve at læse igen. Men at prøve at skrive igen bør overvejes nøje.
Mongo shell-sessionen nedenfor demonstrerer problemet. Mongo-skallen har som standard automatisk genforbindelse aktiveret. Jeg indsætter et dokument i en samling ved navn stuff
find derefter alle dokumenterne i den samling. Jeg indstillede derefter en timer til tredive minutter og prøvede det samme fund igen. Det mislykkedes, men skallen oprettede automatisk forbindelse igen, og da jeg straks prøvede igen, virkede det som forventet.
% 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") }
Vi er her for at hjælpe
Hvis du har spørgsmål, er du naturligvis velkommen til at kontakte os på [email protected]. Vi er her for at hjælpe.