PHP中的连接池


76

使用PHP时是否可以像在J2EE容器中那样缓存数据库连接?如果是这样,怎么办?


1
您是否看过使用mysql_pconnect()的持久连接?
克里斯·巴托


实际上,有关PHP中的连接池的内容,请查看手册:php.net/manual/en/mysqlnd-ms.pooling.phpphp.net/manual/en/mysqlnd-mux.connection_pool.php
Felix Huang

Answers:


57

php中没有连接池
mysql_pconnect连接池是两个不同的东西。与之相关的问题很多mysql_pconnect,首先您应该阅读并仔细使用本手册,但这不是连接池。

连接池是一种应用程序服务器管理连接的技术。当应用程序需要连接时,它会向应用程序服务器请求连接,如果有空闲连接,则应用程序服务器将返回其中一个池连接。

为此,我们可以使用php进行连接扩展:http : //www.oracle.com/technetwork/articles/dsl/white-php-part1-355135.html

因此,php中没有连接池。

正如Julio所说,当当前请求的请求结束时,apache释放所有资源。您可以使用mysql_pconnect,但是该功能受到限制,必须非常小心。另一个选择是使用单例模式,但这都不是池化。

这是一篇很好的文章:https : //blogs.oracle.com/opal/highly-scalable-connection-pooling-in-php

另请阅读此http://www.apache2.es/2.2.2/mod/mod_dbd.html


16
没有连接池?哇。
贾斯汀

2
“当脚本执行结束时,不会关闭与SQL Server的连接。” - php.net/manual/en/function.mysql-pconnect.php
RandomSeed


15

持久连接与连接池不同。仅当您在同一请求/脚本执行上下文中进行多个数据库连接时,才会重新使用php中的持久连接。在大多数典型的Web开发方案中,如果使用mysql_pconnect,您将以最快的速度最大化连接,因为您的脚本将无法在下一个请求中获得对任何打开的连接的引用。在php中使用数据库连接的最好方法是创建一个db对象的单例实例,以便在脚本执行的上下文中重新使用该连接。每个请求仍然至少需要1个数据库连接,但这比每个请求建立多个数据库连接要好。

由于php的性质,在php中没有真正的数据库连接池。Php不是一个可以放置在请求之间并管理对开放连接池的引用的应用服务器,至少不是没有某种主要的技巧。我认为从理论上讲,您可以使用php编写应用服务器,并将其作为命令行脚本运行,该脚本仅位于后台,并保持一堆数据库连接打开并将对它们的引用传递给您的其他脚本,我知道在实践中是否有可能,如何将引用从命令行脚本传递到其他脚本,我怀疑即使您可以将其执行起来也能很好地执行。无论如何,这主要是猜测。我确实注意到其他人发布到apache模块的链接,以允许php之类的prefork服务器建立连接池。 https://github.com/junamai2000/mod_namy_pool#readme


3
“当脚本执行结束时,不会关闭与SQL Server的连接。” - php.net/manual/en/function.mysql-pconnect.php
RandomSeed

“在php中使用数据库连接的最好方法是创建一个db对象的单例实例,以便在脚本执行的上下文中重新使用该连接。” -这是我要找的金鹅。准确解释单例在何处以及为何有用的好方法!
samazi 2014年

9

我想您正在使用mod_php,对吗?

当PHP文件完成执行后,所有状态都会被杀死,因此(在PHP代码中)无法进行连接池。相反,您必须依靠扩展。

您可以使用mysql_pconnect,以使您的连接在页面完成后不会关闭,这样它们就可以在下一个请求中重用。

这可能就是您所需要的,但这与连接池不同,因为无法指定要保持打开状态的连接数。


3
连接可以由不同的用户重用吗?如果是,为什么手册说我们应该配置MySQL以避免太多的连接?
OMG


1

连接池在MySQL服务器端这样工作。

  1. 如果在MySQL服务器配置中启用了持久连接,则在请求的客户端(php脚本)完成其工作并终止后,MySQL会保持连接处于打开状态并处于睡眠状态。
  2. 当第二个请求带有相同的凭据数据(相同的用户名,相同的密码,相同的连接参数,相同的数据库名称,可能来自相同的IP,但我不确定该IP)时,MySQL将先前的连接从睡眠状态转换为活动状态并让客户端使用连接。这有助于MySQL节省用于连接的初始资源的时间,并减少连接的总数。

因此,连接池选项实际上在MySQL服务器端可用。在PHP代码末尾没有选择。mysql_pconnect()只是一个包装,通知PHP在脚本运行结束时不发送连接关闭请求信号。



0

我想建议 PDO::ATTR_PERSISTENT

持久连接是在脚本执行结束时不会关闭的链接。当请求一个持久连接时,PHP检查是否已经有一个相同的持久连接(从较早版本开始一直保持打开状态)-如果存在,则使用它。如果不存在,它将创建链接。


0

如果在打开的连接池中未找到用于“主机,用户名,密码,套接字,端口和默认数据库”的给定组合的未使用持久连接,则只有mysqli会打开一个新连接,否则将重用已打开的可用持久连接,其方式类似于连接池的概念。可以使用PHP指令mysqli.allow_persistent启用和禁用持久性连接。可以通过mysqli.max_links限制脚本打开的连接总数(您可能会对解决max_user_connections达到托管服务器限制的问题很感兴趣)。可以使用mysqli.max_persistent限制每个PHP进程的最大持久连接数。

在更广泛的编程环境中,这是Web /应用服务器的任务,但是在这种情况下,它由PHP本身的mysqli指令以支持连接可重用性的方式进行处理。您还可以实现单例类,以获取静态的连接实例以重用,就像在Java中一样。只是想提醒一下,Java作为其标准JDBC的一部分也不支持连接池,它们是JDBC驱动程序之上的不同模块/层。

进入PHP的好处是,对于PHP echo系统中的通用数据库,它确实支持Persistent Database Connections(持久数据库连接),该连接可持久保存500个请求的连接(php.ini中max_requests的配置),并且避免了在每个请求中创建新连接。因此,请在文档中进行详细检查,以解决您的大部分难题。请注意,与严格的面向对象的Java相比,PHP在广泛的多线程机制,并发处理以及强大的异步事件处理方面没有那么先进。因此,以某种方式使PHP具有诸如池之类的内置机制的效率非常低。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.