Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Asynchrone Event Verarbeitung

Asynchrone Event Verarbeitung

Vortrag auf der Symfony UG Frankfurt zum Thema "Asychrone Event Verarbeitung" mit Symfony2 und RabbitMQ im Speziellen. Wir zeigen hier die Vor- und Nachteil, sowie einige Best Practices und Erfahrungswerte.

Avatar for Garden of Concepts GmbH

Garden of Concepts GmbH

February 26, 2016

Other Decks in Programming

Transcript

  1. Garden of Concepts GmbH • Hanau / München • Eigenes

    CMS - System • Eigenes CRM - System • Individual - Entwicklungen • Symfony Entwicklung ◦ MongoDB, ElasticSearch, MySQL, RabbitMQ, Redis, AngularJS, Twig, Jade, Gitlab, Docker, Vagrant, Ansible • Say hi @goc_mediastudio
  2. Warum benötigen wir asynchrone Verarbeitung? • Langläufige Prozesse auslagern •

    Reaktionszeit verkürzen • Verlagerung von Last • Microservices • Parallelisierung von Prozessen • Skalierbarkeit • Austausch von Nachrichten mit anderen (Sub-)Systemen
  3. Gearman • Gearman Job Server (in C geschrieben) • Läuft

    als Linux Daemon • PECL Extension für Worker API • Worker APIs für weiteren Sprachen (C, Perl,...)
  4. Gearman • PECL-Extension Version 1.1.2 von August 2013 • Letztes

    Server-Release von Anfang 2014 • Gefühlter Stillstand • Gearmand und Extension oftmals inkompatibel / instabil
  5. (PHP) Resque • Portierung von Resque: ◦ Resque is a

    Redis-backed Ruby library for creating background jobs, placing them on multiple queues, and processing them later. • Nutzt Redis(-Cluster) • Redis beherrscht atomare Transaktionen (FIFO)
  6. (PHP) Resque • Seit 2012 unregelmäßig Commits im Master, letzter

    2015-05-12 • chrisboulton/php-resque & michelsalib/BCCResqueBundle tot ?
  7. RabbitMQ • Message Broker in Erlang geschrieben • AMQP (Advanced

    Message Queuing Protocol) • Offenes, aber binäres Netzwerkprotokoll • Routing, Verteilen von Messages, etc. • Transaktionen • Weitere tolle Features ◦ TTL ◦ DLX (Dead Letter eXchange) ◦ PreFetching
  8. There is a Bundle for it • https://github.com/php-amqplib/RabbitMqBundle • Consumer

    und Producer werden zu Symfony-Services • Queue Consumer werden als Symfony Command ausgeführt • Konfiguration via app/config.yml ◦ Besser: app/config/rabbitmq.yml und in app/config/config.yml importieren
  9. Erfahrungen mit Consumern • PHP-Prozesse sind nicht für langläufige Prozesse

    gemacht ◦ Ungewohnte Probleme: Memory Leaks, ... • Mit Supervisor Consumer überwachen und neu starten lassen • Offene Datenbank-Verbindungen, ggf. Timeouts = Beendigung bei Inaktivät • Begrenzte Laufzeit pro Prozess (nach x Messages automatisch beenden) • Memory Limit: RabbitMQ-Bundle hat eine Art “Soft-Quota” • Anlaufen von Consumern dauert vergleichsweise lange • Prefetching (Achtung: Reihenfolge!)
  10. Message • Kompakte Messages, Queues fressen Storage / RAM •

    Allgemeines Format, z.B. JSON oder XML ◦ Keine serialisierten PHP Objekte oder Array, um langfristig Interoperabilität mit anderen System oder Sprachen zu gewährleisten
  11. Message Transformation • JMS/Serializer um Objekte nach JSON zu konvertieren

    ◦ Im Consumer JSON-formatierte Strings zurück in Objekte ◦ Objekte lassen sich dank Symfony Form und Asserts validieren ◦ Alternativ: PHPs JsonSerializable Interface ◦ Entities / Dokumente ggf. neu laden / aktualisieren (Unit of Work)
  12. Message Header • Message “Header” für Content-Type und Version ◦

    Messages könnten sich ändern, Consumer müssen kompatibel bleiben • Eindeutige IDs machen das Logging / Debugging / Leben einfacher • Weitere Metadaten: ◦ Zeitstempel ◦ User ◦ App ID, etc.
  13. Transaktionen • Messages werden immer exakt einem Consumer zugewiesen •

    Consumer muss explizit eine Nachricht mit “acknowledge” beantworten • Andernfalls wird Nachricht rejected (and ggf. requeued) ◦ Verwerfen heißt ggf. Datenverlust ◦ Requeuing - Achtung: ▪ könnte u.U. zu sog. Toxic Messages führen ▪ könnte die Reihenfolge der Messages verändern
  14. Toxic Messages • Wird eine Message nicht explizit beantwortet, landet

    sie wieder in der Queue • Wiederholt sich der Vorgang, haben wir eine Endlosschleife
  15. Dead Letter Exchange • RabbitMQ kennt daher die sog. Dead

    Letter Exchange (DLX) • Queue bestimmt eine DLX, eine weitere Queue, in der alle Messages landen, die zurückgewiesen wurden (Reject, TTL, Prefetch)
  16. Signal Handling • Graceful Shutdown • pcntl_signal / _dispatch •

    SIGTERM • FATAL ERROR abfangen • Logging • Toxic Message-Handling Shutdown
  17. Deployment • Consumer benötigen i.d.R. die aktuelle Code-Base • Consumer

    benötigen einen “graceful” Shutdown • Consumer sollten nur bei Inaktivät beendet werden ◦ Sonst Message/Daten - Verlust
  18. Und andere Herausforderungen • Maßgebliche Änderung der Infrastruktur ◦ Vorsicht

    bei der Partnerwahl / Abhängigkeit • Last verschoben ist nicht aufgehoben • Umdenken erforderlich ◦ Statusanzeige ◦ Zwischenstände ◦ Push statt Pull / Websockets • Abhängigkeiten von Messages ◦ Insbesondere bei Parallelisierung ! • Performance (insg. mit Doctrine ORM / ODM)