Аннотация: Это жизненная история о том, как нестабильная легаси-шины принесла миллионные потери. Бизнесу — в рублях, всему персоналу от инженеров до топов — в виде погибших нервных клеток.
1. Пролог: «Антивирус, как спусковой крючок»
Инфраструктура проекта была отлажена годами. Случались иногда в ней какие-то аварии, но обычно из них удавалось довольно быстро выпутаться. Мы, команда поддержки, уже точно знали все болячки, имели всякие припарки. Наша команда обеспечивала работу и обновление следующего состава:
Сервисная шина: RedHat JBOSS FUSE 6.1
Версия Java: 1.7.0_71
Операционная система: RedHat OS 6.6 (Santiago) с ядром 2.6.32-504.el6.x86_64
Надо отметить, что таких шин не одна, а целых три. Ещё есть кластер BPM, но сейчас не о нём речь. И всё бы работало до наступления энергетического голода или прямого попадания ракеты, но в один прекрасный момент мы получили от первой линии сигнал тревоги — очереди на ActiveMQ начали скапливаться и не вычитываться.
Причину нашли не сразу. Java-процесс шины бодро трудился по выводу top, хотя по сетевой активности показал сильную просадку — нет обмена данными. Попытались зайти в консоль karaf, чтобы проверить состояние модулей, но не тут-то было. Консоль висела. А значит, зависли и все сетевые соединения. Можно представить себе, что это значит для интеграционной шины.
Разумеется, тут же перезапустили сервис и расслабились. Но не надолго. Через полчаса история повторилась, но уже с другой шиной.
И поехало. То зависания были чаще, то шины могли проработать полдня без проблем. Начали собирать экстренные мозговые штурмы по решению. Поступала масса предположений. Для систематизации создали общедоступные документы, где фиксировали все гипотезы. Это оказалось очень полезно, т. к. к решению проблемы постоянно подключались новые специалисты как со стороны заказчика, так и с нашей. Правда, со временем эти файлы стали настолько большие, что новые люди были не в состоянии их быстро освоить, и приходилось пересказывать им содержание предыдущих серий.
Основная гипотеза — установка антивируса службой безопасности… сразу на ПРОД!!! Ладно, отработали и эту гипотезу — инфраструктура развернула новую виртуалку с бекапом до установки антивируса. Но проблема осталась там же, где и была.
Мы анализировали число потоков, тюнили параметры запуска JVM, снимали тред-дампы (в первую очередь искали дедлоки — и они иногда появлялись в большом количестве, когда дамп успевал создаться непосредственно перед падением), дампы хипа, ядра и TCP каждые 30 секунд, анализировали время ответов, но найти проблему не удавалось. В логах шины и системы — никаких предпосылок зависания. Да, были аномалии, но они возникали, судя по всему, уже после зависания.

2. Скрипт не от слова «скрип»: автоматизация как глоток воздуха
Мы были в отчаянии от постоянных созвонов и рестартов. Нужно было хоть как-то минимизировать простои, которые иногда достигали 20 минут, а это несколько миллионов потерь для бизнеса.
В моменты затишья я начал писать сначала отдельные команды на баше, потом собирал их в скрипты. В результате появился мощный скрипт, который каждые 30 секунд проверял 3 главных показателя:
доступна ли консоль karaf
вычитываются ли очереди (использовали чудесную утилитку fmtn/a)
пишутся ли логи шины
Если один из параметров был false, скрипт рестартил сервис шины. Сначала пробовал сделать это мягко — kill -STOP и kill -CONT. Если не помогало, то полный рестарт. Такой инструмент работал бесшумно, без пыли, потреблял минимум ресурсов, но позволил сократить время реагирования на аварийную остановку до 30 секунд, писал собственный лог и снимал дампы.
3. Развязка
Рука бойцов колоть устала
И ядрам пролетать мешала
Гора кровавых тел.
— М. Лермонтов
После того как наш скрипт-сторож взял на себя борьбу со следствиями, команда смогла наконец сосредоточиться на поиске коренной причины. Одного из инженеров поиски привели к статье «Linux Kernel: Performance Issue with Synchronous Accept».
Суть гипотезы: в старых ядрах серии 2.6.x существовала коварная проблема (SO_REUSEPORT), приводящая к «голоданию» (starvation) процессов при приеме сетевых соединений. При высокой нагрузке один поток мог захватить все соединения, а другие — простаивать. Симптомы: живой процесс, тихие логи и полная сетевая недоступность. Это было очень похоже на нашу проблему.
Разумеется, в таком положении мы готовы были пробовать любое разумное решение. Но установка новой ОС означала обновление и Java, что тянуло бы за собой обновление всей шины со всеми модулями, а это очень дорого для бизнеса.
Тогда я предложил хирургически скопировать старую яву на новую ОС RHEL 9.5 с современным ядром 5.15.0-304.171.4.1.el9uek.x86_64, прописал симлинки, и шину скопировать без каких-либо изменений. Пришлось только включить поддержку старой криптографии через update-crypto-policies --set LEGACY, чтобы ява смогла коммуницировать.
И это сработало! Поэтапно мы обновили ОС на всех шинах и BPM. И вот тогда наступило настоящее спокойствие, которого ждали почти 2 месяца.

4. Эпилог: спасибо, что живой
Кстати, наш скрипт-спаситель заказчик в итоге удалил — посчитали, что он больше не нужен. Но зато настроили новые мониторинги в Zabbix через JMX. Решить проблемы они, конечно, не смогут, но хотя бы быстрее покажут проблему.
Вынесенные уроки:
Иногда вместо попытки определить причину пробоины корабля лучше предпринять попытки по латанию дыры, а уже по приходу в порт подумать о замене судна.
Легаси — это мина замедленного действия. Рано или поздно она взорвется. Наш инцидент — прямое тому доказательство.
Командная работа в стрессе — это искусство. Мы провели много часов на созвонах и в переписке. Нам грозили разрывом отношений и прочими недобрыми вещами. Но мы сохранили высокий уровень корпоративной культуры и профессионализм в решении проблемы. А вот «манипуляторы» не пережили этой ситуации.
Это была тяжелая битва, но мы вынесли из неё бесценный опыт как по хард-, так и по софт-скилам. Именно эти навыки помогают нам теперь быстрее и эффективнее выполнять поставленные задачи.
Комментарии (2)

vanxant
30.11.2025 17:40Ну если у людей 2.6 ядро в 2025, потому что им "дорого", ну, эээ. Кроилово ведёт к попадалову, всегда.
CitizenOfDreams
Иногда? Я бы сказал, что при любой аварии всегда нужно в первую очередь удержать корабль на воде или самолет в воздухе. Иначе потом уже совсем другие люди будут собирать обломки и выяснять, кто проморгал айсберг или почему не загорелась лампочка выпуска шасси (спойлер: она просто перегорела).
А в вашем случае почему она вдруг взорвалась после многих лет работы? Неожиданное увеличение нагрузки до уровня, который за все эти годы не достигался?