PHP中的连接池

Posted

技术标签:

【中文标题】PHP中的连接池【英文标题】:Connection pooling in PHP 【发布时间】:2010-09-07 13:45:48 【问题描述】:

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

【问题讨论】:

你看过使用mysql_pconnect()的持久连接吗? 这个怎么样? github.com/junamai2000/mod_namy_pool 其实PHP中有一些关于连接池的东西,查看手册:php.net/manual/en/mysqlnd-ms.pooling.php和php.net/manual/en/mysqlnd-mux.connection_pool.php 【参考方案1】:

我猜你正在使用 mod_php,对吧?

当一个 PHP 文件完成执行时,它的所有状态都会被终止,因此(在 PHP 代码中)无法进行连接池。相反,您必须依赖扩展。

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

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

【讨论】:

连接可以被不同的用户重用吗?如果可以,为什么手册说要配置MySQL避免连接过多?【参考方案2】:

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

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

来到 PHP,好处是对于 PHP 回显系统中的通用数据库,它确实支持持久数据库连接,可以持久连接 500 个请求(php.ini 中的 max_requests 配置),这避免了在每个请求。因此,请详细查看文档,它可以解决您的大部分挑战。请注意,与严格面向对象的 Java 相比,PHP 在广泛的多线程机制和并发处理以及强大的异步事件处理方面并没有那么复杂。所以在某种程度上,PHP 拥有像池这样的内置机制是非常无效的。

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

我想建议PDO::ATTR_PERSISTENT

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

【讨论】:

【参考方案5】:

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

【讨论】:

没有连接池?哇。 "脚本执行结束时不会关闭与 SQL 服务器的连接。" - php.net/manual/en/function.mysql-pconnect.php oracle 博客的工作链接:blogs.oracle.com/opal/entry/highly_scalable_connection_poo【参考方案6】:

您可以使用MySQLi。

欲了解更多信息,请向下滚动到连接池部分@http://www.php.net/manual/en/mysqli.quickstart.connections.php#example-1622

请注意,连接池还取决于您的服务器(即 Apache httpd)及其配置。

【讨论】:

这个答案应该被修改,因为所有其他的都已经很老了。连接池及其可能导致的问题非常真实!【参考方案7】:

持久连接与连接池完全不同。只有在同一请求/脚本执行上下文中进行多个数据库连接时,才会重用 php 中的持久连接。在大多数典型的 Web 开发场景中,如果您使用 mysql_pconnect,您将更快地最大化您的连接,因为您的脚本将无法在您的下一个请求中获取对任何打开连接的引用。在 php 中使用 db 连接的最佳方法是创建 db 对象的单例实例,以便在脚本执行的上下文中重用连接。这仍然会导致每个请求至少 1 个 db 连接,但它比每个请求创建多个 db 连接要好。

由于 php 的性质,php 中没有真正的数据库连接池。 Php 不是一个可以在请求之间坐在那里并管理对开放连接池的引用的应用程序服务器,至少在没有某种重大黑客攻击的情况下并非如此。我认为理论上你可以在 php 中编写一个应用程序服务器并将其作为命令行脚本运行,该脚本将只是坐在后台并保持一堆数据库连接打开并将对它们的引用传递给你的其他脚本,但我不知道这在实践中是否可行,如何将命令行脚本中的引用传递给其他脚本,我有点怀疑即使你可以完成它,它也会表现良好。无论如何,这主要是猜测。我刚刚注意到其他人发布到 apache 模块的链接,以允许对 prefork 服务器(例如 php)进行连接池。看起来很有趣: https://github.com/junamai2000/mod_namy_pool#readme

【讨论】:

"脚本执行结束时不会关闭与 SQL 服务器的连接。" - php.net/manual/en/function.mysql-pconnect.php “在 php 中使用 db 连接的最佳方式是创建一个 db 对象的单例实例,以便在脚本执行的上下文中重用连接。” - 这就是我要找的金鹅。准确解释单例在何处以及为何有用的好方法!【参考方案8】:

您不能手动实例化连接池。

但您可以通过mysql_pconnect 函数使用“内置”连接池。

【讨论】:

以上是关于PHP中的连接池的主要内容,如果未能解决你的问题,请参考以下文章

干货php Redis连接池

PHP进阶教程-实现一个简单的MySQL连接池

一般连接池是怎么处理mysql自动回收长时间

mysql连接池模块

PHP中的数据库连接持久化

数据库连接池php-cp介绍