Laravel 如何维护持久的数据库连接

MAS*_*ASh 1 mysql amazon-rds laravel-5

我正在我的本地机器(我的笔记本电脑)上的 LAMP 设置中开发一个 Laravel 应用程序。

出于测试目的,我尝试使用 mysql 服务Aws RDS代替我的本地mysql server. 发现,一个 API 调用只有一个没有连接的数据库调用(查询:显示表) - 平均需要 12 秒。这是荒唐的。当我使用本地 mysql 服务器时,它大约超过 600 毫秒。到目前为止,尚未启用 PDO::ATTR_PERSISTANT。

登录Illuminate\Database\Connectors\Connector.php[inside createConnection()method],发现,每个请求都会调用这个方法。这适用于两个 mysql 服务器。

然后,我设置PDO::ATTR_PERSISTANTtrue。但响应时间是相似的。

仔细查看后,在同一个文件中找到了这个:

/**
 * Create a new PDO connection instance.
 *
 * @param  string  $dsn
 * @param  string  $username
 * @param  string  $password
 * @param  array  $options
 * @return \PDO
 */
protected function createPdoConnection($dsn, $username, $password, $options)
{
    if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
        return new PDOConnection($dsn, $username, $password, $options);
    }

    return new PDO($dsn, $username, $password, $options);
}
Run Code Online (Sandbox Code Playgroud)

并且PDOConnection- which extends PDO,当持久为假时使用- 构造函数是:

public function __construct($dsn, $user = null, $password = null, array $options = null)
{
    try {
        parent::__construct($dsn, $user, $password, $options);
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['Doctrine\DBAL\Driver\PDOStatement', []]);
        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (\PDOException $exception) {
        throw new PDOException($exception);
    }
}
Run Code Online (Sandbox Code Playgroud)

看来,设置PDO::ATTR_PERSISTANTtrue没有效果。这让我很困惑。

  1. Laravel 中的持久数据库连接实际上是如何播放的?
  2. 响应时间长(使用 mysql 服务Aws RDS)背后的原因是什么?

gvi*_*iew 6

MySQL 是一种以具有轻量级连接开销而闻名的数据库。出于这个原因,关于连接重用的问题很少浮出水面,但无论如何,PHP 中的连接都与进程相关联。您真的只会看到负载下连接重用的好处,其中有足够的 php 进程在运行,持续的 PHP 进程可以重新使用 mysql 客户端连接。

换句话说,您的 mysql 客户端连接可以/将/可能会关闭,具体取决于您的 Web 服务器配置,即使您使用的是持久的 mysql 连接,或者如果请求的 apache 进程还没有,则需要建立新的连接可用的持久连接。

即使您有可用的持久连接,这并不意味着在您的场景中事情会更快,因为您所做的假设是通过公共互联网连接到 RDS 的时间很慢,而实际上,整个 mysql 客户端从您的本地主机应用程序通过公共互联网的连接速度很慢。查询会很慢,结果集获取也会很慢,总体来说这将是一种糟糕的体验。

如果您将整个站点托管在 AWS 上并使用 RDS 进行数据存储,那么连接耗时 12 秒并不是您所看到的。它将更接近于使用本地数据库在本地主机上获得的性能类型。

此外,这个想法的整个谓词都不好。

  1. RDS 是一种高价产品。您根本不应该将其用于开发。如果您使用的是免费层,那么除了小数据库之外的任何数据库性能都会非常缓慢。
  2. MySQL 本质上没有网络层安全性。您的 AWS 部署应该使用 VPC,其中 RDS 位于 VPC 中,您的 PHP 应用程序服务器位于 VPC 中。
  3. 您的应用程序中使用 RDS 没有什么特别之处。它在您的应用程序中看起来像任何其他带有非 localhost -h 参数的 mysql 数据库。

您正在尝试调整在现实世界中几乎没人会使用的东西,因此您正在尝试解决自己制造的对您的项目没有长期利益的问题。

话虽如此,如果您想更好地了解您为什么会遇到这种情况,以及 PHP 和相关资源句柄的工作方式,那么具有重量级和耗时的连接过程的数据库是 Oracle。合法使用 Oracle 和 PHP 的人必须关注连接重用,因为 Oracle 预计会建立连接,然后会发生许多“会话”。尽管这篇Oracle Cookbook 文章现在有些陈旧,但它很好地说明了 PHP 进程(至少与 Apache 和 Mod_php)和数据库连接之间的关联。

最后但并非最不重要的一点是,由于您可以通过多种不同的方式运行 PHP,因此本主题很复杂。Apache有几种不同的配置,不同于IIS,也不同于近几年流行的Nginx/php-fpm。 这个 SO 问题/答案已经解决了您尝试使用的特定 PDO 参数,它最终只是将它传递给 MySQL 客户端库,以及一些重要的警告和问题,这些警告和担忧解释了为什么 MySQL 连接很少值得他们可能遇到的潜在麻烦原因。