Ouvir / notificar como fila de mensagens do Postgres

17

Existe alguma maneira de usar o recurso Ouvir / Notificar do Postgres para entregar uma mensagem a um canal e ter apenas um ouvinte consumindo essa mensagem?

O objetivo é que eu tenha vários aplicativos de trabalho, todos ouvindo o mesmo canal do Postgres. Mas eu quero apenas o trabalho uma vez por mensagem recebida pelo canal de notificação.

Se Listen / Notify não é o recurso correto no Postgres, existe um recurso separado que eu deveria estar usando?

Idealmente, eu gostaria de fazer isso sem usar extensões adicionais.

moesef
fonte

Respostas:

23

De acordo com a documentação do PostgreSQL sobreNOTIFY :

O comando NOTIFY envia um evento de notificação junto com uma sequência opcional de "carga útil" para cada aplicativo cliente que executou anteriormente o canal LISTEN para o nome do canal especificado no banco de dados atual. As notificações são visíveis para todos os usuários .

(ênfase minha)

Isso significa que você não pode fazer o que deseja apenas com LISTEN/NOTIFY . No entanto, você pode ter uma tabela para armazenar mensagens na fila, LISTEN/NOTIFYpara notificar aplicativos externos de que "há coisas novas na fila de mensagens" e usar alguma lógica extra desses aplicativos externos para que apenas um consuma a mensagem.

A estratégia descrita no artigo O que é SKIP LOCKED no PostgreSQL 9.5? é provavelmente a maneira mais segura / fácil de implementar uma fila de mensagens no PostgreSQL. Preste atenção especial à parte "Como o SKIP LOCKED ajuda". Leia também cuidadosamente uma de suas advertências:

Uma fila implementada no RDBMS nunca corresponderá ao desempenho de um sistema de fila dedicado rápido, mesmo que garanta a mesma atomicidade e durabilidade que o PostgreSQL. O uso do SKIP LOCKED é melhor do que as abordagens existentes no banco de dados, mas você continuará mais rápido usando um mecanismo de enfileiramento externo dedicado e altamente otimizado.

Isso é especialmente importante se o volume da fila for alto.

joanolo
fonte
1
Eu gostaria de poder conceder uma recompensa ao autor desse artigo. Tão extremamente útil.
Curinga
3

Eu fiz algo assim há um bom tempo, usei o RabbitMQ e este plugin https://github.com/gmr/pgsql-listen-exchange

Basicamente, o RabbitMQ se conecta ao PostgreSQL e escuta o evento de notificação, então você pode usar o RabbitMQ para agregar essa mensagem a quantas filas forem necessárias e ter um aplicativo consumindo cada fila

Phill Pafford
fonte