Еще немного про сессии MODX, компонент smartSessions
Всем привет!
Небольшая предыстория
Когда я на свой VPS сервер закинул очередной более-менее крупный сайт (в базе около 25 тыс. товаров), у меня начались проблемы с нехваткой памяти, mysql ее нещадно отъедал.
В процессе оптимизации я начал понимать, что у половины сайтов в базе большую часть объема занимает пресловутая таблица modx_sessions, где, как известно, лежат сессии посетителей.
Но… почему? У сайта посещаемость 150-200 человек в сутки, сессии хранятся 7 дней (да, я проверил, они действительно очищаются), но в таблице почему-то 200000 записей, хотя по логике вещей должно быть 200*7=1400+. Реальность расходится с теорией не на 5-10%, а в десятки раз!
В итоге таблица весит полгигабайта, сайтов штук 10, каждому дай памяти, вот VPS и падает периодически… непорядок!
Самый старый и известный материал на эту тему у нас здесь:
bezumkin.ru/sections/tips_and_tricks/2422/
Есть еще куча вопросов на этом сайте на предмет размера таблицы, да и вообще, все давно-давно терто-перетерто… вывод из всего — проверять, что сессии очищаются, уменьшать время хранения, но вот какая-то недосказанность все равно есть, что происходит понятно, а что с этим делать — не очень.
Нет, ну можно правда чистить таблицу с сессиями почаще, раз в 3 дня к примеру (настройка session_gc_maxlifetime), будет в целом терпимо. Но что делать, если я хочу, чтобы мой интернет-магазин хранил сессии месяц? Вот не хочу я пользователей заставлять постоянно вводить логин/пароль (или код из смс)!
И тут я наткнулся на статью lectoria.pro/read/sessii-v-php-i-modx-revolution.html и затем видео www.youtube.com/watch?v=GyzkQu_-vSI
Ба! Да все придумано уже, только вот реализации не нашел, готовый пакет почему-то так и не собран.
[smartSessions]
В общем собрал все в пакет, назвал smartSessions, вот иходники github.com/createit-ru/smartSessions
В чем суть работы:
— для сессий создана новая таблица modx_smart_sessions, которая повторяет родную modx_sessions, но добавлены колонки user_agent, ip, user_id
— написан свой обработчик сессий smartSessionHandler, который унаследован от родного modSessionHandler
Что сейчас может:
— можно отдельно установить время жизни сессий (настройка smartsessions_authorized_users_gc_maxlifetime ) для авторизованных пользователей.
— можно отдельно установить время жизни сессий (настройка smartsessions_bots_gc_maxlifetime) для различных ботов.
— в настройке smartsessions_bot_signatures можно указать перечень сигнатур этих самых ботов (будет произведен поиск LIKE по полю user_agent, например Googlebot|YandexBot|DotBot|bingbot|Mail.RU_Bot|PetalBot|MegaIndex.ru).
Как попробовать
— установите пакет из репозитория modstore;
— укажите в настройке session_handler_class значение smartSessionHandler;
— проверьте, что данные начали собираться в таблицу modx_smart_sessions. При этом таблицу modx_sessions можно очистить (не удалить, а очистить :)), она больше не нужна.
Благодаря расширенной таблице сессий я смог узнать кое-что новое о записях сессий.
Оказывается, что больше 95% записей в ней — это сессии различных ботов, и причем далеко не всегда это привычные Яндекс и Гугл, есть еще десятки других ботов, которые активно ходят по нашим сайтам.
Ситуация, когда в таблице 10000 записей сессий ботов и 200 записей реальных посетителей — обычная!
Например на своем сайте я настроил хранение сессий авторизованных пользователей 30 дней, неавторизованных 7 дней, а сессий ботов — 3 часа.
Результат — количество записей в таблице сессий снизилось в разы, нагрузка на mysql упала.
В качестве примера, выгрузка сессий, сгруппированных и отсортированных по user_agent за несколько часов.
Выделил сессии ботов, как видно их подавляющее большинство:

