AKTUALIZUJ :nasz artykuł pomocy dotyczący tego tematu (zasadniczo kopia tego posta) został przeniesiony do naszego dokumentu dotyczącego rozwiązywania problemów z połączeniem.
Istnieje znany problem polegający na tym, że sieć IaaS platformy Azure wymusza przekroczenie limitu czasu bezczynności wynoszące około trzynaście minut (osiągnięto empirycznie). Współpracujemy z platformą Azure, aby sprawdzić, czy nie możemy uczynić rzeczy bardziej przyjaznymi dla użytkownika, ale w międzyczasie inni odnieśli sukces, konfigurując opcje sterowników, aby obejść ten problem.
Maksymalny czas bezczynności połączenia
Najskuteczniejszym obejściem, jakie znaleźliśmy podczas pracy z platformą Azure i naszymi klientami, było ustawienie maksymalnego czasu bezczynności połączenia poniżej czterech minut. Chodzi o to, aby sterownik ponownie wykorzystywał nieaktywne połączenia, zanim zapora wymusi problem. Na przykład jeden klient, który używa sterownika C#, ustaw MongoDefaults.MaxConnectionIdleTime
do jednej minuty i rozwiązało to ich problemy.
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
Sam kod aplikacji nie uległ zmianie, ale teraz za kulisami sterownik agresywnie odtwarza bezczynne połączenia. Wynik można również zobaczyć w dziennikach serwera:duża liczba połączeń w okresach bezczynności w aplikacji.
Więcej szczegółów na temat tego podejścia można znaleźć w powiązanym wątku mongo-user, SocketException przy użyciu sterownika C# na platformie Azure.
Keepalive
Możesz również obejść ten problem, zmniejszając bezczynność połączeń za pomocą pewnego rodzaju podtrzymania aktywności. Jest to trochę trudne do zaimplementowania, chyba że twój sterownik obsługuje to po wyjęciu z pudełka, zwykle korzystając z TCP Keepalive. Jeśli chcesz wylosować własne, pamiętaj, aby co kilka minut pobierać z puli każde bezczynne połączenie i wydawać proste i tanie polecenie, prawdopodobnie ping.
Obsługa rozłączeń
Rozłączenia mogą się zdarzać od czasu do czasu, nawet bez agresywnej konfiguracji zapory. Zanim przejdziesz do produkcji, chcesz mieć pewność, że obsłużysz je poprawnie.
Najpierw upewnij się, że włączyłeś automatyczne ponowne łączenie. Sposób wykonania różni się w zależności od sterownika, ale gdy sterownik wykryje, że operacja nie powiodła się, ponieważ połączenie było złe, włączenie automatycznego ponownego połączenia informuje sterownik, aby próbował ponownie połączyć się.
Ale to nie rozwiązuje całkowicie problemu. Nadal masz problem z tym, co zrobić z nieudaną operacją, która wywołała ponowne połączenie. Automatyczne ponowne łączenie nie powoduje automatycznego ponawiania nieudanych operacji. Byłoby to niebezpieczne, zwłaszcza dla pisarzy. Dlatego zwykle zgłaszany jest wyjątek, a aplikacja jest proszona o jego obsługę. Często ponawianie odczytów jest oczywiste. Jednak ponowne próby zapisu powinny być dokładnie przemyślane.
Poniższa sesja powłoki mongo pokazuje problem. Powłoka mongo domyślnie ma włączone automatyczne ponowne łączenie. Wstawiam dokument do kolekcji o nazwie stuff
następnie znajdź wszystkie dokumenty w tej kolekcji. Następnie ustawiłem minutnik na trzydzieści minut i ponownie spróbowałem tego samego znaleziska. Nie udało się, ale powłoka automatycznie połączyła się ponownie i kiedy natychmiast ponowiłem próbę znalezienia, zadziałało zgodnie z oczekiwaniami.
% 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") }
Chcemy pomóc
Oczywiście, jeśli masz jakiekolwiek pytania, skontaktuj się z nami pod adresem [email protected] Jesteśmy tutaj, aby pomóc.