我使用Django编写了一个带有pyftpdlib的基本FTP服务器,用于用户管理。我错误地认为Django会处理数据库连接,并在超时后自动重新连接。
编辑:只是为了澄清:这不是Django Web服务,而是在服务器上运行的守护程序,仅使用Django进行简单的数据库接口。我这样做是因为将数据放入数据库的网站使用django。所以我认为在deamon方面也可以这么做,而不是自己编写查询。
现在我每隔几个小时就得到这个:
OperationalError(2006, 'MySQL server has gone away')
当没有人在晚上使用服务器时,这通常会出现 - 所以似乎有一个数据库超时 - 然后有人在早上登录,导致FTP服务使用Django模型查询数据库的密码和用户名
现在我怎样才能确保连接没有消失?是否有任何try / except组合可以轻松检查连接是否仍然存在且是否只是重新连接?
我是这样做的。简而言之,我将django.contrib.auth.User存储在我的FTP类的self.auth中,然后每当我需要检查时,我只需要求self.auth.models.Users进行验证。我再次假设,如果有超时,Django会照顾它。
我有什么办法让django检查并重新连接吗?或者我如何更改代码以防止这种情况发生?
class DjangoMysqlConnector:
def __init__(self,SystemLogger=False, BASIC_CONFIG=False):
self.queue = Queue.Queue()
self.lock = threading.Lock()
sys.path.append("/home/user/git/apps")
if not BASIC_CONFIG:
sys.path.append("/home/user/django/bildverteiler_project")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bildverteiler_project.settings")
else:
sys.path.append(BASIC_CONFIG["project_path"])
os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.path.basename(BASIC_CONFIG["project_path"])+".settings")
django.setup()
import bildverteiler
from django.contrib import auth
self.auth = auth
class CustomDummyAuthorizer(DummyAuthorizer):
def __init__(self,user_query,*args,**kwargs):
super(CustomDummyAuthorizer,self).__init__()
self.user_query = user_query
def validate_authentication(self, username, password, arg):
try:
user_obj = self.user_query.objects.get(username=username)
except:
print "user does not exist: "+str(sys.exc_info())
raise AuthenticationFailed("failed")
else:
if not self.has_user(username):
try:
os.makedirs("/home/user/git/verteilerCore2/default_basedir/in/"+str(user_obj.pk))
except OSError:
pass
self.add_user(user_obj.username, 'xxx', "/home/user/git/verteilerCore2/default_basedir/in/"+str(user_obj.pk), perm='elradfmwM')
if user_obj.check_password(password):
print "password geht"
return None
else:
print "password wrong"
raise AuthenticationFailed("failed")
class FtpThread(threading.Thread):
def __init__(self, user_query):
self.user_query = user_query
self.killswitch = 0
threading.Thread.__init__(self)
self.setDaemon(True)
def run(self,*args,**kwargs):
authorizer = CustomDummyAuthorizer(self.user_query)
handler = FTPHandler
handler.authorizer = authorizer
logging.basicConfig(filename='/var/log/verteiler_ftp.log', level=logging.WARN)
handler.banner = "pyftpdlib based ftpd ready."
address = ('', 21)
self.server = FTPServer(address, handler)
self.server.max_cons = 256
self.server.max_cons_per_ip = 30
self.server.serve_forever()
def stop(self):
self.server.close_all()