Дополнение доступно в ModStore:
modstore.pro/packages/utilities/smartsessions
Небольшая предыстория
Когда я на свой VPS сервер закинул очередной более-менее крупный сайт (в базе около 25 тыс. товаров), у меня начались проблемы с нехваткой памяти, mysql ее нещадно отъедал.
В процессе оптимизации я начал понимать, что у половины сайтов в базе большую часть объема занимает пресловутая таблица modx_sessions, где, как известно, лежат сессии посетителей.
Но… почему? У сайта посещаемость 150-200 человек в сутки, сессии хранятся 7 дней (да, я проверил, они действительно очищаются), но в таблице почему-то 200000 записей, хотя по логике вещей должно быть 200*7=1400+. Реальность расходится с теорией не на 5-10%, а в десятки раз!
В итоге таблица весит полгигабайта, сайтов штук 10, каждому дай памяти, вот VPS и падает периодически… непорядок!
Самый старый и известный материал на эту тему у нас здесь:
bezumkin.ru/sections/tips_and_tricks/2422/
Есть еще куча вопросов на этом сайте на предмет размера таблицы, да и вообще, все давно-давно терто-перетерто… вывод из всего — проверять, что сессии очищаются, уменьшать время хранения, но вот какая-то недосказанность все равно есть, что происходит понятно, а что с этим делать — не очень.
Нет, ну можно правда чистить таблицу с сессиями почаще, раз в 3 дня к примеру (настройка session_gc_maxlifetime), будет в целом терпимо. Но что делать, если я хочу, чтобы мой интернет-магазин хранил сессии месяц? Вот не хочу я пользователей заставлять постоянно вводить логин/пароль (или код из смс)!
И тут я наткнулся на статью lectoria.pro/read/sessii-v-php-i-modx-revolution.html и затем видео www.youtube.com/watch?v=GyzkQu_-vSI
Ба! Да все придумано уже, только вот реализации не нашел, готовый пакет почему-то так и не собран.
[smartSessions]
В общем собрал все в пакет, назвал smartSessions, вот иходники github.com/createit-ru/smartSessions
В чем суть работы:
— для сессий создана новая таблица modx_smart_sessions, которая повторяет родную modx_sessions, но добавлены колонки user_agent, ip, user_id
— написан свой обработчик сессий smartSessionHandler, который унаследован от родного modSessionHandler
Что сейчас может:
— можно отдельно установить время жизни сессий (настройка smartsessions_authorized_users_gc_maxlifetime ) для авторизованных пользователей.
— можно отдельно установить время жизни сессий (настройка smartsessions_bots_gc_maxlifetime) для различных ботов.
— в настройке smartsessions_bot_signatures можно указать перечень сигнатур этих самых ботов (будет произведен поиск LIKE по полю user_agent, например Googlebot|YandexBot|DotBot|bingbot|Mail.RU_Bot|PetalBot|MegaIndex.ru).
Как попробовать
— установите пакет из репозитория modstore;
— укажите в настройке session_handler_class значение smartSessionHandler;
— проверьте, что данные начали собираться в таблицу modx_smart_sessions. При этом таблицу modx_sessions можно очистить (не удалить, а очистить :)), она больше не нужна.
Благодаря расширенной таблице сессий я смог узнать кое-что новое о записях сессий.
Оказывается, что больше 95% записей в ней — это сессии различных ботов, и причем далеко не всегда это привычные Яндекс и Гугл, есть еще десятки других ботов, которые активно ходят по нашим сайтам.
Ситуация, когда в таблице 10000 записей сессий ботов и 200 записей реальных посетителей — обычная!
Например на своем сайте я настроил хранение сессий авторизованных пользователей 30 дней, неавторизованных 7 дней, а сессий ботов — 3 часа.
Результат — количество записей в таблице сессий снизилось в разы, нагрузка на mysql упала.
В качестве примера, выгрузка сессий, сгруппированных и отсортированных по user_agent за несколько часов.
SELECT `user_agent`, COUNT(*)
FROM `modx_smart_sessions`
GROUP BY `user_agent`
ORDER BY `COUNT(*)` DESCВыделил сессии ботов, как видно их подавляющее большинство:

