Was ist besser für lokale IPC, POSIX-Nachrichtenwarteschlangen (mqueues) oder (lokale) Unix-Domain-Sockets?

Lesezeit: 5 Minuten

Ist es besser, POSIX-Nachrichtenwarteschlangen oder Unix-Domain-Sockets für die lokale IPC-Kommunikation zu verwenden?

Ich habe mit Unix-Sockets zwischen Maschinen (nicht Domänen) gearbeitet und ich erinnere mich, dass das Herstellen und Unterbrechen der Verbindung dazu führen würde, dass Sockets eine Weile verweilen, bevor sie endgültig verschwinden. Wenn Sie einen “zuverlässigen” Austausch wünschen, müssen Sie außerdem entweder TCP verwenden oder die Anwendung so gestalten, dass sie ein ACK zurückgibt. Ich bin mir jedoch nicht sicher, ob dies auch für Unix-Domain-Sockets gilt.

In meinem aktuellen Projekt benötigen wir einen lokalen IPC. Meine erste Reaktion war die Verwendung von POSIX MQueues, da ich sie zuvor für lokales Messaging verwendet habe. Ein Kollege schlägt jedoch stattdessen Unix-Domain-Sockets vor.

Ist das eine besser als das andere oder ist es eine Frage der Programmierkenntnisse? Oder vielleicht hängt es von der Anwendung ab, die erstellt wird?

Im Großen und Ganzen folgt die Anwendung, an der wir arbeiten, einem Client/Server-Modell. Die Clients senden Nachrichten an den Server, um “etwas zu tun”. Der Client wartet jedoch nicht auf eine „Ist erledigt“-Antwort – obwohl er wissen möchte, ob seine Anfrage eingegangen ist oder nicht.

Die grundlegende Logik für die Sendeseite lautet:

connect to server
send request
note if the send worked or not
disconnect from server

Es können Hunderte von Clients zu einem Server gehören.

Wir führen ein SMP-System (4-8 Kerne) aus, auf dem das Linux-Betriebssystem ausgeführt wird.

Danke im Voraus.

UNIX-Domain-Sockets müssen nicht in a “verweilen”. TIME_WAIT-ähnlicher Status, da diese Wartezeit verwendet wird, falls Streupakete von der Verbindung noch im Internet herumwandern. Die Sorge gilt nicht lokal.

UNIX-Domain-Sockets können beides sein SOCK_STREAM (wie TCP) oder SOCK_DGRAM (wie UDP), mit der zusätzlichen Garantie, dass UNIX-Domain-Datagramm-Sockets zuverlässig sind und Datagramme nicht neu anordnen.

Sie benötigen immer noch eine Art ACK (das tun Sie sogar mit TCP), wenn Sie möchten sicher dass Ihre andere Anwendung die von Ihnen gesendete Nachricht gelesen hat; immerhin, auch wenn die send() erfolgreich ist, kann es sein, dass es abgestürzt ist, bevor es die Möglichkeit hatte, die Nachricht zu verarbeiten. (Dies gilt auch für Nachrichtenwarteschlangen – um absolut sicher zu sein, dass eine Nachricht nicht verloren geht, muss die empfangende Anwendung die Anforderung in ein Journal schreiben, dieses auf die Festplatte löschen und dann eine Bestätigung zurücksenden).

Ich stimme zu, dass die Wahl im Wesentlichen eine Frage der Programmiervertrautheit ist.

Benutzer-Avatar
Dummy00001

Ist das eine besser als das andere oder ist es eine Frage der Programmierkenntnisse? Oder vielleicht hängt es von der Anwendung ab, die erstellt wird?

SysV-Nachrichtenwarteschlangen im Vergleich zu UNIX-Domänen-Datagramm-Sockets weisen die mir bekannten Hauptunterschiede auf:

  • Du kannst poll() Socket, aber Sie können keine Nachrichtenwarteschlange verwenden.

  • Die Nachrichtenwarteschlange ist global und erfordert möglicherweise (und tut dies normalerweise) einige administrative Eingriffe: Das Bereinigen alter hängender SysV-Ressourcen ist eine der vielen täglichen Routinen von Sysadmins. Während die Semantik der UNIX-Domäne viel einfacher ist und Anwendungen sie im Allgemeinen vollständig intern ohne Beteiligung des Systemadministrators verwalten können.

  • (?) Die Nachrichtenwarteschlange ist dauerhaft, sie behält möglicherweise Nachrichten aus den alten Sitzungen. (Ich kann mich nicht genau daran erinnern, aber IIRC, das ist mir mehr als einmal passiert).

  • Mit Blick auf die man msgrcv Ich sehe keine analogen Steckdosen MSG_PEEK. Selten benötigt, aber manchmal ganz praktisch.

  • Meistens ziehen es Benutzer vor, in der Konfiguration symbolische Namen zu verwenden, nicht die numerische Schlüssel-ID. Mangel an symbolischen Schlüsseln IMO ist ein ziemlich schwerwiegendes Versehen seitens der Designer der SysV-Schnittstelle.

