Рассказ, не имеющий отношения к политике. Большая "Я" - не опечатка.
Просто история одной проблемы в непо
лиэтическом изложении
С некоторых пор у меня на сервере с КП стало твориться нечто странное и необъяснимое, а именно жуткий периодический (порой складывалось впечатление, что эпизодический) жор памяти апачем, вплоть до out of memory и приходом киллера, который пришибал зажравшиеся (по его мнению и не всегда в точку. Например, мускул, осмелившийся попросить ещё кусочек памяти, когда её итак уже нет. В расход!) процессы с целью не позволить серваку совсем уйти в даун. Сервак, между прочим, вполне сбалансированный и не страдающий нехваткой памяти, свопами и прочими закидонами. Обычно.
Я связывал это с обновлением серверного софта для перехода на php 5.3 в связи с необходимостью проапдейтить таки платформу до более актуального состояния, типа 12.5. Ну, совпало примерно по времени. К тому же жалоб на форуме как-то не замечалось, что ещё больше укоренило во мне подозрение софта на "течь". Пару раз пугался, относя на дыру, так как случались в это время нашествия монстров-сканеров, но эту причину отмёл, так как скрипт-кидди стабильно получали пинка под зад, о чём радостно повествовали логи.
Сколько танцев с бубнами я сотворил, обновляя ПО, меняя версии, отключая и подключая модули, скидывая кэш то в файлы, то в мемкэшед, меняя акселераторы, переписывая конфиги, рестартуя сервер, лимитируя количество запросов на процесс и т.п - не перечесть. Много времени. Чаще внеурочного, так как посреди рабочего дня отрубать КП не комильфо, людям работать надо. И времени этого жалко. Но не о том речь.
Иногда казалось, что эврика! После очередных танцев проблема наконец-то решена, потребление приходило более-менее в норму и могло так пребывать довольно долго, но потом вдруг - хрясь! И снова неуёмные аппетиты, тормоза, своп, кернел в панике и киллер, устраняющий неугодных.
Самое забавное, что проблема усугублялась, как правило, по выходным дням, когда и нагрузки на сервак практически никакой, так, только мессенжер на незаглушенных компах пинговал сервер в надежде на свежие ивенты, а вот поди ж ты, апач жрал, как не в себя.
"Не в себя" - это совершенно нескромные количества, вплоть
до гига на процесс, не говоря о виртуальной памяти.
Кто-то может спросить, а чего мол, не лимитировал память под пхп, дабы отбить аппетит, если много захочет. А того, что отказы клиенту мне не нужны. Обидится клиент, если что-то у него обломится. А если обломится что-то серьёзное, вроде длинющего бизнес-процесса со многими высокопоставленными участниками, у которого успело закрыться задание, а вот сам процесс из-за нехватки памяти дальше пойти не успел, то вообще тушите свет. Вылечить такой БП под силу очень немногим, с глубоким знанием модуля и структуры данных БП. Про простых юзеров и админов даже заикаться не стоит. А обернуть в транзакцию завершение задания и переход процесса в следующее состояния почему-то не модно. Привет! Вот и не лимитирую почти. В обычных условиях оно не требуется.
Но вернёмся к нашим баранам. После очередной "эврики" и двух недель вроде бы более-менее спокойного полёта с небольшими отклонениями, в эти, обещавшие быть замечательными, выходные с погожей погодкой, которых летом осталось не так уж много, в пять утра меня настигла смс с алярмой о разбушевавшемся на серваке киллере. Печаль.
По привычке ребутнув апач и не уловив улучшений, так же по привычке проверил версии, почитал ченжлоги, в которых ничего похожего, но всё равно апдейтнул ПО, на всякий случай, вдруг. "Вдруг" не случилось, окончательно приуныл, идей в невыспавшейся башке никаких, всё в очередной раз проклял и лёг, в попытке поймать за хвост такой забавный кошмар, который не успел досмотреть. Не поймал. Проснувшись, снова сел за работу. Идей не прибавилось, логи ничего интересного не вещают, минимум активности, обычные "пинги" мессенжера и необычный жор апача, за пару-другую запросов откусывающего до метров 800 памяти.
Поняв, что всё уже перепроверено и перепробовано, дальше течь только с помощью ядра и такой-то матери, понаблюдав за "пингами", решил посмотреть, что там кушает мессенжер. Это было бинго, хотя я этого ещё не понял. Воткнув memory_get_peak_usage() в конец аяксового скрипта компонента мессенжера вывел в файл, рестартанул апач, чтобы выйти на исходные и стал ждать обращений.
Вот и первые стуки мессенжера - никакого криминала, пиковое использование памяти ~10 метров, потом ещё пара таких же...
И тут -
БАЦ! Очередное обращение даёт 230 метров. Опачки, не понял. Мониторю дальше: 10, 10, 10, БАЦ! 230 с копейками! Интересненько! Какие-то запросы хотят кушать гораздо больше других! Добавляю инфы в файл, докидываю юзер ид и... парам! 230 приходится только на одного аномального юзера, он же начальник одного из участков!
Идём дальше, ищу, в каком ифике запросы от этого юзера обрабатываются, смотрю, что выплёвывается ему в ответ, затаив дыхание - ага, щас посмотрим, поди генерится какой-то ненормальный здоровенный ответ, отсюда и расход, ну-ну! Щас мы его! Однако, всё в рамках приличий, типовой ответ.
Снова приуныл и решил воткнуть вывод использования памяти в начало скрипта, сразу после пролога. Бабах! 230М! Тоска одолевает, мессенжер кажется не причём, надо копать выше, что там с этим юзером за неадекват.
Иду в админку КП, ковыряюсь в карточке юзера на всякий случай, смотрю сессию в админке, мимоходом замечаю, что кто-то хочет в публичке поработать и надо бы открыть доступ. Но доступ открывать нельзя, так как апач жрёт и может уйти в отказ в неподходящий момент. Надо отрубить генератора жора, по айпи нельзя, с этого шлюза много кто работает, решаю пришибить сессию вручную, иду в каталог с сессиями и
ЭВРИКА!Тут-то прозрение и пришло, ибо сессию человека найти оказалось проще простого, она сразу бросалась в глаза, так как весила 15 метров с гаком! Вот вам и жрущий пролог (точнее ЗАпролог). Остальное - дело техники. Перемещаю сессию к себе, рестартую апач, ликую! Расход стандартный! Открываю публичку людям и иду читать злополучную сессию.
Дальше раскрутить ситуацию легче лёгкого - 99.99 и дальше девять почти шестнадцатиметровой сессии занимает сериализованный массив:

