我正在查看Flask教程,它建议为每个Web请求创建一个新的数据库连接。这是正确的做事方式吗?我一直认为数据库连接应该只为每个线程创建一次。可以这样做,同时将应用程序保持为线程安全,使用烧瓶或其他python Web服务器。
答案 0 :(得分:12)
出于学习目的,可能是的。但是在生产环境中运行的实际应用程序根本不是理想的情况。
通常,您总是希望在应用程序和数据库之间建立连接池。无论您使用何种语言/数据库,这都是一种常见的解决方案。
数据库连接池维护打开许多连接。应用程序层只接受未使用的连接,当应用程序层不再需要它时,连接将被释放。 “释放”是指他们返回游泳池再次使用。
底线,每次请求都没有打开/关闭连接。它们从/向数据库连接池获取/释放。
例如,使用Python和mysql,你可以选择PySQLPool。
答案 1 :(得分:9)
创建一个新的连接,每个请求的方式去?对于大型应用程序,我们强烈建议使用SQLAlchemy(可以配置连接池),即使您对ORM不感兴趣。文档实际上有一节:http://flask.pocoo.org/docs/patterns/sqlalchemy/#sql-abstraction-layer
答案 2 :(得分:3)
这是一个很好的性能与不同解决方案的比较。 (PostgreSQL的)
简短版本: 看看pgBouncer
答案 3 :(得分:0)
根据我的经验,经常关闭连接通常是一个好主意。特别是,MySQL喜欢关闭已经闲置一段时间的连接,有时可能会使持久连接处于陈旧状态,导致应用程序无响应。
您真正想要做的是优化“死连接时间”,即连接时间的一小部分,但没有做任何工作。在为每个请求创建新连接的情况下,该死时间实际上只是设置和拆除时间。如果只进行一次连接(每个线程),并且它永远不会坏,那么死区时间就是空闲时间。
当您的应用程序仅提供少量请求时,发生的连接数也会很少,因此保持连接打开但空闲的好处不大。另一方面,当应用程序非常繁忙时,连接几乎永远不会空闲,并且关闭将立即重新打开的连接也会被浪费。在中间,当新请求有时跟随飞行请求,但有时不会,您将不得不对池大小,请求超时等事情进行一些性能调整。
一个非常繁忙的应用程序,使用连接池来保持连接打开只会看到一种死机时间;等待因为连接变坏而永远不会返回的请求。解决此问题的一个简单方法是在提供从池到请求的连接之前执行已知的良好查询(在MySQL中拼写为SELECT 1
),如果连接没有快速返回,则回收连接。