Иногда "ConnectionError: Невозможно подключиться к базе данных" для Монго - PullRequest
0 голосов
/ 13 марта 2011

В настоящее время мы тестируем проект на основе django, который использует MongoEngine в качестве слоя персистентности. MongoEngine основан на pymongo, и мы используем версию 1.6, и мы запускаем установку монго для одного экземпляра.

Что мы заметили, так это то, что иногда и в течение примерно 5 минут невозможно установить соединения с экземпляром mongo. Кто-нибудь сталкивался с таким поведением? какие-либо советы о том, как повысить надежность?

Ответы [ 2 ]

2 голосов
/ 14 марта 2011

У нас возникла проблема с AutoReconnect, которая звучит похоже на то, что вы описываете. Я закончил сбором обезьяньего пимонго в моем <project>/__init__.py файле:

from pymongo.cursor import Cursor                                                             
from pymongo.errors import AutoReconnect                                                      

from time import sleep                                                                        
import sys                                                                                    

AUTO_RECONNECT_ATTEMPTS = 10                                                                  
AUTO_RECONNECT_DELAY = 0.1                                                                    

def auto_reconnect(func):                                                                     
    """                                                                                       
    Function wrapper to automatically reconnect if AutoReconnect is raised.                   

    If still failing after AUTO_RECONNECT_ATTEMPTS, raise the exception after                 
    all. Technically this should be handled everytime a mongo query is                        
    executed so you can gracefully handle the failure appropriately, but this                 
    intermediary should handle 99% of cases and avoid having to put                           
    reconnection code all over the place.                                                     

    """                                                                                       
    def retry_function(*args, **kwargs):                                                      
        attempts = 0                                                                          
        while True:                                                                           
            try:                                                                              
                return func(*args, **kwargs)                                                  
            except AutoReconnect, e:                                                          
                attempts += 1                                                                 
                if attempts > AUTO_RECONNECT_ATTEMPTS:                                        
                    raise                                                                     
                sys.stderr.write(                                                             
                    '%s raised [%s] -- AutoReconnecting (#%d)...\n' % (                       
                        func.__name__, e, attempts))                                          
                sleep(AUTO_RECONNECT_DELAY)                                                   
    return retry_function                                                                     

# monkeypatch: wrap Cursor.__send_message (name-mangled)                                      
Cursor._Cursor__send_message = auto_reconnect(Cursor._Cursor__send_message)                   
# (may need to wrap some other methods also, we'll see...) 

Это решило проблему для нас, но вы могли бы описать что-то другое?

1 голос
/ 23 мая 2012

Вот еще одно решение, которое использует подклассы вместо исправлений обезьян и обрабатывает ошибки, которые могут возникнуть при установлении начального соединения или при доступе к базе данных. Я просто создал подклассы Connection / ReplicasetConnection и обработал возникшие ошибки AutoReconnect во время создания экземпляра и любых вызовов методов. Вы можете указать количество попыток и время ожидания между попытками в конструкторе.

Вы можете увидеть суть здесь: https://gist.github.com/2777345

...