Heim >Backend-Entwicklung >PHP-Tutorial >Detaillierte Erläuterung des Codes zur Implementierung des MySQL-Verbindungspooleffekts in PHP

Detaillierte Erläuterung des Codes zur Implementierung des MySQL-Verbindungspooleffekts in PHP

jacklove
jackloveOriginal
2018-06-29 17:27:111540Durchsuche

In diesem Artikel wird hauptsächlich der PHP-Code zum Implementieren des MySQL-Verbindungspooleffekts vorgestellt. Freunde, die ihn benötigen, können sich auf

Loop beziehen, um Verbindungen aus dem MySQL-Verbindungspool abzurufen, ohne wiederholt neue Verbindungen erstellen zu müssen.

Änderung der Referenzkonfiguration: Sie können sich auf den folgenden Artikel beziehen

Verhindern Sie, dass die Anzahl der Besuche zu groß wird und die Anzahl der Verbindungen überfüllt wird

<?php

/**
 * @author xuleyan
 * @title mysql类
 */

class DbHelper{
  //连接池
  private $_pools = [];

  //连接池大小
  const POOLSIZE = 5;

  const USERNAME = "root";
  const PASSWORD = "root";
  const HOST = "127.0.0.1";
  const DB = "test";

  public function __construct()  
  {
    $db = self::DB;
    $username = self::USERNAME;
    $password = self::PASSWORD;
    $host = self::HOST;

    //持久化连接
    $presistent = array(PDO::ATTR_PERSISTENT => true);

    for ($i=0; $i < self::POOLSIZE; $i++) { 
      $connection = new PDO("mysql:dbname=$db;host=$host", $username, $password);
      // sleep(3);
      array_push($this->_pools, $connection);
    }
  }

  //从数据库连接池中获取一个数据库链接资源
  public function getConnection()
  {
    echo &#39;get&#39; . count($this->_pools) . "<br>";
    if (count($this->_pools) > 0) {
      $one = array_pop($this->_pools);
      echo &#39;getAfter&#39; . count($this->_pools) . "<br>";
      return $one;
    } else {
      throw new ErrorException ( "<mark>数据库连接池中已无链接资源,请稍后重试!</mark>" );
    }
  }

  //将用完的数据库链接资源放回到数据库连接池
  public function release($conn)
  {
    echo &#39;release&#39; . count($this->_pools) . "<br>";
    if (count($this->_pools) >= self::POOLSIZE) {
      throw new ErrorException ( "<mark>数据库连接池已满!</mark>" );
    } else {
      array_push($this->_pools, $conn);
      // $conn = null;
      echo &#39;releaseAfter&#39; . count($this->_pools) . "<br>";
    }
  }

  public function query($sql)
  {
    try {
      $conn = $this->getConnection();
      $res = $conn->query($sql);
      $this->release($conn);
      return $res;
    } catch (ErrorException $e) {
      print &#39;error:&#39; . $e->getMessage();
      die;
    }
  }

  public function queryAll($sql)
  {
    try {
      $conn = $this->getConnection();
      $sth = $conn->prepare($sql);
      $sth->execute();
      $result = $sth->fetchAll();
      return $result;
    } catch (PDOException $e) {
      print &#39;error:&#39; . $e->getMessage();
      die;
    }
  }
}

Rufen Sie dies in einer anderen Datei auf

<?php 

require_once &#39;db.php&#39;;
$sql = &#39;select * from user&#39;;

$dbhelper = new DbHelper;
for ($i=0; $i < 10; $i++) { 
  $res = $dbhelper->query($sql);
  // var_dump($res) . PHP_EOL;
}

So verwenden Sie den Verbindungspool von ThinkPHP, um eine Verbindung zu MySQL herzustellen

Weil ein kleiner Fehler dazu führte, dass das Projekt eines Nachts eine große Anzahl von Verbindungsanfragen an MySQL sendete. Gleichzeitig gab es ein Problem mit dem DNS des MySQL-Servers, was zu einer Zeitüberschreitung der Anti-Auflösung führte . Schließlich wurde der MySQL-Server zum Leben erweckt.

Endlich wurde der Fehler behoben und wir untersuchten, wie wir den MySQL-Verbindungspool vergrößern können.

