5

我有一个问题,它现在才出现。我正在使用最多具有 10 个并发数据库连接的共享网络托管计划。该网络应用程序有几十个查询,一些 pdo,一些 mysql_*。

加载一个页面在 5-6 个并发连接时达到峰值,这意味着至少需要 2 个用户同时加载它才能在其中一个或两个上吐出错误。

我知道这是低效的,我相信我可以减少很多,但这就是我目前的想法是将 pdo 代码移动到一个函数中,然后传入一个查询字符串和一个变量数组,然后让它返回一个数组(部分是为了整理我的代码)。

实际问题:

我怎样才能让这个函数继续重试,直到它设法执行,并保留调用它的脚本(以及任何可能调用该函数的脚本),直到它设法执行并返回它的数据?我不希望事情乱七八糟地执行,我很高兴代码在高峰时间被延迟一秒钟左右

由于有人会要求提供代码,这就是我目前所做的。我在它自己的文件中有这个,所以我有一个中心位置来更改连接参数。if 语句只是为了消除当我从测试服务器切换到肝脏服务器时不断更改参数的需要

$dbtype = "mysql";
$server_addr = $_SERVER['SERVER_ADDR'];
if ($server_addr == '192.168.1.10') {
    $dbhost = "localhost";
} else {
    $dbhost = "xxxxx.xxxxx.xxxxx.co.nz";
}
$dbname = "mydatabase";
$dbuser = "user";
$dbpass = "supersecretpassword";

我在函数顶部“包含”该文件

 include 'db_connection_params.php';
        $pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);

然后在一个连接上运行这样的命令

$sql = "select * from tbl_sub_cargo_cap where sub_model_sk = ?";
$capq = $pdo_conn->prepare($sql);
$capq->execute(array($sk_to_load));
while ($caprow = $capq->fetch(PDO::FETCH_ASSOC)) {
//stuff
}
4

2 回答 2

7

单个页面不需要 5-6 个并发连接,每个页面实际上应该只使用 1 个连接。我会尝试重新构建应用程序的任何部分导致单个页面上的多个连接。

但是,您应该能够在连接失败时捕获 PDOException(有关连接管理的文档),然后重试几次。

一个简单的例子,

<?php
$retries = 3;
while ($retries > 0)
{
    try
    {
        $dbh = new PDO("mysql:host=localhost;dbname=blahblah", $user, $pass);
        // Do query, etc.
        $retries = 0;
    }
    catch (PDOException $e)
    {
        // Should probably check $e is a connection error, could be a query error!
        echo "Something went wrong, retrying...";
        $retries--;
        usleep(500); // Wait 0.5s between retries.
    }
}
于 2013-02-18T05:53:03.117 回答
0

10 个并发连接很多。它可以轻松地为 10-15 个在线用户提供服务。需要付出巨大的努力才能使他们筋疲力尽。
所以你的代码有问题。

有两个主要原因:

  • 慢查询需要太多时间,因此服务一次命中使用一个 mysql 连接的时间太长。
  • 从每个脚本打开多个连接。

前一个必须调查,但后一个很简单:

  1. 不要在一个脚本中混合 myqsl_ 和 PDO:您一次打开 2 个连接。
  2. 使用 PDO 时,只打开一次连接,然后在整个代码中使用它。

减少一个脚本中的连接数是唯一的方法。
如果您的代码中有多个 PDO 类实例,则需要将所需的超时处理代码添加到每个调用中。因此,无论如何都需要大量的代码重写。
将这些新实例global $pdo;替换为。这将花费相同的时间,但它将是永久解决方案,而不是您想要的临时补丁。
请理智一点。

PHP 会在脚本结束时自动关闭所有连接,您不必担心手动关闭它们。
一个脚本中只有一个连接是一种常见的做法。它被世界各地的所有开发人员使用。您可以毫无疑问地使用它。就用它吧。

于 2013-02-18T05:49:43.987 回答