开发者

Occasional "ConnectionError: Cannot connect to the database" to mongo

We are currently testing a django based project that uses MongoEngine as the persistence layer. MongoEngine is based on pymongo and we're using version 1.6 and we are running a single instance setup of mongo.

What we have noticed is that occasionally, and for about 5 minutes, connections cannot be established to the mongo instance. Has anyone come across such 开发者_如何学Gobehavior? any tips on how to improve reliability?


We had an issue with AutoReconnect which sounds similar to what you are describing. I ended up monkeypatching pymongo in my <project>/__init__.py file:

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...) 

This resolved the issue for us, but you might be describing something different?


Here is another solution that uses subclassing instead of monkey patching, and handles errors that might be raised while establishing the initial connection or while accessing a database. I just subclassed Connection/ReplicasetConnection, and handled raised AutoReconnect errors during instantiation and any method invocations. You can specify the number of retries and sleep time between retries in the constructor.

You can see the gist here: https://gist.github.com/2777345

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