Ankündigung

Einklappen
Keine Ankündigung bisher.

Frontend-Backend-Kommunikation, wie?

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Frontend-Backend-Kommunikation, wie?

    Moin!

    Ich arbeite an einem dezentralen sozialen Netzwerk auf Basis von PHP und MySQL. Für Hintergrundtätigkeiten haben wir sogenannte "Worker", dies sind PHP-Kommandozeilen-Jobs, die vom Frontend oder von anderen Workern aus gestartet wurden. Ich möchte dies gerne in Zukunft ändern.

    Mir schwebt ein Design vor, bei dem ein- oder mehrere Frontend-Server einem Daemon auf dem Backend-Server Bescheid geben, dass ein weiterer Worker gestartet werden soll, bzw. neue Jobs zum Abbarbeiten anstehen.

    Wie könnte man dies realisieren? Die Voraussetzung ist auch, dass es mit Standard-PHP (ab 7) gehen muss und keine zusätzlichen Bibliotheken verwendet werden. Es muss natürlich auch auf einem einzelnen Server laufen, es sollte aber die Option geben, dass es auf mehreren Servern läuft.

    Wichtig wäre mir etwas, das nicht per Polling auf der normalen Datenbank arbeitet.


  • #2
    In der Regel verwendet man hierfür Message Queues (Stichwort MOM). Je nach Implementierung der Message Queue kann somit auch recht einfach Load-Balancing mit dem Round-Robin Verfahren betrieben werden.

    Aber ohne zusätzliche Datenbank oder Bibliotheken wird das ganze nichts, zumindest nicht dezentral. Da müsstest du dann Interprozess-Kommunikation o.ä. nutzen.
    "Software is like Sex, it's best if it's free." - Linus Torvalds

    Kommentar


    • #3
      Wir haben bereits ein entsprechendes System, das die Aufträge in eine Queue schiebt und das diese Aufträge dann last- und prioritätsabhängig auf die einzelnen Worker verteilt. Dementsprechend geht es mir eher darum, wie ich in das bestehende System eine Kommunikation zwischen Dämon und Frontend aufbauen kann, bei der das Frontend dem Dämon zeitnah mitteilen kann, dass neue Jobs anstehen. Das soll aus naheliegenden Gründen nicht per sekündlichem Pollen der Datenbank geschehen.

      Kommentar


      • #4
        Warum sollte denn das Frontend dem Dämon mitteilen dass "zeitnah" neue Jobs anstehen? Das Ziel der Queue ist doch gerade die Entkopplung deines Frontends von den Workern.
        Oder meinst du damit dass eure Queue atm. mit Polling abgefragt wird (bzw. du das vermeiden möchtest) und du eine Alternative dafür suchst? Die praktikabelste Alternative dürfte hierfür dann Publish-Subscribe bzw. das Observer-Pattern sein.
        "Software is like Sex, it's best if it's free." - Linus Torvalds

        Kommentar


        • #5
          Es ist ja ein soziales Netzwerk. D.h. nach dem Verfassen eines Beitrags/Kommentars soll dieser möglichst schnell auf die Zielserver der Kontakte verteilt werden. Dementsprechend ist eine zeitnahe Mitteilung sinnvoll. Im Moment wird die Queue vom Frontend gestartet, was unsauber ist. Ich habe jetzt einen ersten Prototypen fertiggestellt, der die Kommunikation über eine kleine Tabelle auf dem MySQL-Server durchführt, die als Engine-Typ "Memory" ist. Diese Tabelle enthält grundsätzlich einen Datensatz mit einem boolschen Wert. Der wird auf "true" gesetzt, sobald der Dämon neue Prozesse starten soll. Der Dämon fragt diese Tabelle sekündlich ab (dies sollte ja keine I/O-Probleme erzeugen und das System nicht sonderlich belasten) und dann ggf. einen Worker forken.

          Es geht sicherlich eleganter, allerdings ist die Funktionalität ausreichend gekapselt, so dass wir sie jederzeit durch andere Methoden ersetzen können, außerdem ist das gesamte System so ausgelegt, dass sie sehr leicht zu installieren und administrieren ist. Da können wir uns leider keine komplexen Lösungen erlauben.

          Kommentar


          • #6
            Verstehe ich richtig, dass jeder Kontakt in dem sozialen Netzwerk dann ein Knotenpunkt in dem Netzwerk ist und entsprechend seine eigenen Daemons hat?
            Dann könntest du doch auch einfach Interprozess-Kommunikation nutzen (respektive Shared Memory): https://www.ibm.com/developerworks/l...ory/index.html
            "Software is like Sex, it's best if it's free." - Linus Torvalds

            Kommentar


            • #7
              Ein Server kann hunderte von Usern haben, aber pro Server läuft nur ein Dämon. Insgesamt besteht das Netzwerk derzeit aus über 300 Servern, die auf der gesamten Welt verteilt sind. Shared Memory hatte ich mir schon bei der Kommunikation der Worker untereinander überlegt - aber nicht in diesem Schritt.

              Kommentar


              • #8
                Ich versteh nur immer noch nicht warum du ein Flag brauchst um dem Worker Bescheid zu geben, dass die Queue befüllt wurde. Das kann dieser doch selber überprüfen und dann entsprechend anfangen diese abzuarbeiten?
                Ob du jetzt einen Count auf die Queue-Tabelle ausführst oder ein Flag ausliest macht doch keinen Unterschied. Nur dass du beim einfügen in die Queue die unnötige Arbeit hast, dieses Flag zu setzen und anschließend wieder das Flag zu entfernen wenn die Queue abgearbeitet wurde.

                Um deiner eingangs definierten Bedingung "[...] das nicht per Polling auf der normalen Datenbank arbeitet" zu genügen, müsstest du mit SharedMemory arbeiten (d.h. du legst die Queue in den SharedMemory).
                "Software is like Sex, it's best if it's free." - Linus Torvalds

                Kommentar


                • #9
                  Das sekündliche Pollen der "echten" Tabelle in der Datenbank würde unnötig I/O-Last erzeugen. Das gesamte System ist auf Performance optimiert. Das Flag in einer "Memory"-Tabelle erzeugt dagegen keine I/O-Last. Die Queue-Tabelle selber würde ich nie in eine Speicher-basierte Datenbank legen. Ich bevorzuge robuste Systeme, die auch einen Neustart ohne Datenverlust überstehen.

                  Kommentar


                  • #10
                    Die I/O Last bei einer sekündlichen Abfrage hält sich in Grenzen. Vorallem wenn es sowieso nur eine kleine Queue-Tabelle ist. Für Situationen in denen keine Einträge in der Queue-Table vorliegen greift dann der Query Cache (insofern natürlich konfiguriert), wird also auch aus dem Arbeitsspeicher geladen.

                    Und was machst du z.B. wenn der Worker das Flag auf False setzt, obwohl das Frontend gerade Datensätze eingefügt hatte und auf True gesetzt hatte? Dann würden die Einträge erstmal nicht abgearbeitet werden.
                    "Software is like Sex, it's best if it's free." - Linus Torvalds

                    Kommentar

                    Lädt...
                    X