Дополнение доступно в ModStore:
modstore.pro/packages/utilities/smartsessions
Комментарии: 76
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
интерес есть, было бы классно ;-)
Сейчас работаю над закрытым порталом для сотрудников одной крупной мировой компанией и тоже пришлось глубоко погрузится в мир сессий.
К моему счастью, раз в сутки в 3 часа ночи происходит полное обновление данных о сотрудниках и я могу просто запустить скрипт по удалению файлов сессии. Это позволяет разлогинить всех сотрудников, чтобы утром каждый вошел (если не уволен за ночь) с новыми правами и плюс, не заводить кучу файлов сессий. Раз в сутки все файлы просто удаляются.
При правильных настройках — у активных пользователей сессия не будет слетать (так как часто запрашивается).
А менее популярные сессии анонимов при большом размере кеша будут выталкиваться.
Так и при установке MODX на два сервера и более репликация Redis позволит не слетать авторизациям между запросами на разные сервера (именно тут у сессий в БД и было преимущество над файлами, где тоже можно было настроить репликацию БД между серверами).
Но я не знаю и не делал сайтов на MODX, работающих одновременно на двух серверах)
У вас нет ссылок на примеры реализации? Просто я буквально неделю назад углубленно вникал в работу redis и скажем так — не нашел redis очень удобным для хранения сессий. Применил redis для хранения временных токенов, для доступа у определенным ресурсам — вот тут прям идеально применение redis поскольку программа имеет возможность установки времени жизни записи и сама следит за ее удалением.
неужели кто-то так делает? MODX это возможность за 6 дней сделать неплохо работающий сайт, лендинг, небольшой магазин без амбиций. Но распылять MODX на несколько серверов… Мне кажется это из области фантастики. Здесь на форуме собраны лучшие разработчики на MODX в России и бывших странах СССР — кто так делал?
В MODX нужно всего лишь очистить системную настройку session_handler_class — в этом случае за сессии будет отвечать PHP и по умолчанию будет хранить их в файлах.
Для хранения их в redis нужно в php.ini указать:
И теперь уже PHP будет отвечать за хранение сессий в redis.
Более подробнее уже несложно нагуглить)
Правда не стал использовать phpredis а взял вот эту программу cheprasov/php-redis-client
Но дело ведь в том, что редис сам по себе не гарантирует сохранность данных.
Если мы храним сессии в файлах, то они там и остаются. Храним сессии в базе — они там и остаются. А редис это все таки хранилище которое живет в оперативной памяти и при выключении питания на сервере к примеру — все будет потеряно. Да редис умеет периодически сбрасывать данные на жесткий диск, но все это не гарантируется разработчиком.
А в сессии ничего важного и не должно быть. Максимальные потери здесь — содержимое корзины да и выход из аккаунта. А если настроить сохранение на диск, то и потеряется только сессионные данные за последние n секунд)
Зачем? Теперь лишняя таблица в базе болтается. Для таких целей используют миграции. В MODX их нет, но можно расширить схему.
Писать в базу нефильтрованный USER_AGENT — это чтобы пощекотать себе нервы?
Ну и про наследование в ООП советовал бы почитать.
Режим «Николай Ланец» OFF. ))
Но за здравую критику — спасибо
Видимо автор этого текста изучает PHP только в совокупности с MODX (и AjaxForm).
А если я не авторизовался и ничего не положил в корзину, то и сессия мне не нужна. На нормальных сайтах именно так и происходит.
А корзина товаров? А если я товар «отложил», а если я перешел по реферальной ссылке на сайт, а если у нас правда что-то работает через ajax?
Правильнее бы конечно создавать сессии когда они действительно нужны. Но MODX работает на своей волне, а кажется именно его мы здесь и обсуждаем.
Давайте делать статичные странички на html!
Для аякса необходимы сессии? Это что-то новенькое)
Не MODX, а указанное дополнение.
Ну да, переписать дополнение или использовать другое не нужно. А нужно к этому дополнению городить кучу костылей))
1. отдельно управлять временем жизни сессий для авторизованных пользователей (например, поставить им месяц);
2. отдельно управлять временем жизни сессий ботов (к примеру, поставить им 3 часа);
3. У всех остальных — ну пусть будет стандартная неделя.
И на моих сайтах, за счет п.2. размер таблицы и объем данных уменьшился в десятки раз, т.к. именно сессии различных ботов составляли 90% записей в таблице.
Во времена повсеместного бума интернет-приватности и частичного отказа от cookies я вот хочу перенести в сессии некоторые настройки персонализации для незарегистрированных посетителей сайта (например открыто или закрыто боковое меню) и вообще сводить к минимуму использование cookies там где возможно.
Короче, ИМХО тренд сейчас в сторону увеличения времени жизни сессий, а не уменьшению.
Поэтому, если не «плакаться» что «anonymous_sessions» работает не так как хочется, а так, как решил мейнтейнер (хотя может и открыть ещё один issue для обсуждения?), то проблему с растущей базой надо как-то решать всё равно, а идея проверять user-agent и через него фильтровать сессии ботов это же прям похоже на решение!
К Вашему сведению, сессия работает через куку, где хранится её ID. Так что переводить на сессию в Вашем случае смысла нет. Лучше используйте в JS LocalStorage или SessionStorage. Технологии нужно использовать по их назначению, тогда и проблем не будет.
Ну подправил настройки PHP и довольный по привычке перехожу на главную modx.pro глянуть как дела и вижу тут большой новый пост про сессии (0_о)… уже заподозрил что рекламные-таргет-технологии добрались до портала и подкладывают рекомендации на основе истории поиска :)
Оказалось, совпадение…
P.S. Автору большое спасибо! Конечно, готовые решения намного лучше когда в пакетах!
А так затея интересная, автору респект.
MODX не умеет очищать сессии, если используется иной, отличный от modSessionHandler класс.
В процессоре проверяется настройка session_handler_class, и если там указано что-то не стандартное — сразу ошибка.
Как вариант — сделать свой пункт в меню для очистки сессий, а стандартный скрыть… ну и тогда нужно дописать процессор и т.п.
Самый простой выход — через js в админке менять хандлер у этого пункта меню, в котором указать свой процессор (поправленную копию системного процессора).
П.С. К слову, я не сторонник С-ишных названий с префиксом I. Да и суффикс Interface, наверно, всё-таки лишний. По-современному должно быть так — интерфейс SessionHandler, а реализации — modSessionHandler, AntibotSessionHandler и т.п.
Я с C# много работал N лет назад, в голове все это еще прочно сидит)
Но я тоже за расширение оригинальной таблицы modx_sessions через свой плагин для добавления колонок.
П.С.
А еще закинул чуть чуть рублс для стимуляции подвигов, а это без сомнений подвиг!
Я может конечно чет не так понял… но это случилось после того как перешел на этот обработчик! Не подскажите в чем может быть проблемс?
Есть вот такая ошибка в логах:
При этом в кончиках не указан этот путь "/var/lib/php/sessions" для сохранения сессий (строка закомментирована). В чём может быть дело?
Я, когда руки дойдут до smartSessions, попробую оптимизировать компонент, может побыстрее будет работать.
Ошибки появляются несколько раз в день. Посещаемость +\- 10к в сутки. Но бывает больше. Иногда растёт скачкообразно. Видимо, в такие моменты и случается ошибка.
Видел похожий компонент от Володи. Для MODx3. modx.pro/components/24542. Там в комментах тоже были вопросы по оптимизации. Может быть поможет.
Спасибо за отзывчивость, Алексей. Будем ждать обновления.
В этом дополнении нет ничего нового, связанного с контекстами, по сравнению со стандартным sessionhandler. Основная цель дополнения — расширить таблицу сессий, чтобы в ней хранился user-agent. И если user-agent принадлежит боту — чистить такие сессии раньше, не хранить их долго.
Эта ошибка возникла из-за того, что оказался поврежден файл с таблицей БД. Причина, по которой произошла данная ситуация, вероятно, связана с каким-то сбоем на сервере. К примеру, у меня раньше часто из-за нехватки памяти падал процесс mysql, и эти падения иногда заканчивались повреждением отдельных таблиц БД, весьма часто таблицы с сессией (потому что эта таблица каждый раз при открытии любой страницы сайта обновляется), но иногда и таблиц вроде site_content. Увеличение объема памяти решило в моем случае проблему с падающим mysql и повреждением таблиц.
У моего сайта была посещаемость 300 человек в сутки. В неделю это 7*300=2100 человек. Сессии как раз неделю и хранились. Вот только в таблице сессий было не 2000 записей, как было бы ожидаемо, а около 100-200 тысяч. Когда я начал изучать вопрос — боты, одни боты! яндекс, гугл, просто wget какие-то, индексаторы картинок, парсеры… чего только не было) и что забавное — почти всегда каждый запрос генерил новую сессию, боты не держали её)) а итоге приходит яндекс бот на сайт, индексирует сайт, 3000 страниц — о-ппа и +3000 сессий. А кому они нужны?)
Это довольно индивидуальный параметр для каждого сайта. Если не очищается совсем — то gc не работает в php, с ним нужно копать, вот чтиво десятилетней давности: bezumkin.ru/sections/tips_and_tricks/2422
база то в порядке? таблица жива?
forums.modx.com/thread/103530/howto-remove-collection-from-custom-table
Что и происходит, судя по мониторингу MYSQL.
С такими ошибками в логах NGINX:
Настройку session_handler_class меняю на modSessionHandler
Помогает только копирование файлов из бэкапа. В чем может быть дело?
Проанализировал код
1. Во время удаления сессий выполняется N запросов, если быть точным то сколько прописано сигнатур user agent столь и будет выполнено запросов
2. Поле user_agent не индексное, то есть это будут медленные запросы
Еще хотел узнать, зачем для ботов создавать сессию?
И потом её удалять, целесообразность этого функционал не понимаю
особенно с учетом тяжести запросов в цикле
Интересная мысль насчет целесообразности создания сессий для ботов… в принципе может они и не нужны… как вариант можно добавить соответствующую настройку в компонент. В общем мысль сохранил.
Предлагаю, если нужно, захостить его там же, где статистика установки компонентов, в надёжной инфраструктуре одного из крупных ДЦ. Я поспособствую!
Или выпустить список в качестве отдельного пакета, который наследовать, чтобы обновлять средствами MODX.
С каждым годом всё больше и больше проблем от ботов. Ваши решения (Алексея и Андрея) очень помогают, и необходимость в них только растёт!