Привет, мессенжер! Вот ты и спалился =) А уж как это богатство в памяти развернётся - ух! В зобу дыханье спёрло.
Смотрим, откуда ноги растут - это массив, в который мессенжер вроде как скидывает отрапортованные клиентом всплывшие нотификаторы, при этом видимо не проверяя, есть ли они уже там. Ничего страшного, казалось бы. Да вот нифига!
Номер раз:
Некоторые сотрудники не читают уведомления, поэтому их может накопиться преизрядное количество. И я вполне понимаю таких людей, как ни странно. Ибо уведомления часто это спам, мешающий работать, в котором трудно отловить нужную информацию. Привет, неконтролируемый поток уведомлений, на который так долго жалуются
боль юзеры на форумах! Привет, бесполезный и забытый (забитый?) механизм подписки! Да, в последнем релизе уведомления стали настолько злыми, что бесят практически всех (особенно генерального директора), поэтому люди жмут значок нотификатора только чтобы избавиться от этой здоровенной мелькающей ленты окон уведомлений на весь экран, на дизайне "лайт" при этом загораживающей доступ к меню. Но, как выяснилось, жмут всё-таки не все, есть отдельные оппозиционеры, которые этого не делают.
Номер два:
Многие сотрудники не выключают компы и на закрывают вкладки с порталом. Благодаря мессенжеру сессии могут быть бесконечными, если свет не отрубают, коннект и сервак не падает и прочие катастофы не происходят. Привет, усиление безопасности путём настройки длительности сессий! Забыл закрыть сеанс на чужбине - открыл тылы врагу! Временное хранение может стать постоянным.
В общем-то, неконтролируемое складывание данных в сессию и есть ошибка. Вполне обычная, никаких претензий к автору, бывает.
Просто аукнулось при стечении ряда обстоятельств. Может, считается, что нечитающих уведомления юзеров не бывает в природе. Может, привычка: сессия - это же временно, само отвалится. Может просто недосмотр, из-за чего одни и те же данные могут бесконечно складываться в сессию, приводя к её опухоли вплоть до того, что сервак отваливается в попытках её переварить на каждом хите.
А так странно проявлялась, потому как сотрудник уходил в отпуск или в командировку и гасил комп, сессия пришибалась, сервак стабилизировался. А кто-то просто жал на иконку нотификатора, чтобы не бесили. А иногда я просто стопорил серв достаточно надолго, чтобы сессии устарели и мусорщик их выкинул, вот всё и было красиво после рестарта. А почему в выходные обострение - опять же просто: на незакрытых сеансах количество данных в сессиях всё росло, а так как активность малая, то процессы просто не успевали отваливаться по лимиту запросов на процесс, освобождая память. Росли и висели.
Сегодня кстати помониторил сессию человека, за 10 часов опухла до 2х метров. Ну так, просто интереса для и ещё парочка растёт потихоньку.Зачем я всё это написал и какая мораль? Да фиг его знает, накипело просто =) Да и мораль, как и правда - у каждого своя. Кто-то может почерпнёт что-то. Всё равно очередной выходной пропал, отчего бы и не поболтать ерундой, заодно задев пару набивших оскомину моментов, авось прислушаются.
PS. А может это наша пхпшная привычка вовсе? Есть такое у нас, ленивое что-то. Зачем прибирать за собой, само отвалится. Зачем заморачиваться оптимизацией памяти, ещё ансеты делать, алгоритм поприличней продумать? Красиво и правильно? Так время отнимает! Сдохнет процесс и освободит. Или сессия сдохнет. Не у всех привычка, конечно же, но есть. За собой вот тоже замечаю, прибивать временные данные порой лень становится, распустился на пхп. А процесс-то ведь может не сдохнуть сразу, а висеть неизвестное время как мод апача (который битрикс вроде как одобряет, хоть и юзает сам фпм на б24) и память-то не вернёт, а будет ещё кушать. И сессии вот, опять же, маклаудные.
PPS. Ещё невольно вспоминаются новички, мечтающие не заморачиваться с кукисами и БД и делать "вечные" сессии, в которых хранить весь пользовательский хлам. Которых пинаешь, что так нельзя, но не всегда доходит. Им тоже в назидание, что может случится ненароком (не считая того, что огромное количество сессий будет вести к тормозам само по себе).
PPPS. И резалт_модифайеры отчего-то вспоминаются, когда из-за одного дополнительного поля приходится почти дублирующую выборку делать или толстыми массивами жонглировать...
PPPPS! Может таки поправить тут сортировку, чтобы не по времени изменения была? А то поправишь мелочь какую-нибудь, а оно выпрыгивает как чёртик из табакерки поверх всех =(