Signatur
Beschreibung
Das Interface MongoDB\Driver\Monitoring\SDAMSubscriber definiert die Methoden, die ein Objekt implementieren muss, um Server-Discovery-and-Monitoring-Ereignisse (SDAM) des MongoDB-Treibers zu empfangen. SDAM beschreibt, wie der Treiber die Topologie eines MongoDB-Deployments (Standalone, Replica Set, Sharded Cluster) erkennt und verfolgt.
Klassen, die dieses Interface implementieren, können über Änderungen an der Server-Topologie informiert werden – zum Beispiel wenn Server hinzugefügt oder entfernt werden, wenn sich der Zustand eines Servers ändert oder wenn Heartbeat-Ereignisse auftreten. Das Interface erweitert MongoDB\Driver\Monitoring\Subscriber und muss mit MongoDB\Driver\Monitoring\addSubscriber() registriert werden.
Typische Anwendungsfälle umfassen das Logging von Topologieänderungen, das Monitoring der Cluster-Gesundheit in Produktionssystemen sowie das Debuggen von Verbindungsproblemen und Failover-Szenarien in Replica Sets.
- serverChanged – Wird aufgerufen, wenn sich die Beschreibung eines Servers ändert.
- serverClosed – Wird aufgerufen, wenn ein Server aus der Topologie entfernt wird.
- serverOpening – Wird aufgerufen, wenn ein neuer Server zur Topologie hinzugefügt wird.
- topologyChanged – Wird aufgerufen, wenn sich die Topologiebeschreibung ändert.
- topologyClosed – Wird aufgerufen, wenn eine Topologie geschlossen wird.
- topologyOpening – Wird aufgerufen, wenn eine neue Topologie geöffnet wird.
- serverHeartbeatFailed – Wird aufgerufen, wenn ein Server-Heartbeat fehlschlägt.
- serverHeartbeatStarted – Wird aufgerufen, wenn ein Server-Heartbeat gestartet wird.
- serverHeartbeatSucceeded – Wird aufgerufen, wenn ein Server-Heartbeat erfolgreich abgeschlossen wurde.
Beispiele
Einfacher SDAM-Subscriber zur Protokollierung von Topologieänderungen
<?php
use MongoDB\Driver\Monitoring\SDAMSubscriber;
use MongoDB\Driver\Monitoring\ServerChangedEvent;
use MongoDB\Driver\Monitoring\ServerClosedEvent;
use MongoDB\Driver\Monitoring\ServerOpeningEvent;
use MongoDB\Driver\Monitoring\TopologyChangedEvent;
use MongoDB\Driver\Monitoring\TopologyClosedEvent;
use MongoDB\Driver\Monitoring\TopologyOpeningEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent;
class SDAMLogger implements SDAMSubscriber
{
public function serverChanged(ServerChangedEvent $event): void
{
echo sprintf(
"Server geändert: %s:%d\n",
$event->getHost(),
$event->getPort()
);
}
public function serverClosed(ServerClosedEvent $event): void
{
echo sprintf(
"Server geschlossen: %s:%d\n",
$event->getHost(),
$event->getPort()
);
}
public function serverOpening(ServerOpeningEvent $event): void
{
echo sprintf(
"Server geöffnet: %s:%d\n",
$event->getHost(),
$event->getPort()
);
}
public function topologyChanged(TopologyChangedEvent $event): void
{
echo "Topologie geändert.\n";
}
public function topologyClosed(TopologyClosedEvent $event): void
{
echo "Topologie geschlossen.\n";
}
public function topologyOpening(TopologyOpeningEvent $event): void
{
echo "Topologie geöffnet.\n";
}
public function serverHeartbeatFailed(ServerHeartbeatFailedEvent $event): void
{
echo sprintf(
"Heartbeat fehlgeschlagen: %s:%d - %s\n",
$event->getHost(),
$event->getPort(),
$event->getError()->getMessage()
);
}
public function serverHeartbeatStarted(ServerHeartbeatStartedEvent $event): void
{
// optional: Heartbeat-Start protokollieren
}
public function serverHeartbeatSucceeded(ServerHeartbeatSucceededEvent $event): void
{
// optional: erfolgreiche Heartbeats protokollieren
}
}
$subscriber = new SDAMLogger();
MongoDB\Driver\Monitoring\addSubscriber($subscriber);
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
// Beliebige Datenbankoperationen...
SDAM-Subscriber zur Messung der Heartbeat-Dauer
<?php
use MongoDB\Driver\Monitoring\SDAMSubscriber;
use MongoDB\Driver\Monitoring\ServerChangedEvent;
use MongoDB\Driver\Monitoring\ServerClosedEvent;
use MongoDB\Driver\Monitoring\ServerOpeningEvent;
use MongoDB\Driver\Monitoring\TopologyChangedEvent;
use MongoDB\Driver\Monitoring\TopologyClosedEvent;
use MongoDB\Driver\Monitoring\TopologyOpeningEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent;
use MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent;
class HeartbeatMonitor implements SDAMSubscriber
{
private array $heartbeatStart = [];
public function serverHeartbeatStarted(ServerHeartbeatStartedEvent $event): void
{
$key = $event->getHost() . ':' . $event->getPort();
$this->heartbeatStart[$key] = microtime(true);
}
public function serverHeartbeatSucceeded(ServerHeartbeatSucceededEvent $event): void
{
$key = $event->getHost() . ':' . $event->getPort();
$dauer = (microtime(true) - ($this->heartbeatStart[$key] ?? microtime(true))) * 1000;
echo sprintf("Heartbeat erfolgreich für %s: %.2f ms\n", $key, $dauer);
}
public function serverHeartbeatFailed(ServerHeartbeatFailedEvent $event): void
{
$key = $event->getHost() . ':' . $event->getPort();
echo sprintf("Heartbeat fehlgeschlagen für %s: %s\n", $key, $event->getError()->getMessage());
}
public function serverChanged(ServerChangedEvent $event): void {}
public function serverClosed(ServerClosedEvent $event): void {}
public function serverOpening(ServerOpeningEvent $event): void {}
public function topologyChanged(TopologyChangedEvent $event): void {}
public function topologyClosed(TopologyClosedEvent $event): void {}
public function topologyOpening(TopologyOpeningEvent $event): void {}
}
$monitor = new HeartbeatMonitor();
MongoDB\Driver\Monitoring\addSubscriber($monitor);
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$query = new MongoDB\Driver\Query([]);
$cursor = $manager->executeQuery('testdb.col', $query);
// Wichtig · Fallstricke
Alle Methoden müssen implementiert werden: Da PHP-Interfaces vollständige Implementierung aller deklarierten Methoden erfordern, müssen auch selten genutzte Methoden wie serverHeartbeatStarted als leere Methoden vorhanden sein, wenn sie nicht benötigt werden.
Performance: SDAM-Subscriber werden für jeden Heartbeat und jede Topologieänderung aufgerufen. Aufwendige Operationen (z. B. Datenbankschreibvorgänge, synchrone HTTP-Anfragen) innerhalb der Subscriber-Methoden können die Performance des Treibers negativ beeinflussen. Leichtgewichtige Operationen wie In-Memory-Logging sind zu bevorzugen.
Thread-Sicherheit: SDAM-Ereignisse können aus Hintergrund-Threads des Treibers ausgelöst werden. Subscriber-Implementierungen sollten daher thread-sicher sein, sofern eine entsprechende Umgebung (z. B. mit ReactPHP oder parallelen Prozessen) genutzt wird.