Redis ®-Warteschlangen für sequentielle Jobverarbeitung mit PHP nutzen

Mit der Redis ®-Queue-Bibliothek kannst du eine Reihe von Aufgaben in der Reihenfolge abarbeiten, in der sie eingegangen sind – also nach dem First-in-First-out-Prinzip. Diese Methode ist im Webentwicklungsbereich besonders nützlich, wenn du vermeiden möchtest, dass Nutzer aufgrund langwieriger Prozesse warten müssen. In stark frequentierten Online-Shops lassen sich etwa Zahlungsverifizierungen oder Adressprüfungen im Hintergrund abwickeln, ohne dass der Benutzerfluss unterbrochen wird. Wenn du also sicherstellen willst, dass Prozesse geordnet ablaufen, aber deine Anwendung zeitkritisch auf Nutzereingaben reagieren soll, ist der Einsatz einer Redis®-Warteschlange – beispielsweise für eine Dateikonvertierung – sehr sinnvoll.

In dieser Anleitung erfährst du, wie du mit den Redis®-Befehlen RPUSH und LPOP sowie PHP und MySQL Benutzerregistrierungen auf einem Ubuntu 20.04-Server in einer MySQL-Datenbank verarbeiten kannst.

Systemanforderungen

Bevor du loslegst, stelle sicher, dass folgende Voraussetzungen erfüllt sind:

  • Ein Server mit Ubuntu 20.04
  • Sudo-Zugriff auf einen Benutzer
  • Ein vollständiger LAMP-Stack (Linux, Apache, MySQL, PHP)
  • Ein funktionierender Redis®-Server

Installation des php-redis-Moduls

Verbinde dich zunächst mit deinem Server. Aktualisiere anschließend die Paketinformationen und installiere das php-redis-Modul. Dieses erlaubt dir, Redis ®-Funktionen direkt in deinen PHP-Skripten zu nutzen.

$ sudo apt update
$ sudo apt install -y php-redis

Starte nach der Installation den Apache-Webserver neu, damit die Änderungen übernommen werden.


$ sudo systemctl restart apache2


Einrichten der test_db-Datenbank

In diesem Abschnitt des Tutorials speicherst du die Registrierungsdaten von Kunden zunächst temporär in Redis ®. Später werden diese Daten dauerhaft in einer MySQL-Datenbank abgelegt.

Beginne damit, dich als Root-Benutzer am MySQL-Server anzumelden:

Nachdem du dein Root-Passwort eingegeben und bestätigt hast, erstelle eine neue Datenbank namens test_db:

mysql> CREATE DATABASE test_db;

Erstelle nun einen MySQL-Benutzer namens test_db_user und weise ihm ein sicheres Passwort zu (ersetze EXAMPLE_PASSWORD durch ein starkes Passwort). Dieser Benutzer wird später von deinem PHP-Skript verwendet, um auf die Datenbank zuzugreifen.

mysql> CREATE USER 'test_db_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
mysql> GRANT ALL PRIVILEGES ON test_db.* TO 'test_db_user'@'localhost';
mysql> FLUSH PRIVILEGES;

Falls du statt MySQL MariaDB verwendest, ersetze die obige Benutzererstellung durch folgenden Befehl:

MariaDB> GRANT ALL PRIVILEGES on test_db.* TO 'test_db_user'@'localhost' identified by 'EXAMPLE_PASSWORD';

Wechsle nun zur neu erstellten test_db-Datenbank:

Erstelle anschließend eine Tabelle customers mit folgendem Befehl:

mysql> CREATE TABLE customers (
       customer_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
       first_name VARCHAR(50),
       last_name VARCHAR(50),
       email_address VARCHAR(255)
       ) ENGINE = InnoDB;

Trage an dieser Stelle noch keine Daten in die Tabelle ein. Die Befüllung erfolgt später über ein Worker-Skript, das die Daten aus Redis ® übernimmt. Verlasse nun die MySQL-Konsole:


