PHP 中的连接池

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:16:52  来源:igfitidea点击:

Connection pooling in PHP

phpconnection-pooling

提问by The Chairman

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

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

回答by darpet

There is no connection poolingin php.
mysql_pconnectand connection poolingare two different things. There are many problems connected with mysql_pconnectand first you should read the manual and carefully use it, but this is not connection pooling.

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

Connection pooling is a technique where the application server manages the connections. When the application needs a connection it asks the application server for it and the application server returns one of the pooled connections if there is one free.

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

We can do connection scaling in php for that please go through following link: http://www.oracle.com/technetwork/articles/dsl/white-php-part1-355135.html

我们可以在 php 中进行连接扩展,请通过以下链接:http: //www.oracle.com/technetwork/articles/dsl/white-php-part1-355135.html

So no connection pooling in php.

所以在 php 中没有连接池。

As Julio said apache releases all resources when the request ends for the current reques. You can use mysql_pconnect but you are limited with that function and you must be very careful. Other choice is to use singleton pattern, but none of this is pooling.

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

This is a good article: https://blogs.oracle.com/opal/highly-scalable-connection-pooling-in-php

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

Also read this one http://www.apache2.es/2.2.2/mod/mod_dbd.html

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

回答by minorgod

Persistent connections are nothing like connection pooling. A persistent connection in php will only be reused if you make multiple db connects within the same request/script execution context. In most typical web dev scenarios you'll max out your connections way faster if you use mysql_pconnect because your script will have no way to get a reference to any open connections on your next request. The best way to use db connections in php is to make a singleton instance of a db object so that the connection is reused within the context of your script execution. This still incurs at least 1 db connect per request, but it's better than making multiple db connects per reqeust.

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

There is no real db connection pooling in php due to the nature of php. Php is not an application server that can sit there in between requests and manage references to a pool of open connections, at least not without some kind of major hack. I think in theory you could write an app server in php and run it as a commandline script that would just sit there in the background and keep a bunch of db connections open and pass references to them to your other scripts, but I don't know if that would be possible in practice, how you'd pass the references from your commandline script to other scripts, and I sort of doubt it would perform well even if you could pull it off. Anyway that's mostly speculation. I did just notice the link someone else posted to an apache module to allow connection pooling for prefork servers such as php. Looks interesting: https://github.com/junamai2000/mod_namy_pool#readme

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

回答by Julio César

I suppose you're using mod_php, right?

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

When a PHP file finishes executing all it's state is killed so there's no way (in PHP code) to do connection pooling. Instead you have to rely on extensions.

当一个 PHP 文件完成执行所有它的状态时,它的状态被杀死,所以没有办法(在 PHP 代码中)进行连接池。相反,您必须依赖扩展。

You can mysql_pconnectso that your connections won't get closed after the page finishes, that way they get reused in the next request.

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

This might be all that you need but this isn't the same as connection pooling as there's no way to specify the number of connections to maintain opened.

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

回答by user193130

You can use MySQLi.

您可以使用MySQLi

For more info, scroll down to Connection poolingsection @ http://www.php.net/manual/en/mysqli.quickstart.connections.php#example-1622

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

Note that Connection pooling is also dependent on your server (i.e. Apache httpd) and its configuration.

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

回答by Engr Syed Rowshan Ali

Connection pooling works at MySQL server side like this.

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

  1. If persistence connection is enabled into MySQL server config then MySQL keep a connection open and in sleep state after requested client (php script) finises its work and die.
  2. When a 2nd request comes with same credential data (Same User Name, Same Password, Same Connection Parameter, Same Database name, Maybe from same IP, I am not sure about the IP) Then MySQL pool the previous connection from sleep state to active state and let the client use the connection. This helps MySQL to save time for initial resource for connection and reduce the total number of connection.
  1. 如果在 MySQL 服务器配置中启用了持久连接,那么在请求的客户端(php 脚本)完成其工作并死亡后,MySQL 将保持连接打开并处于睡眠状态。
  2. 当第二个请求带有相同的凭据数据(相同的用户名、相同的密码、相同的连接参数、相同的数据库名称、可能来自相同的 IP,我不确定 IP)然后 MySQL 将先前的连接从睡眠状态池化为活动状态并让客户端使用连接。这有助于 MySQL 节省初始连接资源的时间并减少连接总数。

So the connection pooling option is actually available at MySQL server side. At PHP code end there is no option. mysql_pconnect() is just a wrapper that inform PHP to not send connection close request signal at the end of script run.

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

回答by Xavier

If an unused persistent connection for a given combination of "host, username, password, socket, port and default database can not be found" in the open connection pool, then only mysqli opens a new connection otherwise it would reuse already open available persistent connections, which is in a way similar to the concept of connection pooling. The use of persistent connections can be enabled and disabled using the PHP directive mysqli.allow_persistent. The total number of connections opened by a script can be limited with mysqli.max_links (this may be interesting to you to address max_user_connections issue hitting hosting server's limit). The maximum number of persistent connections per PHP process can be restricted with mysqli.max_persistent.

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

In wider programming context, it's a task of web/app server however in this context, it's being handled by mysqli directive of PHP itself in a way supporting connection re-usability. You may also implement a singleton class to get a static instance of connection to reuse just like in Java. Just want to remind that java also doesn't support connection pooling as part of its standard JDBC, they're being different module/layers on top of JDBC drivers.

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

Coming to PHP, the good thing is that for the common databases in the PHP echosystem it does support Persistent Database Connections which persists the connection for 500 requests (config of max_requests in php.ini) and this avoids creating a new connection in each request. So check it out in docs in detail, it solves most of your challenges. Please note that PHP is not so much sophisticated in terms of extensive multi-threading mechanism and concurrent processing together with powerful asynchronous event handling, when compared to strictly object oriented Java. So in a way it is very less effective for PHP to have such in-built mechanism like pooling.

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

回答by Marcel

You cannot instantiate connection pools manually.

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

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

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

回答by Amir Fo

I would like to suggest PDO::ATTR_PERSISTENT

我想建议 PDO::ATTR_PERSISTENT

Persistent connections are links that do not close when the execution of your script ends. When a persistent connection is requested, PHP checks if there's already an identical persistent connection (that remained open from earlier) - and if it exists, it uses it. If it does not exist, it creates the link.

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