0

对于我的一个 Android 应用程序,我遇到了基于 PHP/Mysql 的 Web 服务 API 的问题。这是问题描述。

我在错误日志中收到以下错误。

用户my-db-user已经有超过'max_user_connections' 的活动连接

我的代码用完了mysql database connections,我已经达到了我的主机可以提供的最大限制。我不能再增加max_connectionsmax_user_connections

这是我在 PHP 脚本中编写数据库访问的方法。我到处都遵循这种模式,因此在所有数据库访问类及其方法(如获取、插入、更新、删除等)中都是相同的。

数据库助手.php

 <?php

 class DatabaseHelper {

      private $db_host = 'my-host';
      private $db_user = 'my-db-user';
      private $db_password = 'my-password';
      private $db_name = 'my-db-name';

      public function getConnection() {
           try {
           $con = new mysqli($this->db_host, $this->db_user, $this->db_password, $this->db_name);
           return $con;
           } catch (Exception $ex) {
                error_log('DB Error --> ' . $ex);
                return null;
           }
      }
 }

?>

这是我如何使用它的数据库访问类。

<?php

require_once (dirname(__FILE__) . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "pathtofile" . DIRECTORY_SEPARATOR . 'DatabaseHelper.php');

class SomeDao {    

    public function get() {
        $result = array();
        $database = new DatabaseHelper();
        $mysqli = $database->getConnection();       
        if ($mysqli != null) {
            $stmt = $mysqli->stmt_init();
            if ($stmt->prepare("SELECT columns FROM some_table")) {
                $status = $stmt->execute();
                if ($status) {
                    $stmt->bind_result($columns);
                    $records = array();
                    while ($stmt->fetch()) {
                        // build record array
                        $record = array();
                        // add key value pairs to array
                        $record["columns"] = $columns;
                        // add $record to $records
                        array_push($records, $record);
                    }
                    $result["statusCode"] = Constants::$OK;
                    $result["statusMessage"] = "OK";
                    $result["records"] = $records;
                } else {
                    $result["statusCode"] = Constants::$SYSTEM_ERROR;
                    $result["statusMessage"] = "System Error." . $mysqli->error;
                }
                @$stmt->close();
            } else {
                $result["statusCode"] = Constants::$SYSTEM_ERROR;
                $result["statusMessage"] = "System Error." . $mysqli->error;
            }            
            @$mysqli->close();
        } else {
            $result["statusCode"] = Constants::$SYSTEM_ERROR;
            $result["statusMessage"] = "System Error.";
        }
        return $result;
    }   
}
?>

我相信会有很多像我一样的人会遇到这个问题并成功解决它。必须有一些方法来优化使用,mysql db connections我想知道我该怎么做。我只需要我可以用来克服这个问题的最佳方法。

希望我已经清楚地说明了我的问题。请帮忙。

问候

4

3 回答 3

2

为每个查询打开和关闭连接是非常浪费的。

这意味着每次将火柴移入和移出桌子时,都要经历整个身份验证过程并创建不同的 TCP 连接。

你最终会得到一堆垂死的 TCP 连接(有耗尽 TCP 端口的风险),并使用相当大一部分带宽与数据库服务器交换密码。

此外,如果您碰巧忘记关闭其中一个连接,它可能会一直存活到脚本结束,从而减少可用连接的数量。可以说是一种“连接泄漏”。

典型的会话应如下所示:

open connection
    do some stuff
    do some stuff
    do some stuff
    do some stuff
close connection

并不是 :

open / do stuff / close
open / do stuff / close
open / do stuff / close
open / do stuff / close

由于您已经有一个助手类,我建议您只打开一次连接(当您实例化助手时)并在每次需要访问数据库时从中获取连接句柄。仅当帮助程序被销毁时(即在最坏的情况下在脚本结束时,或者当帮助程序超出范围时),才应关闭连接。

作为一个额外的好处,它将使您的代码更加紧凑。所有这些错误报告都比实际的处理代码大,因此很难发现错误。更好地在您的帮助对象中处理它们,以便代码可以专注于完成工作。

最后但并非最不重要的一点是,您可以在帮助对象中添加一致性检查。例如,计算静态类变量中打开的连接数,只是为了确保您没有无意中实例化更多帮助程序或创建比您想象的更多的连接。

如果您遵循此模式,则每个当前活动的请求最多应该有一个 DB 连接,这应该会最大化您的响应能力。

如果您的页面一直在通过 Ajax 进行六次查询,那么会更快地达到限制。尝试通过分解您的请求来减少数据库的使用。

如果一些愚蠢的 SEO 机器人或精神病用户在您的网站上玩手提钻,除了监控客户端 IP 并拒绝访问那些执行过于频繁查询的人之外,您几乎无能为力。

持久连接只会让您首先减轻做错事的损害,因为“关闭”它们实际上不会这样做(并且重新打开它们也不会对它们产生影响),前提是您为此设置了正确的选项.

于 2014-01-01T03:20:33.493 回答
0

您可以尝试使用持久连接。

用 p 前缀你的主机:像这样:而不是 private $db_host = 'my-host'; 尝试私有 $db_host = 'p:my-host';

这仅适用于 php 版本 5.3 及更高版本。它可能会或可能不会帮助您,但值得一试。请务必阅读此文档 http://www.php.net/manual/en/mysqli.quickstart.connections.php

如果尚未设置,您可能必须设置 mysqli.allow_persistent。

于 2014-01-01T02:30:38.210 回答
0

尝试通过p:在前面添加来使用持久连接$db_host

private $db_host = 'p:my-host';

请务必阅读本文档,以免引入任何不需要的副作用。

于 2014-01-01T02:31:04.550 回答