PHP-Skript für die Redis ®-Warteschlange erstellen

Lege zunächst eine neue PHP-Datei namens redis_queue.php im Hauptverzeichnis deines Webservers an. In dieser Datei werden Kundendaten über POST-Anfragen entgegengenommen und in die Redis ®-Warteschlange eingefügt.

$ sudo nano /var/www/html/redis_queue.php

Füge folgenden Inhalt in die Datei ein:

<?php
    try {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);

        $data = [];
        $data = [
            'first_name'    => $_POST['first_name'],
            'last_name'     => $_POST['last_name'],
            'email_address' => $_POST['email_address']
        ];

        $redis->rpush("customers_register", json_encode($data));

        echo "Customer details accepted successfully.\n";

    } catch (Exception $e) {
        echo $e->getMessage();
    }

Dieses Skript verbindet sich mit dem Redis®-Server auf dem lokalen System über Port 6379. Es liest die Kundendaten aus dem $_POST-Array, speichert sie in einem assoziativen Array und kodiert dieses anschließend als JSON. Der Datensatz wird dann mithilfe von rpush in die Redis ®-Liste customers_register eingefügt. Nach erfolgreichem Speichern wird eine Bestätigung ausgegeben.

Kundendaten an die Redis ®-Warteschlange senden

Normalerweise würden Nutzer ihre Daten über ein HTML-Formular übermitteln. In diesem Beispiel nutzt du jedoch den Befehl curl, um die Daten direkt an http://localhost/redis_queue.php zu senden.

Führe die folgenden Befehle einzeln aus, um drei verschiedene Kunden in die Warteschlange einzugeben:

$ curl --data "first_name=JOHN&last_name=DOE&email_address=john_doe@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=MARY&last_name=SMITH&email_address=mary_smith@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=ROE&last_name=STEVE&email_address=roe_steve@example.com" http://localhost/redis_queue.php

Jeder dieser Befehle sollte mit folgender Meldung bestätigen, dass die Daten korrekt gespeichert wurden:

Customer details accepted successfully.

Diese Rückmeldung zeigt an, dass die Kundendaten erfolgreich in die Redis®-Warteschlange aufgenommen wurden. Im nächsten Schritt wirst du ein Hintergrundskript erstellen, um diese Einträge weiterzuverarbeiten.

PHP-Skript zur Redis ®-Warteschlange erstellen

Erstelle zunächst eine neue PHP-Datei namens redis_queue.php im Hauptverzeichnis deines Servers. Dieses Skript verarbeitet POST-Anfragen mit den Registrierungsdaten von Kunden.

$ sudo nano /var/www/html/redis_queue.php

Füge anschließend den folgenden PHP-Code in die Datei ein:

<?php
    try {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);

        $data = [];
        $data = [
            'first_name'    => $_POST['first_name'],
            'last_name'     => $_POST['last_name'],
            'email_address' => $_POST['email_address']
        ];

        $redis->rpush("customers_register", json_encode($data));

        echo "Customer details accepted successfully.\n";

    } catch (Exception $e) {
        echo $e->getMessage();
    }

Das Skript baut eine Verbindung zum Redis ®-Dienst auf, der lokal über Port 6379 erreichbar ist. Es nimmt Benutzerdaten aus dem $_POST-Array entgegen, strukturiert sie in einem assoziativen Array und konvertiert diese anschließend in einen JSON-String. Mithilfe des Befehls rpush wird der Datensatz an die Liste customers_register übergeben. Bei Erfolg wird eine Bestätigungsausgabe erzeugt.

Kundendaten in die Warteschlange einreihen

Normalerweise erfolgt die Registrierung über HTML-Formulare. In diesem Fall verwenden wir jedoch das Terminal-Tool curl, um die Daten direkt an das Skript redis_queue.php unter http://localhost/redis_queue.php zu senden.

Führe die folgenden Befehle einzeln aus, um drei Kundendatensätze in die Warteschlange einzureihen:

