85

Is it possible to cache database connections when using PHP like you would in a J2EE container? If so, how?

4

8 回答 8

61

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

于 2010-09-29T07:47:22.433 回答
18

持久连接与连接池完全不同。只有在同一请求/脚本执行上下文中进行多个数据库连接时,才会重用 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

于 2012-04-26T18:51:35.170 回答
12

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

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

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

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

于 2008-09-02T15:49:14.120 回答
9

您可以使用MySQLi

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

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

于 2014-01-07T16:38:47.390 回答
1

如果在打开的连接池中找不到“主机、用户名、密码、套接字、端口和默认数据库”的给定组合的未使用持久连接,则只有 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 echosystem 中的通用数据库,它确实支持持久数据库连接,它可以为 500 个请求(php.ini 中的 max_requests 配置)持久连接,这避免了在每个请求中创建新连接。因此,请详细查看文档,它可以解决您的大部分挑战。请注意,与严格面向对象的 Java 相比,PHP 在广泛的多线程机制和并发处理以及强大的异步事件处理方面并没有那么复杂。所以在某种程度上,PHP 拥有像池这样的内置机制是非常无效的。

于 2020-02-22T00:03:07.537 回答
0

You cannot instantiate connection pools manually.

But you can use the "built in" connection pooling with the mysql_pconnect function.

于 2008-09-02T15:42:47.223 回答
0

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

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

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

于 2019-06-24T03:45:43.500 回答
0

我想建议PDO::ATTR_PERSISTENT

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

于 2019-03-22T13:41:23.453 回答