Verwenden von POSIX-Nachrichtenwarteschlangen anstelle von TCP-Sockets – wie wird eine “Verbindung” hergestellt?

Lesezeit: 5 Minuten

Ich habe Client- und Serverprogramme, die jetzt über TCP kommunizieren. Ich probiere stattdessen die Verwendung von POSIX-Nachrichtenwarteschlangen aus (natürlich in Fällen, in denen sich Client und Server auf derselben Maschine befinden). Meine Hoffnung ist, dass es die Leistung verbessert (insbesondere durch reduzierte Latenz).

Ich habe das meiste herausgefunden, bin mir aber bei einer Sache nicht sicher: wie man die “Verbindung” herstellt. Der Server akzeptiert gleichzeitig Verbindungen von mehreren Clients, daher bin ich versucht, den TCP-Verbindungsaufbauprozess wie folgt zu emulieren:

  1. Der Server öffnet eine Warteschlange mit einem bekannten Namen und liest kontinuierlich daraus (er kann verwenden select(2) wie bei TCP).
  2. Der Client öffnet drei Warteschlangen: zwei mit beliebigen Namen (einschließlich einiger Eindeutigkeiten wie PID, um Kollisionen zu vermeiden) und eine mit dem bekannten Namen, der vom Server verwendet wird.
  3. Der Client sendet eine “Verbinden”-Nachricht an die Warteschlange des Servers, einschließlich der Warteschlangennamen des Clients (einer ist für den Client-zu-Server-Verkehr bestimmt und der andere für das Gegenteil).
  4. Der Server öffnet die in der Verbindungsnachricht des Clients genannten Warteschlangen und beginnt mit dem Lesen (Auswählen) aus der Client-zu-Server-Warteschlange.
  5. Der Client schließt die Serverwarteschlange mit dem bekannten Namen. Die bidirektionale Kommunikation wird unter Verwendung der beiden vom Client benannten Warteschlangen (eine für jede Richtung) fortgesetzt.

Sie können wahrscheinlich erkennen, dass dieses Schema der üblichen TCP-Methode ähnelt, und das ist kein Zufall. Allerdings würde ich gerne wissen:

  1. Können Sie sich einen besseren Weg vorstellen, dies zu tun?
  2. Sehen Sie mögliche Probleme mit meiner Methode?
  3. Haben Sie noch andere Gedanken, einschließlich der Wahrscheinlichkeit, dass die Verwendung von Nachrichtenwarteschlangen anstelle von TCP auf demselben Computer die Leistung (Latenz) tatsächlich verbessert?

Denken Sie daran, dass ich zuvor noch keine POSIX-Nachrichtenwarteschlangen verwendet habe (ich habe vor einiger Zeit IBM WebSphere MQ verwendet, aber das ist ziemlich anders). Die Plattform ist Linux.

Benutzeravatar von Philluminati
Philluminati

  1. Können Sie sich einen besseren Weg vorstellen, dies zu tun?

    Vielleicht werfen Sie einen Blick auf Fifos (alias Named Pipes). Sie sind wie Netzwerk-Sockets, aber für den lokalen Rechner. Sie sind unidirektional, daher müssen Sie möglicherweise zwei erstellen, einen für jede Richtung. Ihre Frage entbehrt jeglicher Begründung warum Sie nehmen diese Änderung ausdrücklich vor. Es ist nichts falsch daran, Sockets für die Kommunikation von Prozess zu Prozess zu verwenden. Sie sind bidirektional, effizient, umfassend unterstützt und geben Ihnen die Freiheit, die Prozesse später zwischen den Maschinen zu trennen.

  2. Sehen Sie mögliche Probleme mit meiner Methode?

    System V-Nachrichtenwarteschlangen und Fifo-Named Pipes sind beide absolut in Ordnung. Fifo-Pipes sind wie normale Pipes, sodass Sie mit minimalen Codeänderungen lesen () und schreiben () können. System V-Nachrichtenwarteschlangen erfordern das Einfügen der Daten in eine Struktur und das Aufrufen von msgsnd(). Beide Ansätze wären jedoch in Ordnung.

  3. Haben Sie noch andere Gedanken, einschließlich der Wahrscheinlichkeit, dass die Verwendung von Nachrichtenwarteschlangen anstelle von TCP auf demselben Computer die Leistung (Latenz) tatsächlich verbessert?

    Meine anderen Gedanken sind, dass Sie, wie Sie sagten, eine Technik entwickeln müssen, damit jeder Client eine eindeutige Kennung hat. Ein Ansatz wäre, die PID zu der Struktur hinzuzufügen, die Sie übergeben, oder zu Beginn eine eindeutige ID mit dem Elternteil / Master auszuhandeln. Beachten Sie außerdem, dass der Vorteil von System V-Nachrichtenwarteschlangen darin besteht, dass Sie auf “selektive” Nachrichten warten, sodass Sie idealerweise eine Warteschlange vom Server zu allen Clients verwenden können, wobei jeder Client auf eine andere Nachricht wartet.

    Ich habe keine Ahnung, welche Technik Ihnen den optimalen Durchsatz in Ihrer Software bietet. Es lohnt sich vielleicht wirklich nicht, System V-Nachrichtenwarteschlangen zu verwenden, aber nur Sie können diese Entscheidung treffen.