$ curl --data "first_name=JOHN&last_name=DOE&email_address=john_doe@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=MARY&last_name=SMITH&email_address=mary_smith@example.com" http://localhost/redis_queue.php
$ curl --data "first_name=ROE&last_name=STEVE&email_address=roe_steve@example.com" http://localhost/redis_queue.php

Jeder dieser Befehle sollte folgende Bestätigung zurückgeben:

Customer details accepted successfully.

Diese Ausgabe bestätigt, dass die Redis®-Warteschlange die Kundendaten erfolgreich empfangen und gespeichert hat. Im nächsten Schritt entwickelst du ein Hintergrundskript, um die Einträge weiterzuverarbeiten.

Redis®-Daten dauerhaft in MySQL speichern

In diesem Schritt erstellst du einen Hintergrundprozess, der Kundendaten aus der Redis®-Warteschlange entfernt und dauerhaft in einer MySQL-Datenbank speichert. Dafür verwendest du die LPOP-Funktion von Redis®, die nach dem First-In-First-Out-Prinzip arbeitet.

Beginne mit dem Anlegen einer neuen PHP-Datei namens redis_worker.php im Stammverzeichnis deines Webservers:

$ sudo nano /var/www/html/redis_worker.php

Füge folgenden PHP-Code in die Datei ein:

<?php
    try {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);

        $data = $redis->lpop('customers_register');
        $data = json_decode($data, true);

        if (!empty($data)) {
            $db_name     = 'test_db';
            $db_user     = 'test_db_user';
            $db_password = 'EXAMPLE_PASSWORD';
            $db_host     = 'localhost';

            $pdo = new PDO('mysql:host=' . $db_host . '; dbname=' . $db_name, $db_user, $db_password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

            $sql = 'insert into customers
                    (
                    first_name,
                    last_name,
                    email_address
                    )
                    values
                    (
                    :first_name,
                    :last_name,
                    :email_address
                    )';

            $stmt = $pdo->prepare($sql);
            $stmt->execute($data);

            echo $data['first_name'] . " " . $data['last_name'] . "'s details saved to database.";
        }

    } catch (Exception $e) {
        echo $e->getMessage();
    }

Das Skript verbindet sich mit dem lokal laufenden Redis®-Dienst und holt mithilfe der lpop-Funktion den ältesten Eintrag aus der Warteschlange customers_register. Die JSON-kodierten Daten werden dekodiert und anschließend mithilfe von PHP Data Objects (PDO) in die MySQL-Tabelle customers eingefügt.

Die SQL-Anweisung verwendet gebundene Parameter – eine bewährte Sicherheitsmaßnahme gegen SQL-Injection-Angriffe. Nach erfolgreicher Ausführung gibt das Skript eine Bestätigung aus, dass die Kundendaten gespeichert wurden.

Wichtig: Dieses Beispiel dient nur Demonstrationszwecken und enthält keine Validierungslogik. In produktiven Umgebungen solltest du zusätzlich auf Datenprüfung und -bereinigung achten, um die Sicherheit deiner Anwendung zu gewährleisten.

Redis®-Worker-Skript überprüfen

Um sicherzustellen, dass das Skript redis_worker.php korrekt arbeitet, rufe die URL http://localhost/redis_worker.php auf. Führe dazu folgenden Befehl dreimal aus, um alle zuvor in die Warteschlange eingetragenen Einträge zu verarbeiten:

$ curl http://localhost/redis_worker.php

Wenn die Einrichtung korrekt ist, sollte die Ausgabe anzeigen, dass die Kundendaten aus der Redis®-Liste entfernt und in der gleichen Reihenfolge in die Datenbank gespeichert wurden, in der sie eingetragen wurden:

JOHN DOE's details saved to database.
MARY SMITH's details saved to database.
ROE STEVE's details saved to database.

Gespeicherte Daten in MySQL kontrollieren

Um zu überprüfen, ob alle Kundendaten korrekt in der Datenbank gespeichert wurden, melde dich mit Root-Zugang am MySQL-Server an:

