Postgres Прослушать / Уведомить как очередь сообщений

17

Есть ли способ использовать функцию прослушивания / уведомления Postgres для доставки сообщения на канал, и только один слушатель может использовать это сообщение?

Цель этого заключается в том, чтобы у меня было несколько «рабочих» приложений, которые все слушали один и тот же канал Postgres. Но я хочу, чтобы работа выполнялась только один раз для каждого сообщения, полученного через канал уведомлений.

Если функция прослушивания / уведомления не является правильной функцией в Postgres, есть ли отдельная функция, которую я должен использовать?

В идеале я хотел бы сделать это без использования каких-либо дополнительных расширений.

moesef
источник

Ответы:

23

Согласно документации PostgreSQL оNOTIFY :

Команда NOTIFY отправляет событие уведомления вместе с необязательной строкой «полезной нагрузки» каждому клиентскому приложению, которое ранее выполняло канал LISTEN для указанного имени канала в текущей базе данных. Уведомления видны всем пользователям .

(акцент мой)

Это означает, что вы не можете делать то, что вы хотите просто с LISTEN/NOTIFY . Однако у вас может быть как таблица для хранения сообщений в очереди, так и LISTEN/NOTIFYдля уведомления внешних приложений о том, что « в очереди сообщений есть что-то новое», и использование некоторой дополнительной логики из этих внешних приложений, чтобы сообщение использовалось только одним.

Стратегия, описанная в статье Что такое SKIP LOCKED в PostgreSQL 9.5? это, пожалуй, самый безопасный / простой способ реализовать очередь сообщений в PostgreSQL. Обратите особое внимание на раздел «Как SKIP LOCKED помогает». Читайте также внимательно одно из их предостережений:

Очередь, реализованная в СУБД, никогда не будет соответствовать производительности быстрой выделенной системы очередей, даже той, которая обеспечивает те же атомарность и долговечность, что и PostgreSQL. Использование SKIP LOCKED лучше, чем существующие в базе данных подходы, но вы все равно будете работать быстрее, используя выделенный и высоко оптимизированный внешний механизм организации очередей.

Это особенно важно, если объем очереди высок.

joanolo
источник
1
Я хотел бы присудить награду автору этой статьи. Так чрезвычайно полезно.
Wildcard
3

Я сделал что-то подобное некоторое время назад с хорошим успехом, я использовал RabbitMQ и этот плагин https://github.com/gmr/pgsql-listen-exchange

В основном RabbitMQ подключается к PostgreSQL и прослушивает событие notify, затем вы можете использовать RabbitMQ для агрегирования этого сообщения в столько очередей, сколько необходимо, и иметь приложение, потребляющее каждую очередь

Фил Паффорд
источник