Mehrere kleine Programme, die über Sockets mit einem großen Programm verbunden sind

8

Ich bin am Anfang eines Projekts, bei dem von mehreren Sensoren gelesen und die Daten von diesen Sensoren zusammengeführt werden. Insgesamt werden 4 Sensoren über USB und eine Webcam, ebenfalls über USB, angeschlossen.

Einer meiner Kollegen ist sehr lautstark darüber, wie schön es ist, Programme in kleinere Teile aufzuteilen und sie über das Netzwerk kommunizieren zu lassen. Er schlägt vor, dass wir für jeden Sensor (oder jede Kamera) eine ausführbare Datei und dann eine zentrale Steuerungsanwendung haben sollten, die mit den anderen kommuniziert.

Ich mag diese Idee intuitiv nicht. Der betreffende Kollege arbeitete an einem anderen Projekt, das diesen Ansatz verwendete und endlose Probleme hatte, die schwer zu finden und zu debuggen waren.

Es scheint kein sehr staatliches Design zu sein und erscheint mir etwas unelegant. Ich möchte eine Bibliothek für den Umgang mit jedem Sensor schreiben und sie möglicherweise in separaten Threads ausführen.

Es sollte auch darauf hingewiesen werden, dass die Berechnungen, die wir durchführen müssen, Aktualisierungen für ein anderes System bei fast 1000 Hz liefern. Das Hinzufügen einer Ebene der Netzwerkkommunikation scheint einen potenziellen Engpass hinzuzufügen.

Es würde mich interessieren, die Meinungen anderer Leute dazu und vielleicht einige Hinweise zu dieser Art von Praxis zu hören.