Sobald du eingeloggt bist, wechsle in die entsprechende Datenbank:

Führe nun eine SELECT-Abfrage aus, um alle Einträge in der Tabelle customers anzuzeigen:

mysql> SELECT
       customer_id,
       first_name,
       last_name,
       email_address
       FROM customers;

Die Ausgabe sollte in etwa wie folgt aussehen und bestätigen, dass das Redis®-Queue-System und der Worker korrekt arbeiten:

+-------------+------------+-----------+------------------------+
| customer_id | first_name | last_name | email_address          |
+-------------+------------+-----------+------------------------+
|           1 | JOHN       | DOE       | john_doe@example.com   |
|           2 | MARY       | SMITH     | mary_smith@example.com |
|           3 | ROE        | STEVE     | roe_steve@example.com  |
+-------------+------------+-----------+------------------------+
3 rows in set (0.00 sec)

Beende die MySQL-Sitzung mit folgendem Befehl:


Redis®-Worker mit einem Cronjob automatisieren

Bisher hast du das Skript redis_worker.php manuell über den curl-Befehl ausgeführt. In diesem Schritt richtest du einen Cronjob ein, der das Skript automatisch in regelmäßigen Abständen startet – ganz ohne manuelles Zutun.

Öffne dazu die systemweite crontab-Datei:

Füge ganz unten in der Datei die folgende Zeile ein, um das Skript redis_worker.php jede Minute auszuführen:

* * * * * root /usr/bin/wget -O - http://localhost/redis_worker.php

Speichere die Datei und beende den Editor. Danach sende einen weiteren Kundeneintrag an den Endpunkt redis_queue.php:

$ curl --data "first_name=BABY&last_name=SMALL&email_address=baby_small@example.com" http://localhost/redis_queue.php

Der Befehl sollte eine Erfolgsmeldung zurückgeben, die bestätigt, dass die Kundendaten korrekt in die Redis®-Warteschlange aufgenommen wurden:

Customer details accepted successfully.

Warte etwa eine Minute und melde dich anschließend erneut am MySQL-Server an, um zu prüfen, ob die Daten übernommen wurden:

Sobald du in der MySQL-Konsole bist, wechsle in die passende Datenbank:

Kontrolliere den Inhalt der customers-Tabelle mit folgender Abfrage:

mysql> SELECT
       customer_id,
       first_name,
       last_name,
       email_address
       FROM customers;

Wenn alles korrekt funktioniert hat, solltest du folgenden zusätzlichen Eintrag sehen:

+-------------+------------+-----------+------------------------+
| customer_id | first_name | last_name | email_address          |
+-------------+------------+-----------+------------------------+
|           1 | JOHN       | DOE       | john_doe@example.com   |
|           2 | MARY       | SMITH     | mary_smith@example.com |
|           3 | ROE        | STEVE     | roe_steve@example.com  |
|           4 | BABY       | SMALL     | baby_small@example.com |
+-------------+------------+-----------+------------------------+
4 rows in set (0.00 sec)

Für besonders zeitkritische Anwendungen reicht ein Intervall von einer Minute eventuell nicht aus. In solchen Fällen empfiehlt sich eine Endlosschleife in PHP, die regelmäßig nach neuen Einträgen sucht.

Fazit

In diesem Tutorial hast du gelernt, wie du mit Redis ® und PHP auf einem Ubuntu 20.04-Server ein Warteschlangensystem für Hintergrundjobs umsetzt. Du hast Daten in Redis ® eingereiht, mit einem Worker verarbeitet und dauerhaft in einer MySQL-Datenbank gespeichert. Das gezeigte Konzept kann beliebig angepasst und erweitert werden – je nach Anwendungsfall.

Quelle: vultr.com

Jetzt 200€ Guthaben sichern

Registrieren Sie sich jetzt in unserer ccloud³ und erhalten Sie 200€ Startguthaben für Ihr Projekt.

Das könnte Sie auch interessieren:

Es wurden keine Ergebnisse gefunden.