Wie bei allen SysV-Ressourcen ist ihre Verwaltung die Haupt-PITA. Wenn Sie die Nachrichtenwarteschlangen-ID vom System entscheiden lassen, müssen Sie dafür sorgen, dass sie ordnungsgemäß mit anderen Anwendungen geteilt wird. (Und Sie müssen den Admins auch irgendwie sagen, dass die ID irgendwann entfernt werden muss). Wenn Sie zulassen, dass der Schlüssel für die Nachrichtenwarteschlange konfiguriert wird, treten möglicherweise triviale Probleme auf, da die ID bereits von einer Anwendung verwendet wird oder ein Überbleibsel des vorherigen Laufs ist. (Dass Server nur neu gestartet werden, weil ihnen die SysV-Ressourcen ausgehen, ist ziemlich üblich.)

Alles in allem vermeide ich SysV-Ressourcen, wenn möglich: Mangel an poll() Support ist in den meisten Fällen ein Deal Breaker.

Der Client wartet jedoch nicht auf eine „Ist erledigt“-Antwort – obwohl er wissen möchte, ob seine Anfrage eingegangen ist oder nicht.

Das ist ein häufiges Dilemma der Transaktionsverarbeitung. Allgemeine Antwort ist (wie in RDBMSs), dass Sie nicht können und nach einer Kommunikationsunterbrechung (Absturz oder was auch immer) die Anwendung selbst überprüfen muss, ob die Anfrage bereits verarbeitet wurde oder nicht.

Daraus kann ich erkennen, dass TCP wahrscheinlich die bessere Wahl wäre. Der Client sendet die Anfrage und erklärt sie erst dann für beendet, wenn er eine positive Antwort vom Server erhält. Der Server muss die Transaktion rückgängig machen, es sei denn, er kann die Antwort an den Client senden.

  • Unter Linux ist ein Posix-Nachrichtenwarteschlangen-Deskriptor jedoch eigentlich ein Dateideskriptor und unterstützt select/poll. Bei Sysv-Nachrichtenwarteschlangen bin ich mir nicht sicher.

    – Nr

    23. September 2010 um 10:03 Uhr


  • @nos: Referenz? Mischen Sie es nicht mit AIX? POSIX beschreibt das und das nicht alte Linux-Referenz, die ich kenne sagt auch nein.

    – Dummy00001

    23. September 2010 um 10:08 Uhr

  • man mq_overview, “Unter Linux ist ein Nachrichtenwarteschlangen-Deskriptor eigentlich ein Dateideskriptor und kann mit select(2), poll(2) oder epoll(7) überwacht werden. Dies ist nicht portierbar.” , wie bereits erwähnt, handelt es sich um Posix-Nachrichtenwarteschlangen. Ich bin mir nicht sicher, ob sysv-Nachrichtenwarteschlangen so funktionieren, wenn sie dies tun, hat sich dies in den letzten Jahren geändert.

    – Nr

    23. September 2010 um 10:29 Uhr


  • @nos: danke. Das erklärt, warum es zwei Schnittstellen gibt. Das mq_* Funktionen ist die neue POSIX-Schnittstelle: “Erstmals in Ausgabe 5 veröffentlicht. Zur Anpassung an die POSIX Realtime Extension enthalten.” Und doch definiert die POSIX nicht die Verwendung von poll() mit den “message queue descriptors” … 🙁

    – Dummy00001

    23. September 2010 um 10:44 Uhr


Ich würde vorschlagen, DBus nach einer solchen Anwendung zu suchen, und sei es nur wegen ihrer Datenmarshalling und RPC-ähnlichen Schnittstelle (sowohl synchron als auch asynchron). Es verwendet nativ Domain-Sockets und funktioniert nach einer anfänglichen Lernkurve sehr gut.

1362980cookie-checkWas ist besser für lokale IPC, POSIX-Nachrichtenwarteschlangen (mqueues) oder (lokale) Unix-Domain-Sockets?

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

Privacy policy