Как я забыл сказать горшочку, чтобы он не варил

Вот вам прохладная история на ночь. И как раз продолжение истории с ботом-оповещалкой для телеграма!

В общем я настроил на боте оповещения, когда происходят аномальные скачки в использовании CPU/RAM. И вот уже вторую ночь подряд мне приходит уведомление об этом вот самом.


Поясняю контекст. У меня на сервере в качестве демонов крутятся два сервера: один для сбора матчей (слушает команды, получает ID матчей, собирает данные и добавляет в базу), второй для мониторинга матчей (смотрит все новые соревновательные матчи и посылает запросы сборщику).

Я для них не писал сам какой-то особый режим работы. Вместо этого изначально я их просто запускал через nohup _executable_ & disown. Таким образом я получал демона и всё было хорошо.

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

Проблема тут уже в том, что nohup в этом случае не особо помогает: из-за отслеживания сигналов (читай активной работы с stdin/stdout) потребление ЦП автоматически начинало скакать до 100% и тут уже ничего не попишешь. Решение было довольно простое: просто запускать этот сервер через screen -dmS — никакого тебе сжирания процессора и всё прекрасно работает. К тому же, если вдруг случаются какие-то неприятные ситуации, можно открыть screen и глянуть на лог ошибок, которые будет выдавать сервер.

И вот я запустил бота, настроил мониторинг ресурсов и спустя какое-то время получил первое уведомление о 100% нагрузке на процессор. Захожу проверить, смотрю — тот самый сервер-сборщик сходит с ума. Ну, думаю, сейчас подключусь к screen, продолжу сессию, посмотрю, что не так, кто его обидел... а сессии нет.

Не понял.

Что за фигня.

Может в логе ошибок на диске что-то есть?

Нет, и там пусто.

Непонятно.

Решил посмотреть на скрипт запуска демонов, случайно заметил, что я там неправильно прописал редирект stderr. Ну ладно, не страшно. Что было в логах я предварительно проверил, ничего не потерялось, просто перезапустил всё по горячим следам. Проблема исчезла, но причину я так и не нашёл.

Следующая ночь, примерно то же время. Снова приходит уведомление. снова 100% загрузка, снова тот же сервер, опять сессия screen отвалилась. И логи опять пустые. Ну что за дела?

И вот в этом моменте, открыв htop, я краем глаза заметил странный процесс где-то на дне. Проскроллил вниз, присмотрелся — работает некий "autorun.sh". Начинаю припоминать, что где-то год назад, ещё до появления сервера для мониторинга, ещё до появления этой версии сервера-сборщика, был прототип, который делал обход команд и искал новые матчи. Команду для запуска скрипта со всеми нужными параметрами, которые я сделал специально для еженочного обхода, я прописал в отдельный шелл-скрипт, назвав его... autorun.sh. И после этого поместил его в crontab. И забыл.

Прошло время. Я сделал новые версии серверов, несколько раз примерно в это же время суток сталкивался с непонятными скачками потребления ЦП, но не обращал особого внимания, потому что обычно виноват был в этом я и какой-то косяк в свежем коде. Старый скрипт-сборщик заменился полноценным сервером, который запускался через тот же лаунчер и той же самой командой. Параллельно с этим я пересел на anacron и все ежедневные задачи висели именно в нём. И если бы не этот случай, я бы и не вспомнил, что когда-то я добавил одну-единственную задачу на еженочный запуск autorun.sh, и прописал я её именно в cron.

И ради интереса я решил залезть в оригинальный скрипт и посмотреть, что же я там прописал такого, что могло вызывать такую реакцию. А там в целом не было ничего особенного: просто список на примерно 100 команд, для каждой из которых производился сбор матчей. Только сбор матчей производился по ныне нерабочему методу API. 
Ну а после такой попытки сбора матчей скрипт пытался сохранить полученный список и запустить скрипт-сборщик, который в виде прототипа считывал его из файла. Только вот незадача: по этой команде теперь запускался сервер-сборщик, который при получении определённых параметров забивает, что есть уже одна запущенная копия, что в итоге иногда приводит к конфликтам. И именно это и происходило вторую ночь подряд.

А причиной всему была одна простая вещь: я забыл убрать скрипт из crontab. Так горшочек каждую ночь пытался заварить кашу, которой нет, на огне, которого нет.