Зависшие соединения на сервере rabbit


#1

Приветствую.

На стороне 1С есть одно регламентное задание, которое читает из очереди. Читает в один поток. Но иногда наблюдается картина, что у очереди есть два получателя, и на одном получателе висит неподтвержденное сообщение и при этом нет никакой активности. При этом на стороне 1С зависших фоновых нет.

Как с этим можно бороться?
Из-за чего может возникать такая ситуация?

Два получателя:

Зависший канал (соединение):


#2

Это значит, что 1С не освободила объект внешней компоненты и он так и остался висеть в памяти. Полагаю, такое могло быть только если падал rphost или поток внутри rphost.

Перезапуск рабочих процессов в кластере настроен?


#3

Перезапуск рабочих процессов в 1с настроен при превышении объема памяти


#4

Может в подсистеме сделать работу фонового задания с пристрелом - как мы обычно делаем “фоновое задание должно жить не более 15 минут”

@Dshcherbina эмпирическое исследование показывало что в 1С лучше делать фоновые которые “короткоживущие” - это не совсем к данной задаче относится, но все же.


#5

Поддерживаю. Длительные ФЗ имеют обыкновение пропадать бесследно с сервера. И никаких следов, ни в журнале регистрации, ни в МенеджереФоновых. Скорее всего, непойманное исключение внутри платформы при каких-то условиях. И как раз это - как я писал выше - могло привести к неосвобождению объекта компоненты.


#6

Добавлю, что перезапуск рабочих процессов прибивает фоновые задания. не завершает путем какого-либо штатного сигнала завершения сеанса, а именно рубит на корню.

На прошлых проектах, когда было критично, чтобы фоновые задания завершались успешно и до конца, помимо перезапуска по памяти настраивали таймаут на выключение рабочего процесса.

То есть при превышении объема допустимой оперативной памяти рабочий процесс сначала переходил в состояние “выключен” (или “не активен”, не помню как он там называется), фоновые задания продолжали там до-выполняться (на протяжении до двух часов), и только после этого рабочий процесс завершал свою работу физически.


#7

Т.е. правильно я понял

  • На стороне сервера rebbit нет возможности настроить отключение таких соединений

  • предлагается у регламентного задания, которое читает данные из очереди, проставить “останавливать через 15 минут”. И тогда есть шанс, что это фоновое не попадет в “перегружаемый рабочий процесс” или просто пропадет. И при принудительном завершении фонового задания, компонента будет выгружена корректно, и если даже в этот момент читается сообщение, то оно будет возвращено в очередь и не останется висеть в неподтвержденных


#8

отключение таких соединений со стороны сервера возможно через административную утилиту

rabbitmqadmin -q close connection name=name_of_connection

@EvilBeaver heartbeat ? или чур меня с моими предложениями


#9

Было бы круто, а то иногда приходится ходить руками отстреливать соединения.


#10

я был уверен что именно ты увидишь это ключевое слово, я даже помню где мы это обсуждали и метод такой добавляли в тестовом режиме Пожелания к редакции Yellow-rabitmq 1.X


#11

Точно, когда начинал тему, были ощущения, что эта тема где то затрагивалась.
Я тоже присоединяюсь к @Bronislav что такая функция необходима.


#12

Предлагаемый алгоритм чуть проще: настраивать читающее рег задание на старт каждые скажем 2 мин. Если в системе уже работает задание с тем же ключом, то второй экземпляр стартован не будет. Т.е. это нормально, если расписание стоит каждые 2 мин, а само задание работает 10 минут. Дублироваться задания не будут.

Далее, в прикладном коде мы открываем соединение с кроликом и слушаем входящие, задавая таймаут. Это будет время “висения” задания. Например - 5 минут. Если за пять минут событий не пришло, таймаут сработает и управление вернется обратно в 1С. В прикладном коде в случае таймаута мы должны мягко выйти из сеанса ФЗ, т.е. завершить дальнейшие попытки коннектов и просто закончить выполнение кода ФЗ.

Платформа увидит, что больше нет заданий с таким ключом и через 2 мин. снова запустит наш “слушатель”.

Получается, что если события из кролика поступают, то наш “слушатель” работает, получает их и обрабатывает. Как только их поток прерывается более чем на 5 минут (цифры подбираем опытным путем исходя из задачи) - задание гасится, и в следующий раз поднимается планировщиком платформы через заданный интервал.

Тем самым обеспечивается более-менее короткий срок жизни фонового задания и мягкое завершение соединений с кроликом.

Я на 100% не знаю, как реализованы внешние компоненты в 1С, но довольно сильно уверен, что они загружаются в адресное пространство конкретного rphost и за освобождение памяти от объектов компоненты отвечает этот же rphost. Если он работает хорошо, то за счет счетчика ссылок он корректно освобождает память и вместе с ней - отключаются соединения от кролика. Если этого не происходит, то причина ровно одна - память не освободилась. Это могло произойти:

  1. Есть циклические ссылки на объект компоненты
  2. Поток платформы, который должен был освободить память - упал, не выполнив метод Release, уменьшающий счетчик ссылок

Если завершается (падает или штатно) сам rphost целиком, то по идее, все его ресурсы, включая сетевые сокеты должны закрыться, и соединение для кролика пропадет. Т.е. перезапуск rphost по таймеру, теоретически должен решить проблему висящих коннектов.