Pool Verbindungspool
Das gemeinsame Nutzen desselben Verbindungsobjekts durch mehrere Koroutinen kann zu Datenkomplikationen führen. Daher ist es notwendig, einen Verbindungspool zur Verwaltung von Verbindungsressourcen für Datenbanken, Redis usw. zu verwenden.
Hinweis
Diese Funktion benötigt workerman>=5.1.0
Achtung
- Die zugrunde liegende Architektur unterstützt automatisch Swoole/Swow/Fiber/Select/Event-Driven.
- Wenn Sie Fiber/Select/Event-Driven verwenden und PDO, Redis oder andere blockierende Erweiterungen verwenden, wird es automatisch auf einen Verbindungspool mit nur einer Verbindung herabgestuft.
Redis Verbindungspool
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Coroutine\Pool;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
class RedisPool
{
private Pool $pool;
public function __construct($host, $port, $max_connections = 10)
{
$this->pool = new Pool($max_connections);
// Setzen Sie die Methode zum Erstellen von Verbindungen im Verbindungspool
$this->pool->setConnectionCreator(function () use ($host, $port) {
$redis = new \Redis();
$redis->connect($host, $port);
return $redis;
});
// Setzen Sie die Methode zum Zerstören von Verbindungen im Verbindungspool
$this->pool->setConnectionCloser(function ($redis) {
$redis->close();
});
// Setzen Sie die Methode zur Überprüfung des Heartbeats
$this->pool->setHeartbeatChecker(function ($redis) {
$redis->ping();
});
}
// Verbindung abrufen
public function get(): \Redis
{
return $this->pool->get();
}
// Verbindung zurückgeben
public function put($redis): void
{
$this->pool->put($redis);
}
}
// Http Server
$worker = new Worker('http://0.0.0.0:8001');
$worker->eventLoop = Swoole::class; // Oder Swow::class oder Fiber::class
$worker->onMessage = function (TcpConnection $connection, Request $request) {
static $pool;
if (!$pool) {
$pool = new RedisPool('127.0.0.1', 6379, 10);
}
$redis = $pool->get();
$redis->set('key', 'hello');
$value = $redis->get('key');
$pool->put($redis);
$connection->send($value);
};
Worker::runAll();
MySQL Verbindungspool (unterstützt automatisches Abrufen und Zurückgeben von Verbindungen)
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Coroutine\Context;
use Workerman\Coroutine;
use Workerman\Coroutine\Pool;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
class Db
{
private static ?Pool $pool = null;
public static function __callStatic($name, $arguments)
{
if (self::$pool === null) {
self::initializePool();
}
// Aus dem Koroutinenkontext die Verbindung abrufen, um sicherzustellen, dass dieselbe Koroutine dieselbe Verbindung verwendet
$pdo = Context::get('pdo');
if (!$pdo) {
// Verbindung vom Verbindungspool abrufen
$pdo = self::$pool->get();
Context::set('pdo', $pdo);
// Bei Ende der Koroutine wird die Verbindung automatisch zurückgegeben
Coroutine::defer(function () use ($pdo) {
self::$pool->put($pdo);
});
}
return call_user_func_array([$pdo, $name], $arguments);
}
private static function initializePool(): void
{
self::$pool = new Pool(10);
self::$pool->setConnectionCreator(function () {
return new \PDO('mysql:host=127.0.0.1;dbname=your_database', 'your_username', 'your_password');
});
self::$pool->setConnectionCloser(function ($pdo) {
$pdo = null;
});
self::$pool->setHeartbeatChecker(function ($pdo) {
$pdo->query('SELECT 1');
});
}
}
// Http Server
$worker = new Worker('http://0.0.0.0:8001');
$worker->eventLoop = Swoole::class; // Oder Swow::class oder Fiber::class
$worker->onMessage = function (TcpConnection $connection, Request $request) {
$value = Db::query('SELECT NOW() as now')->fetchAll();
$connection->send(json_encode($value));
};
Worker::runAll();
Schnittstellendefinition
interface PoolInterface
{
/**
* Konstruktor
* @param int $max_connections Maximale Anzahl von Verbindungen, Standard 1
* @param array $config = [
* 'min_connections' => 1, // Minimale Anzahl von Verbindungen, Standard ist 1
* 'idle_timeout' => 60, // Zeitüberschreitung für Leerlaufverbindungen (Sekunden), Standardwert 60 Sekunden, nach 60 Sekunden wird die Verbindung gelöscht und aus dem Verbindungspool entfernt
* 'heartbeat_interval' => 50, // Intervall für die Heartbeat-Prüfung (Sekunden), Standardmäßig 50 Sekunden, jede 50 Sekunden wird geprüft, ob die Verbindung normal ist
* 'wait_timeout' => 10, // Wartezeitüberschreitung beim Abrufen einer Verbindung (Sekunden), Standardmäßig 10 Sekunden, nach 10 Sekunden schlägt der Abruf einer Verbindung fehl und wirft eine Ausnahme
* ]
*/
public function __construct(int $max_connections = 1, array $config = []);
/**
* Eine Verbindung abrufen
*/
public function get(): mixed;
/**
* Eine Verbindung zurückgeben
*/
public function put(object $connection): void;
/**
* Eine Verbindung erstellen
*/
public function createConnection(): object;
/**
* Verbindung schließen und aus dem Verbindungspool entfernen
*/
public function closeConnection(object $connection): void;
/**
* Die aktuelle Anzahl der Verbindungen im Verbindungspool abrufen (einschließlich bereits abgerufener Verbindungen und nicht abgerufener Verbindungen)
*/
public function getConnectionCount(): int;
/**
* Verbindungen im Verbindungspool schließen (ohne bereits abgerufene Verbindungen)
*/
public function closeConnections(): void;
/**
* Die Methode zum Erstellen von Verbindungen im Verbindungspool festlegen
*/
public function setConnectionCreator(callable $connectionCreateHandler): self;
/**
* Die Methode zum Zerstören von Verbindungen im Verbindungspool festlegen
*/
public function setConnectionCloser(callable $connectionDestroyHandler): self;
/**
* Die Methode zur Überprüfung des Heartbeats festlegen
*/
public function setHeartbeatChecker(callable $connectionHeartbeatHandler): self;
}