Philluminati

  • Sie sagen meiner “Frage fehlt jeder Grund, warum Sie diese Änderung vornehmen”. Ich habe es erwähnt: Leistung (Latenz). Unterscheiden sich System V-Nachrichtenwarteschlangen in der Funktionalität von POSIX-Nachrichtenwarteschlangen? Die von mir verwendeten POSIX-Systeme (z. B. mq_open(3)) scheinen die von Ihnen erwähnten “selektiven” Nachrichten nicht zu unterstützen.

    – Johannes Zwinck

    4. Januar 2009 um 3:59 Uhr

  • Ich habe jetzt versucht, benannte Pipes zu verwenden. Sie sind langsamer (zumindest für die Weiterleitung vieler kleiner Nachrichten) als POSIX-Nachrichtenwarteschlangen.

    – Johannes Zwinck

    5. Januar 2009 um 16:41 Uhr

Am Ende habe ich es im Grunde so implementiert, wie ich es beschrieben habe, mit ein paar Verbesserungen:

  • In Schritt 2 habe ich GUIDs für die Warteschlangennamen verwendet, anstatt die PID des Clients einzubeziehen.
  • In Schritt 4 habe ich das Senden einer „Akzeptieren“-Nachricht vom Server zum Client hinzugefügt.
  • Wenn eine Seite die Kommunikation beenden möchte, sendet sie eine “Disconnect”-Nachricht.

Das Handshaking ist einfacher als TCP, scheint aber ausreichend zu sein.

Was die Latenz betrifft: Es ist viel besser. Etwa 75 % weniger Latenz bei Verwendung von POSIX-Nachrichtenwarteschlangen anstelle von TCP auf derselben Maschine. Meine Nachrichten sind jeweils in der Größenordnung von 100 Bytes.

Benutzeravatar von lxyfirst
lxyfirst

Ich habe die Leistung von posix MQ und einem Paar TCP/IP-Sockets verglichen.

Das Demoprogramm hat zwei Threads, einen zum Schreiben und einen zum Lesen.

Das Ergebnis ist, dass posix MQ schneller ist,

  • MQ 460000 tps
  • Steckdosenpaar 400000 tps

Ich bin auf ein ähnliches Problem gestoßen, ich entwickle Echtzeitanwendungen und benötige eine IPC-Technik mit ähnlicher Socket-Funktionalität und minimaler Latenz.

Haben Sie Ihre POSIX-MQ-basierte Lösung nur mit lokalen UNIX-Sockets oder TCP-Sockets verglichen?

Vielen Dank

Wie haben Sie das gemacht, wenn select() bei Nachrichtenwarteschlangen nicht funktioniert? Was ist Sys V oder POSIX? Warum den zusätzlichen Aufwand beim Erstellen einer GUID-zu-PID-Nachschlagetabelle betreiben, wenn die PID garantiert eindeutig ist und kleinerer Speicher (ganzzahlig) ist?

/blee/

  • Dies sollte wirklich ein Kommentar zu meiner Antwort sein. Wie auch immer: Select funktioniert mit POSIX-Nachrichtenwarteschlangen, die ich verwende. Es gibt keine GUID-zu-PID-Nachschlagetabelle – die GUID wird zwischen den Prozessen kommuniziert und die PID wird nie verwendet. PIDs sind nicht eindeutig – sie werden auf den meisten Systemen wiederverwendet.

    – Johannes Zwinck

    17. Februar 2009 um 23:29 Uhr

Benutzeravatar von gst
gst

Sie können Message Queues für IPC auch in Programmen verwenden, die sich auf verschiedenen Computern befinden, in solchen Fällen können Sie ZeroMQ verwenden (http://www.zeromq.org) oder andere Nachrichtenwarteschlangen-APIs, empfehle ich Ihnen auch, sie in Betracht zu ziehen und sie auch zu testen.

  • Dies sollte wirklich ein Kommentar zu meiner Antwort sein. Wie auch immer: Select funktioniert mit POSIX-Nachrichtenwarteschlangen, die ich verwende. Es gibt keine GUID-zu-PID-Nachschlagetabelle – die GUID wird zwischen den Prozessen kommuniziert und die PID wird nie verwendet. PIDs sind nicht eindeutig – sie werden auf den meisten Systemen wiederverwendet.

    – Johannes Zwinck

    17. Februar 2009 um 23:29 Uhr

1432340cookie-checkVerwenden von POSIX-Nachrichtenwarteschlangen anstelle von TCP-Sockets – wie wird eine “Verbindung” hergestellt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy