问题产生
flask程序使用sqlalchemy或flask-sqlalchemy运行一段时间后,会报该错误
sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30 (Background on this error at: http://sqlalche.me/e/3o7r)
问题产生原因分析
产生该问题的原因有种,并发太高等都可能引起该错误,
还有一个典型的错误原因是,在客户端发送一个请求后, flask后台执行一个数据库操作,随后进行某种逻辑操作,如果该逻辑出现错误,会为客户端返回500错误码,此时该连接未释放,因此会导致数据库连接池继续占用。如下代码
@web.route("/test_error")
def test_error():
print("-----------------error times "+ str(datatemp.error_counter)+"------------")
datatemp.error_counter += 1
sites = Site.query.filter().all()
r = requests.get('http://github.com', timeout=0.001)
return "error times "+ str(datatemp.error_counter)
requsts.get会必定报错,该逻辑之前 执行了查询操作,因此不会释放连接。
向/test_error连续发送20个请求,就会出现连接池错误。
解决方案1 增加连接池
操作如链接所示:增加连接池
该解决方案仅仅适合由于用户高并发引起的该问题,对于本文所述情况,该解决方案仅仅能延缓该问题,无法解决该问题。
解决方案2 增加try_except
在可能出错的语句,增加try字段
如上述代码可以修改为
@web.route("/test_error")
def test_error():
print("-----------------error times "+ str(datatemp.error_counter)+"------------")
datatemp.error_counter += 1
sites = Site.query.filter().all()
try:
r = requests.get('http://github.com', timeout=0.001)
except:
r = None
return "error times "+ str(datatemp.error_counter)
可以解决本文所述情况引起的连接池错误,但是时间成本过长,尤其项目规模较大时
解决方案3 使用redis
这个解决思路来源于Stack Overflow,本人尚未验证,
理论上来说即为可行,可以解决高并发,本问所述问题等