Postgres Listen / Notify As Message Queue

17

Czy istnieje sposób użycia funkcji Postgres Listen / Notify w celu dostarczenia wiadomości do kanału i umożliwienia korzystania z niej tylko przez jednego słuchacza?

Celem tego jest to, że mam wiele aplikacji „roboczych”, wszystkie słuchają tego samego kanału Postgres. Ale chcę, aby praca była wykonywana tylko raz dla każdej wiadomości otrzymanej za pośrednictwem kanału powiadomień.

Jeśli Listen / Notify nie jest poprawną funkcją Postgres, czy jest jakaś osobna funkcja, której powinienem używać?

Idealnie chciałbym to zrobić bez użycia dodatkowych rozszerzeń.

moesef
źródło

Odpowiedzi:

24

Zgodnie z dokumentacją PostgreSQL na tematNOTIFY :

Komenda NOTIFY wysyła zdarzenie powiadomienia wraz z opcjonalnym ciągiem „ładunku” do każdej aplikacji klienckiej, która wcześniej wykonała kanał LISTEN dla określonej nazwy kanału w bieżącej bazie danych. Powiadomienia są widoczne dla wszystkich użytkowników .

(moje podkreślenie)

Oznacza to, że nie można zrobić to, co chcesz po prostu z LISTEN/NOTIFY . Możesz jednak mieć zarówno tabelę do przechowywania wiadomości w kolejce, LISTEN/NOTIFYaby powiadamiać aplikacje zewnętrzne, że „w kolejce wiadomości są nowe rzeczy”, i użyć dodatkowej logiki z tych aplikacji zewnętrznych, aby tylko jedna z nich zużyła wiadomość.

Strategia przedstawiona w artykule Do czego służy SKIP LOCKED w PostgreSQL 9.5? jest prawdopodobnie najbezpieczniejszym / najłatwiejszym sposobem implementacji kolejki komunikatów w PostgreSQL. Zwróć szczególną uwagę na część „Jak SKIP LOCKED pomaga”. Przeczytaj także uważnie jedno z ich zastrzeżeń:

Kolejka zaimplementowana w RDBMS nigdy nie będzie pasować do wydajności szybkiego dedykowanego systemu kolejkowania, nawet takiego, który zapewnia taką samą atomowość i trwałość gwarancji jak PostgreSQL. Używanie SKIP LOCKED jest lepsze niż istniejące podejście w bazie danych, ale nadal będziesz działać szybciej dzięki dedykowanemu i wysoce zoptymalizowanemu silnikowi kolejkowania zewnętrznego.

Jest to szczególnie ważne, jeśli wolumin w kolejce jest wysoki.

joanolo
źródło
1
Chciałbym przyznać nagrodę autorowi tego artykułu. Bardzo pomocny.
Wildcard,
3

Zrobiłem coś takiego z powodzeniem, użyłem RabbitMQ i tej wtyczki https://github.com/gmr/pgsql-listen-exchange

Zasadniczo RabbitMQ łączy się z PostgreSQL i nasłuchuje zdarzenia powiadomienia, a następnie można użyć RabbitMQ do agregowania tej wiadomości do tylu kolejek, ile potrzeba, i aplikacja zużywa każdą kolejkę

Phill Pafford
źródło