Nachdem ich in den letzten zwei Tagen gesucht habe, habe ich festgestellt, dass es in der ThinkPHP-Dokumentation keine Dokumentation zum Verbindungspooling gibt. Also habe ich den Code selbst studiert.

Zuallererst: Es gibt drei häufig verwendete MySQL-Erweiterungsbibliotheken für PHP: mysql, mysqli, pdo_mysql.

* mysqli unterstützt kein Verbindungspooling.
* pdo_mysql wird unterstützt, die pdo-Erweiterung von thinkPHP unterstützt jedoch nicht mysql, sondern nur:'MSSQL','ORACLE','Ibase','OCI' (siehe Zeile 59 von Pdo.class.php)

* MySQL-Unterstützung über die Methode: mysql_pconnect. (Spezifische Parameter finden Sie in der offiziellen PHP-Dokumentation)

1 Die Möglichkeit, ThinkPHP für die Aktivierung langer Verbindungen zu aktivieren, ist:

class BaseMysql extends Model {
  protected $connection = array(
    &#39;db_type&#39; => &#39;mysql&#39;,
    &#39;db_user&#39; => &#39;***&#39;,
    &#39;db_pwd&#39; => &#39;*******&#39;,
    &#39;db_host&#39; => &#39;*******&#39;,
    &#39;db_port&#39; => &#39;3306&#39;,
    &#39;db_name&#39; => &#39;custom&#39;,
    &#39;db_params&#39; => array(&#39;persist&#39; => true),
  );
}

Wenn Sie denken, dass alles gut wird, wenn Sie dies nur konfigurieren, liegen Sie völlig falsch.

2 mysql -> my.cnf geänderte Konfiguration:
[mysqld]

interactive_timeout =60 // Ablaufzeit der interaktiven Verbindung (MySQL-Client).
wait_timeout =30 //Ablaufzeit einer langen Verbindung. Das muss geändert werden! Der Standardwert beträgt 8 Stunden. Wenn das Anforderungsvolumen groß ist, ist die Anzahl der Verbindungen bald erschöpft.
max_connections = 100 //Die maximale Anzahl von Verbindungen kann als Größe des Verbindungspools betrachtet werden

3 php.ini-Änderung:
[MySql]
mysql.allow_persistent = On
mysql.max_persistent = 99 // Muss kleiner sein als die maximale Anzahl von Verbindungen, die von mysql konfiguriert wurden
mysql.max_links = 99

4 Wenn der Webserver Apache ist, muss Keep-Alive aktiviert sein. Andernfalls kann die lange Verbindung nach Beendigung der Anforderung nicht wiederverwendet werden.
Webserver ist der Fall von Nginx:
pm = dynamisch // Standardmäßig einige Unterprozesse starten, um http-Anfragen zu verarbeiten.
pm.max_children // Maximale Anzahl untergeordneter Prozesse. Diese Konfiguration sollte kleiner sein als die max_connections von MySQL.

5 Wenn Sie feststellen, dass es immer noch nicht verwendet werden kann, überprüfen Sie bitte, ob das Keepalive des Betriebssystems aktiviert ist.

Übersicht:

Sie müssen gleichzeitig die Keep-Alive-Verbindung und die lange Datenbankverbindung aktivieren, da die lange Verbindung sonst die Anzahl der MySQL-Verbindungsressourcen vergeblich belegt und kann nicht wiederverwendet werden.
Im Fall von Nginx + PHP-FPM wird die lange Verbindung zwischen dem PHP-FPM-Unterprozess und MySQL tatsächlich aufrechterhalten. Welchem ​​PHP-FPM-Unterprozess die Front-End-HTTP-Anfrage zugewiesen ist, der Unterprozess wird seine lange Verbindung mit MySQL wiederverwenden.

Das oben Gesagte ist das Ergebnis einer ganztägigen Recherche. Bitte weisen Sie auf etwaige Unvollkommenheiten hin und danken Ihnen im Voraus!

Verwandte Empfehlungen:

Detaillierte Erklärung zur Verwendung von PHP CURL und Java http

Temporäre Übertragung von WeChat-Aufzeichnungen für PHP WeChat-Entwicklung Permanente Speicherung von PHP-Kenntnissen

PHP-Entwurfsmusterregistrierungsbaummusteranalyse PHP-Kenntnisse


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Codes zur Implementierung des MySQL-Verbindungspooleffekts in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn