【问题标题】:Occasional "ConnectionError: Cannot connect to the database" to mongo偶尔出现“ConnectionError:无法连接到数据库”到 mongo
【发布时间】:2011-07-14 08:14:35
【问题描述】:

我们目前正在测试一个使用 MongoEngine 作为持久层的基于 django 的项目。 MongoEngine 基于 pymongo,我们使用的是 1.6 版,我们正在运行 mongo 的单实例设置。

我们注意到,偶尔,大约 5 分钟,无法建立与 mongo 实例的连接。有没有人遇到过这样的行为?关于如何提高可靠性的任何提示?

【问题讨论】:

    标签: django mongodb pymongo


    【解决方案1】:

    我们遇到了AutoReconnect 的问题,这听起来与您所描述的相似。我最终在我的<project>/__init__.py 文件中对 pymongo 进行了猴子补丁:

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

    这为我们解决了问题,但您可能描述的是不同的东西?

    【讨论】:

    • 似乎它可以解决我们的问题.. 如果我们发现差异,我会通知您
    • 最近的发展有帮助吗?
    【解决方案2】:

    这是另一种解决方案,它使用子类化而不是猴子修补,并处理在建立初始连接或访问数据库时可能引发的错误。我只是继承了 Connection/ReplicasetConnection,并在实例化和任何方法调用期间处理了引发的 AutoReconnect 错误。您可以在构造函数中指定重试次数和重试之间的休眠时间。

    您可以在此处查看要点:https://gist.github.com/2777345

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2018-08-17
      • 2019-12-07
      • 1970-01-01
      • 2017-09-21
      相关资源
      最近更新 更多