Willkommen auf der privaten Homepage von Johannes Jarolim, Salzburg, Österreich. Welcome to the private homepage of Johannes Jarolim, Salzburg, Austria, Europe.
Eine Artikel mit

Schlagwort pheanstalk

Asynchrone Datenverarbeitung mit PHP, Pheanstalk und einem Consumer Service unter Debian

Oft möchte man zeitintensive Datenverarbeitung vom Web-Frontend entkoppeln. PHP ist hier leider keine große Hilfe – allerdings geht das relativ einfach mit dem “Umweg” über eine Message Queue. Die Message Queue agiert hierbei als persistenter FIFO Queue: Sobald die Nachricht übermittelt ist, kann das Frontend schon weitermachen. Die Nachricht ist gespeichert und kann jederzeit abgeholt und verarbeitet werden. Im Hintergrund benötigen wir zusätzlich einen Service, der die Nachrichten verlässlich sequentiell abarbeitet: Ich möchte hier ebenfalls mit PHP arbeiten.

Voraussetzung

Solche Lösungen lassen sich auf Shared Hosting Lösungen nur sehr schlecht umsetzen, da man auf seinem Server Software installieren muß: Eine (in meinem Falle) Debian-VPS mit root Rechten muss es schon sein. Unter z.B. https://www.hosteurope.de/Server/Virtual-Server/ bekommt man so eine VPS schon ab EUR 9.99 / Monat.

beanstalkd installieren

Als erstes installieren wir beanstalkd – eine Open Source Message Queue Lösung:

# sudo apt-get update
# sudo apt-get install beanstalkd

Die zugehörige Konfigurationsdatei findet sich unter /etc/default/beanstalkd – Hier können IP und Port konfigurieren, auf denen gehorcht wird. Per Default horch beanstalkd auf 127.0.0.1:11300

Optional: Beanstalkd Console installieren

Optional, aber sehr empfehlenswert: Einen eigenen VHost einrichten und die Beanstalkd Console installieren, die man unter https://github.com/ptrofimov/beanstalk_console finden kann. Mit Hilfe dieser Web-App kann man jederzeit die Queue einsehen, Nachrichten lesen, erstellen oder auch löschen – Sehr hilfreich.

Einen PHP Consumer erstellen

Grundsätzlich benötigen wir ein kleines Programm, dass auf neue Nachrichten in der Queue horcht und diese abarbeitet bzw. “konsumiert”.

Dazu erstellen wir etwas ganz Einfaches: Der Consumer horcht auf die Queue – Der Inhalt neuer Nachrichten wird in ein Logfile geschrieben.

Wir nutzen die composer Library “Pheanstalk\Pheanstalk“:

<?php 

  use Pheanstalk\Pheanstalk; 

  /** 
   * small consumer 
   * @see /lib/systemd/system/beanstalk-consumer.service 
   * @see https://medium.com/@benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6 
   * @author jjarolim, adwerba 
   */ 

  require_once __DIR__ . '/vendor/autoload.php'; 

  $pheanstalk = new Pheanstalk('127.0.0.1'); 

  while ($job = $pheanstalk->watch('default')->reserve()) {
    file_put_contents(__DIR__.'/consumer.log', $job->getData()."\n", FILE_APPEND);
    $pheanstalk->delete($job);	
  }

Service erstellen

Damit der Consumer auch verlässlich im Hintergund läuft und auf neue Nachrichten reagiert, erstellen wir einen Systemd Service: Systemd kümmert sich darum, dass der Consumer verlässlich läuft bzw. neu gestartet wird, sollte er sich aufhängen.

Dazu erstellen wir das File beanstalk-consumer.service unter /lib/systemd/system:

[Unit]
Description=Beanstalk Consumer Demo Service
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=www-data
ExecStart=/usr/bin/env php /path/to/consumer.php

[Install]
WantedBy=multi-user.target

Service starten / stoppen

Schlußendlich starten wir den neuen Service und alles läuft:

# systemctl start beanstalk-consumer

Ab jetzt kann man neue Nachrichten in die Queue schicken: Der Consumer reagiert zeitnah und verarbeitet brav alles.