James
quelle
9
" hatte kein Ende von Problemen, die schwer zu finden und zu debuggen waren " nicht sicher, ob eine Multithread-Lösung einfacher zu debuggen sein wird. Wenn Sie nicht sagen, dass Multithreading falsch ist, erinnern Sie sich nie daran, gehört zu haben: "Verwenden wir eine Lösung mit mehreren Threads, die so viel einfacher zu debuggen ist."
cdkMoose
3
Als häufiger Benutzer von Erlang ist diese "Verwendung des Netzwerks / Protokolls als grundlegende Abstraktionsebene" oft meine Standard-Denkweise. Es tut die Dinge einfacher zu debuggen (Sie können in Isolation komplettes Verhalten testen) und es macht ein System robuste (Kamera # 1 etwas in einem seltsamen Zustand kann nur Crash - Kamera # 1 Behandlungscode, und nichts anderes wartet auf diesem Code setzen) und macht das Hinzufügen eines Überwachungssystems einfach. Diese Eigenschaften sind sonst sehr schwer zu erreichen - aber andererseits könnte Ihr Problem wirklich trivial genug sein, dass nichts davon von Bedeutung ist.
zxq9
1
Wie läuft man überhaupt mit 1000Hz auf USB? Was genau sind Ihre Leistungsanforderungen? Betrachten Sie die Sockets als Latenz oder Durchsatzengpass?
Bergi
1
Warum brauchen Sie Ihrer Meinung nach ein "Stateful Design"? Sind Ihre Sensoren nicht ereignisbasiert?
Bergi
Ein Programmierer hatte ein Problem. Er dachte bei sich: "Ich weiß, ich werde es mit Fäden lösen!" . hat jetzt probleme. zwei er
Toby Speight

Antworten:

13

Ich mag diese Idee intuitiv nicht.

Intuitiv gefällt mir die Idee, Programme in kleinere Teile aufzuteilen. Wenn die verschiedenen Prozesse jedoch immer alle auf demselben Computer ausgeführt werden, ist die Netzwerkkommunikation wahrscheinlich nicht die optimale Form von IPC. Für die Hochgeschwindigkeitskommunikation zwischen Prozessen ist der gemeinsam genutzte Speicher möglicherweise die bessere Option. Unabhängig davon, für welchen Ansatz Sie sich entscheiden, müssen Sie die Leistung messen oder zumindest schätzen, bevor Sie Entscheidungen treffen.

Der betreffende Kollege arbeitete an einem anderen Projekt, das diesen Ansatz verwendete und endlose Probleme hatte, die schwer zu finden und zu debuggen waren.

Sie müssen überprüfen, welche Art von Problemen und wo die Hauptursachen waren. Wenn sie aufgrund von Parallelität Probleme hatten, werden Sie beim Versuch einer Multithread-Lösung auf dieselben Probleme stoßen (wenn nicht sogar mehr).

Stellen Sie Updates für ein anderes System mit fast 1000 Hz bereit

Wenn dies "hohe Geschwindigkeit" ist, hängt dies von der Geschwindigkeit der Produktionsmaschinen und der Größe des Betriebs ab, der mit jedem Update verbunden ist. Wenn es um Leistung geht, sind Bauchgefühle äußerst unzuverlässig. Sie müssen die Dinge messen . Wenn Ihr Kollege glaubt, dass sein Ansatz schnell genug sein wird und Sie glauben, dass dies nicht der Fall ist, muss mindestens einer von Ihnen seinen Glauben beweisen oder verfälschen. Zum Beispiel könnte einer von Ihnen einen kleinen Prototyp implementieren, um die Interprozesskommunikation zu simulieren und die Geschwindigkeit zu messen. Alles andere schaut in eine Glasschale.

Doc Brown
quelle
9

Sie können für Ihre Anwendung relevant sein oder nicht, aber einige Vorteile für die Multiprozesslösung, die Sie anscheinend nicht in Betracht gezogen haben, sind:

  • Feinkörnigere Berechtigungskontrolle. Sie können separate Berechtigungen für die Webcam und die anderen Sensoren haben.
  • Einfacher, Sensoren isoliert zu testen.
  • Einfacher, einen Sensor zur Laufzeit zu verspotten.
  • Es ist einfacher, Dritte dazu zu bringen, Code für ihre Sensoren zu schreiben, ohne Ihren Code öffnen zu müssen.
  • Verwendung von Tools wie Wireshark zur Fehlerbehebung sowohl während der Entwicklung als auch vor Ort.
  • Der einzige mir bekannte Kontext, in dem "stateful" als positives Attribut angesehen wird, besteht darin, dass die stateful-Teile eines Systems auf einen kleinen Bereich wie einen Schauspieler beschränkt sind , der das Design Ihres Kollegen mehr zu unterstützen scheint als das Ihre.
  • Es ist einfacher, eine Sperre aufzuheben und nur einen Sensorprozess neu zu starten, ohne das gesamte System neu starten zu müssen.
  • Kann einfach durch Hinzufügen von Hardware skaliert werden.
  • Die Socket-Kommunikation mit Quelle und Ziel auf demselben Computer ist relativ effizient.

Zusätzliche Nachteile der Multiprozesslösung:

  • Der Umgang mit Gegendruck ist komplexer.
  • Wenn Sie im Wesentlichen nur die Rohdaten von jedem Sensor ohne Filterung oder Verarbeitung weitergeben, haben Sie gerade Ihre Controller-Anwendung vom Lesen von einem USB-Treiber zum Lesen von einem Netzwerktreiber geändert, ohne dass die Abstraktion wirklich zunimmt.
Karl Bielefeldt
quelle
Wenn man eine Architektur verwendet, bei der jeder Socket eine Master- und eine Slave-Seite hat und jede Übertragung durch den Master eine sofortige Antwort des Slaves erzeugt (auch wenn die Antwort "noch nicht bereit" ist), wartet der Master immer auf die des Slaves Antwort, wäre Gegendruck ein Problem?
Supercat
Das wäre eine Möglichkeit, damit umzugehen, @supercat. Es ist nicht so, dass der Gegendruck nicht beherrschbar ist, es ist so, dass viele Leute ihn nicht im Voraus erklären, was das Design einfacher aussehen lässt, als es wirklich sein muss.
Karl Bielefeldt
8

Der Ansatz, den Ihr Kollege befürwortet, wird oft als Microservices-Architektur bezeichnet und ist heutzutage ziemlich im Trend. Es hat eine Reihe von potenziellen Vorteilen:

  • Skalierbarkeit: Durch einfaches Hinzufügen zusätzlicher Maschinen / VM-Instanzen kann die Skalierung relativ einfach gestaltet werden.
  • Robustheit: Mit einem geeigneten Design kann tolerant gemacht werden, dass einzelne Microservice-Prozesse abstürzen, die Konnektivität verlieren oder auf andere Weise nicht mehr verfügbar sind.
  • Erweiterbarkeit: Die Verwendung von Standard-Webtechnologien für die Schnittstelle zwischen Mikrodiensten (normalerweise http-REST-Anforderungen mit Json- oder XML-Antworten) kann es Dritten oder Kunden relativ einfach machen, eine Schnittstelle zu Ihrem System herzustellen und es für ihre eigenen Anforderungen zu erweitern.

Es hat auch eine Reihe von Nachteilen:

  • Leistung: Im Allgemeinen zahlen Sie Leistungskosten für die Kommunikation zwischen Prozessen. Dies kann sehr wichtig sein, wenn Sie APIs im http-REST-Stil erstellen.
  • Komplexität: Normalerweise benötigen Sie eine Menge zusätzlichen Code, um Daten zwischen Prozessen zu marshallen, anstatt nur Daten zwischen Threads in einem einzelnen Prozess weiterzugeben. Sie werden auch Abhängigkeiten von Bibliotheken für die Netzwerkkommunikation, die http-Unterstützung usw. einführen.
  • Debuggbarkeit: Das Debuggen einer Anwendung, die aus mehreren unabhängigen Kommunikationsprozessen besteht, ist in der Regel komplexer als die Verwendung des integrierten Debuggers einer IDE für einen einzelnen Prozess.

Ich bin mir nicht ganz sicher, was Sie meinen, wenn Sie sagen, dass das Design "nicht wie ein sehr staatliches Design erscheint". Im Allgemeinen wird "zustandsvoll" als schlechtes Merkmal eines Entwurfs angesehen, und "zustandslose" Mikrodienste werden als gutes Entwurf angesehen.

Angesichts der Informationen zu Ihren Anforderungen, die Sie in Ihrem Beitrag angeben, denke ich, dass ein auf Microservices basierendes Design für Ihren Anwendungsfall übertrieben wäre und die Vorteile die zusätzliche Komplexität nicht rechtfertigen würden. Die Vorteile von Microservices-Architekturen kommen in der Regel nur dann zum Tragen, wenn größere Webdienste erstellt werden, bei denen Skalierbarkeit, Robustheit und Erweiterbarkeit im Vordergrund stehen.

Die potenziellen Vorteile einer Microservices-Architektur werden auch nur mit einem durchdachten Design realisiert. Meiner Meinung nach erfordert eine solche Architektur mehr Vorabentwurf (insbesondere wenn es um das Protokoll für die Kommunikation zwischen Mikrodiensten geht) als ein Einzelprozessentwurf, um das vorliegende Problem erfolgreich zu lösen.

mattnewport
quelle
1
"Normalerweise benötigen Sie eine Menge zusätzlichen Code, um Daten zwischen Prozessen zu sammeln, anstatt nur Daten zwischen Threads in einem einzigen Prozess weiterzugeben." Hier gibt es jedoch einen Kompromiss zwischen der Menge an Code, die Sie schreiben, um zu übergeben Nachrichten im Vergleich zu der Einfachheit des Designs , die Sie durch (z. B.) die Kommunikation sequentieller Prozesse erhalten. Wenn Sie das CSP-Design "richtig" machen, muss es nicht unbedingt einen Unterschied machen, ob die Komponenten separate Threads im selben Prozess oder separate Prozesse sind, da sie in beiden Fällen dieselbe Nachrichtenschnittstelle mit unterschiedlichen Implementierungen verwenden.
Steve Jessop
So fügen Sie auf, was @SteveJessop sagt über die Serialisierung / Rangier - dies gemacht werden kann , sehr effizient später einmal die Leistungsmerkmale des Systems verstanden werden . Der häufigste Fall von "Äh, Netzwerke / Sockets sind schwierig, verwenden wir HTTP und XML" ist fast der schlimmste Fall und kann erheblich verbessert werden - aber den meisten von uns ist bekannt genug, dass dies eine großartige Möglichkeit ist, ein System zu hacken zusammen funktioniert das jetzt . Etwas zu optimieren, das funktioniert (und daher bereits messbar ist), ist viel besser als zu versuchen, ein Design zu beheben, das in der Praxis noch nicht existiert.
zxq9