Postgres Anhören / Benachrichtigen als Nachrichtenwarteschlange

17

Gibt es eine Möglichkeit, Postgres Listen / Notify-Funktion zu verwenden, um eine Nachricht an einen Kanal zu übermitteln, und nur ein Listener diese Nachricht zu konsumieren?

Der Grund dafür ist, dass ich mehrere 'Worker'-Apps habe, die alle denselben Postgres-Kanal hören. Aber ich möchte, dass die Arbeit nur einmal pro Nachricht über den Benachrichtigungskanal erledigt wird.

Wenn Listen / Notify nicht die richtige Funktion in Postgres ist, gibt es eine separate Funktion, die ich verwenden sollte?

Idealerweise möchte ich dies ohne zusätzliche Erweiterungen tun.

moesef
quelle

Antworten:

23

Laut PostgreSQL-Dokumentation überNOTIFY :

Der Befehl NOTIFY sendet ein Benachrichtigungsereignis zusammen mit einer optionalen "Payload" -Zeichenfolge an jede Clientanwendung, die zuvor den Kanal LISTEN für den angegebenen Kanalnamen in der aktuellen Datenbank ausgeführt hat. Benachrichtigungen sind für alle Benutzer sichtbar .

(Hervorhebung von mir)

Das heißt, Sie können nicht einfach mit dem tun, was Sie wollen LISTEN/NOTIFY. Sie können jedoch sowohl eine Tabelle zum Speichern von Nachrichten LISTEN/NOTIFYin der Warteschlange als auch zum Benachrichtigen externer Anwendungen über "die Nachrichtenwarteschlange enthält neue Elemente" und einige zusätzliche Logik dieser externen Anwendungen verwenden, sodass nur eine die Nachricht verarbeitet.

Die in diesem Artikel beschriebene Strategie Wofür ist SKIP LOCKED in PostgreSQL 9.5? ist wahrscheinlich der sicherste / einfachste Weg, eine Nachrichtenwarteschlange in PostgreSQL zu implementieren . Achten Sie besonders auf den Teil "Wie SKIP LOCKED hilft". Lesen Sie auch sorgfältig einen ihrer Vorbehalte:

Eine im RDBMS implementierte Warteschlange wird niemals mit der Leistung eines schnellen dedizierten Warteschlangensystems mithalten können, selbst wenn dieses die gleichen Atomaritäts- und Haltbarkeitsgarantien wie PostgreSQL bietet. Die Verwendung von SKIP LOCKED ist besser als die Verwendung bestehender datenbankinterner Ansätze, Sie können jedoch mithilfe einer dedizierten und hochoptimierten externen Warteschlangen-Engine schneller vorgehen.

Dies ist besonders wichtig, wenn das Warteschlangenvolumen hoch ist.

joanolo
quelle
1
Ich wünschte, ich könnte dem Autor dieses Artikels ein Kopfgeld gewähren. Also sehr hilfreich.
Wildcard
3

Ich habe so etwas vor einiger Zeit mit gutem Erfolg gemacht. Ich habe RabbitMQ und dieses Plugin https://github.com/gmr/pgsql-listen-exchange verwendet

Grundsätzlich stellt RabbitMQ eine Verbindung zu PostgreSQL her und wartet auf das Benachrichtigungsereignis. Anschließend können Sie RabbitMQ verwenden, um diese Nachricht in so viele Warteschlangen wie erforderlich zu aggregieren und eine App für jede Warteschlange bereitzustellen

Phill Pafford
quelle