Postgres c# тайм-аут прослушивания - PullRequest
0 голосов
/ 21 февраля 2020

Я использую Postgres 9.5, которая имеет функцию под названием LISTEN/NOTIFY, которая позволяет вам настроить асинхронный командный канал для получения уведомлений с сервера. В течение первых 10-15 минут, когда мое приложение запускается и я тестирую уведомления, кажется, что все работает, но через некоторое время сообщения просто теряются.

Есть ли у кого-нибудь какие-либо предложения относительно того, что может предотвратить такое поведение? Это как-то связано с настройками keep alive / tcp keep alive? В pg_state_activity я вижу то же соединение, и оно находится в состоянии ожидания.

Общее краткое изложение ситуации

  • Использование библиотеки npg sql в c# для удаленного сайта Postgresql сервер
  • Использование продолжительного соединения (настройка прослушивания, ожидание)
  • Выполнение запроса для прослушивания входящих уведомлений и уведомлений
  • Ожидание (с токеном отмены) ) до тех пор, пока не будет получено сообщение (никакие другие действия не выполняются при подключении).

Просматривая некоторые другие ответы в StackOverflow, кажется, что люди также связывают это с пулированием, хотя я не совсем уверен это хорошо переводится как npgsql, так как объединяет соединения при подключении / отключении.

Буду признателен всем за понимание этой проблемы, у кого-нибудь есть идеи, как я могу заставить мою ситуацию работать? Вот фрагмент кода, который является виновником: https://gist.github.com/phr34k/3a59af154d8ce6636dfc332271052a6a

Редактировать

В ответ на ответ jjanes я пошел на дальнейшее расследование. Когда я смотрю в pg_state_activity, он перечисляет соединение в состоянии ожидания. Когда я сопоставляю номер порта клиента с netstat -t на сервере, по крайней мере, я не вижу соединения в списке.

Честно говоря, до того, как я запустил netstat -t, я попытался pg_notify, так что я пока не могу быть уверен, что запуск pg_notify не привел к его завершению. Однако странная вещь заключается в том, что соединение продолжает отображаться в pg_state_activity, как если бы postgres даже не осознавал, что соединение было закрыто?

Я думаю, что это как-то связано с брандмауэрами и незанятыми соединениями , Кто-нибудь знает, есть ли что-нибудь по умолчанию в стеке ubuntu / digital ocean, который через некоторое время разрывает соединения?

1 Ответ

1 голос
/ 22 февраля 2020

Я не думаю, что что-либо заставит соединение прекратить прослушивание, без вызова UNLISTEN или закрытия. Наиболее вероятное объяснение состоит в том, что соединение разорвано, и затем пул соединений выдает это сообщение путем восстановления соединения, и в этом случае новое соединение не будет прослушиваться. Это событие должно регистрироваться как на стороне клиента, так и, вероятно, на стороне сервера. Видите ли вы в журналах что-то, что, кажется, имеет смысл в этом контексте?

'idle' - это нормальное "состояние" в pg_stat_activity чего-то, что ничего не делает, кроме прослушивания, так что это не поможет вы. Но столбец «backend_start» может помочь, согласуется ли это с закрытием и повторным открытием соединения? «State_change» может на первый взгляд показаться многообещающим, но, похоже, он не обновляется только после того, как клиент прочитает уведомление. Я не вижу способа для одного сеанса определить, прослушивают ли другие сеансы. pg_listening_channels () работает только для соединения, которое его выдает.

Ожидание (с токеном отмены), пока не будет получено сообщение (никаких других действий с соединением не происходит).

Значит ли токен отмены? Вы когда-нибудь использовали это? Может ли поделиться фрагментом кода, который реализует это ожидание?

Я не думаю, что 10 или 15 минут достаточно для того, чтобы TCP решил, что соединение разорвано, поэтому, если соединение разорвано, оно становится Скорее всего, что-то активно этим занимается, вроде файервола Если это так, он может «проследить» за поддержкой и в любом случае решить разорвать соединение.

...