如何在Python web服务器中保持数据库连接
我在看Flask的教程,里面建议每次网页请求都要创建一个新的数据库连接。这这样做对吗?我一直以为数据库连接应该每个线程只创建一次。这样做可以吗?同时又能保证应用是线程安全的,像Flask或者其他Python的网页服务器?
3 个回答
根据我的经验,频繁关闭连接通常是个好主意。特别是MySQL,它喜欢关闭那些闲置了一段时间的连接,有时候这会导致持久连接处于一种不正常的状态,从而让应用程序变得无响应。
你真正想要做的是优化“死连接时间”,也就是连接处于开启状态但没有在做任何工作的时间。如果每次请求都创建一个新连接,那么这段死时间其实就是连接的建立和关闭时间。如果每个线程只建立一次连接,并且这个连接一直有效,那么死时间就是连接闲置的时间。
当你的应用程序只处理少量请求时,连接的数量也会很少,这样保持一个闲置的连接就没什么好处。相反,当应用程序非常繁忙时,连接几乎不会闲置,关闭一个马上又要重新打开的连接也是浪费。在中间的情况,当新的请求有时跟在正在处理的请求后面,有时又没有时,你就需要对连接池的大小、请求超时等进行一些性能调优。
一个非常繁忙的应用程序,如果使用连接池来保持连接开启,只会遇到一种死时间:等待那些因为连接出问题而永远不会返回的请求。解决这个问题的一个简单方法是在将连接提供给请求之前,执行一个已知的、有效的查询(在MySQL中就是 SELECT 1
),如果没有快速返回,就回收这个连接。
每次请求都创建一个新连接,这样做合适吗?不合适。对于大型应用,我们强烈建议使用SQLAlchemy(它可以配置连接池),即使你对ORM(对象关系映射)不感兴趣。实际上,文档中有一部分专门讲这个内容:http://flask.pocoo.org/docs/patterns/sqlalchemy/#sql-abstraction-layer
为了学习的目的,可能这样做可以理解。但在真正的应用程序中,尤其是在生产环境里,这样的做法就不太理想了。
通常情况下,你总是希望在你的应用程序和数据库之间有一个连接池。无论你使用什么编程语言或数据库,这都是一个常见的解决方案。
数据库连接池会保持一定数量的连接处于打开状态。应用程序只需使用一个当前没有被占用的连接,当应用程序不再需要这个连接时,它就会被释放。这里的“释放”是指将连接返回到连接池,以便下次可以再次使用。
简单来说,连接不是每次请求都打开和关闭的,而是从数据库连接池中获取和释放。
举个例子,如果你使用Python和mysql,可以考虑使用PySQLPool这个库。