我正在 Python 3.8 中编写一个简单的验证码生成 API。我的访问密钥存储在远程服务器(托管)上的 MySql 中,程序在我的本地主机上运行。但是,在长时间不活动后,与数据库的连接会丢失,因为服务器设置了超时。起初,我想只是增加它,但我明白这不是一个选项,因为我希望程序 24/7 全天候工作。这是我的数据库类:
class DataBase:
def __init__(self):
self.core = API_Core()
self.connection = pymysql.connect(
host=config.host,
user=config.name,
password=config.passwd,
db=config.name,
charset="utf8",
cursorclass=DictCursor
)
self.cursor = self.connection.cursor()
timeout = 2147482
self.cursor.execute(query=f"""SET SESSION wait_timeout := {timeout};""")
self.connection.commit()
log.debug("db inited")
def add_key(self, access=10, expires=Access_levels.key_live_time)->str:
key = self.core.generate_key()
q = f"""INSERT INTO api_keys (access, api_key, expires) VALUES ({access}, '{key}', {int(time.time()) + expires})"""
cur = self.connection.cursor()
cur.execute(q)
self.connection.commit()
return key
def __check_key_access(self, key: str) -> int:
"""Get access level for key"""
q = f"""SELECT access FROM api_keys WHERE api_key='{key}'"""
cur = self.connection.cursor()
cur.execute(q)
return cur.fetchone()
def do_some_action(self, key: str, action: str):
pass # TODO
acc = self.__check_key_access(key=key)["access"]
if acc >= eval(f"Access_levels.{action}"):
if action == "get_captcha":
return True
# TODO Time limit
if action == "get_unlim_captcha":
return True
if action == "add_new_user":
key = self.add_key()
return key
if action == "del_user":
pass # TODO
if action == "get_user_data":
pass # TODO
据此,我提出了几个问题:在不活动的情况下是否需要断开与数据库的连接?以及如何实施?如果程序在长时间不活动后尝试向数据库发送请求,如何确保程序不会因错误而崩溃?如果您可以保持连接打开并且不影响安全/性能/资源,那么如何确保服务器不会断开连接?只是不删除游标?或者怎么做?
也许你应该考虑一个数据库连接池。这样的实现与数据库维护一个连接池,并在每次工作时发出一个就绪连接,然后将其返回到池中。您设置连接数。同时,在与其他数据库(Oracle、PostgreSQL)合作时,可以设置最大连接数(可以同时打开多少个)和一开始打开的个数。
或者在MySql中设置一个long wait
建议在使用数据库时始终检查连接的活动。
或者,您可以创建方法。第一个将负责连接数据库,并将 pymysql.connect 对象存储在 self.connection 中:
第二,用于检查连接。请求前,检查连接,如果没有连接,调用mysql_conn方法:
如果有持续的请求,那么保持连接打开可能是值得的。