
На протяжении 5 лет работы с Joomla, я понял, что данная CMS не очень подходит для сайтов, на которые будет заходить какое-либо значимое количество пользователей. Как я уже говорил ранее, Joomla покрывает потребности в разработке 95% вебсайтов – личные блоги, корпоративные сайты, интернет-магазины (до 1-2K юников в сутки) – всё это Joomla с лёгкостью съест и с лихвой проглатывает, но суть в деталях...
Наш пациент
Исторически так сложилось, что мне в руки попал не очень большой, но сильно тормозящий региональный новостной сайт на Joomla. На данный момент посещаемость сайта – от 5000 (на выходных) до 11000 (в будний день) сеансов в сутки. В базе – 20K новостей.
Анамнез
С сайтом было много-много различных проблем. Уже начиная с какой-то ощутимой нагрузки, стала долго грузиться главная страница. Перенесли сайт на VPS и выиграли несколько месяцев во времени.
Через полгода симптомы вернулись и мы закешировали модули, которые можно кешировать и немного оптимизировали остальные. Сайт продержался ещё пару месяцев.
Далее начали отваливаться уже страницы новостей, да и главная тоже хандрила. Решили вопрос жестко – включили кеширование всего контента в обход Joomla. Сайт начал летать.
Симптомы
- Ну вот и всё,- подумали мы – вот та волшебная пилюля, можно вздохнуть с облегчением. Но не тут то было. Ещё через 2 месяца начала «отвативаться» админка. При сохранении новости в самую большую категорию, админка «думала» минуты 2-3 и тупо вылетала по таймауту:

Диагноз
Для начала (после небольших танцев с бубном ибо версия Joomla была не последняя не очень подходила под мой локальный сервак) я включил профилирование и полез в админку. Но не тут то было. Во-первых, при сохранении новости происходит 302-й редирект (на нужный URL в зависимости от кнопки) и запросы мы не увидим ввиду этого редиректа. Ну, а во вторых, сайт отваливался по таймауту, так что пришлось покостылить с отладкой.
В драйвере (/libraries/joomla/database/driver/mysqli.php) перед вызовом mysqli_query() пишем затычку для логирования всех запросов в файл:
if(MEGA_DEBUG_SCRIPT){
$this->queriesCount++;
$pref = sprintf('[%7.7f, %3d] ',
($this->microtime_float() - $this->time_start),
$this->queriesCount);
file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'log.txt',
$pref.'Query:'.$query.PHP_EOL,
FILE_APPEND | LOCK_EX);
file_put_contents(__DIR__.DIRECTORY_SEPARATOR.'log.txt',
$pref.'Trace Log:'.PHP_EOL.
$this->generateCallTrace().PHP_EOL.PHP_EOL,
FILE_APPEND | LOCK_EX);
}
Не буду вдаваться в подробности – generateCallTrace и microtime_float понятно как работают. В общем, запустил я сохранение, глянул – и ужаснулся. В файле было огроменная куча запросов вида:
UPDATE `s1b4x_content` SET ordering = 896 WHERE `id` = '19573';
UPDATE `s1b4x_content` SET ordering = 897 WHERE `id` = '19574';
UPDATE `s1b4x_content` SET ordering = 898 WHERE `id` = '19575';
...
Сохранение отваливалось на 3500+ запросах к базе. Вот он, наш крассавчик.
Лечение
По трейслогу я нашел виновника торжества:
// Reorder the articles within the category so the new article is first
if (empty($table->id))
{
$table->reorder('catid = ' . (int) $table->catid . ' AND state >= 0');
}
В файле administrator/components/com_content/models/article.php моделька пытается пересортировать все новости в нашей категории и делает это очень тупым и примитивным образом. Тьфу!
Закомментировав $table->reorder всё заработало. Данное поле для нас не играет роли, ведь на сайте мы используем сортировку по дате, а не по полю `ordering`.
Профилактика
Во-первых, не используйте Joomla на новостных сайтах. Будет плохо. Стандартный медиа-менеджер ужасный для загрузки фото. Нет какой-либо нормально удобной системы «закрепления» новостей, модули жутко тормозят, да вот и на вылавливание всяких неудобных моментов потратите много времени.
Во-вторых, перед сдачей новостного сайта обязательно тестируйте его не высоких нагрузках. Погоняйте Apache Jmeter, добавьте 100K – 1M новостей.
Конечно, при желании, прямыми руками можно и Джумлу заставить летать, но только стоит ли это того?
Комментарии
Или взять какой-нибудь фреймворк - и писать уже на нём.
Этот пост больше о конкретной проблеме Joomla и о её решении. А для новостных сайтов у меня опыт либо Джумлы, либо самописного движка. Который, кстати, в разы удобнее (в плане загрузки фото и размещения статей), да и не падает
Так что лично для меня для новостных сайтов проще его взять. Но я не могу данное решение рекомендовать всем.
Особенно не понимаю, зачем такая структура БД сделана.
//Пришёл с хабра, упомянули в комментах https://habr.com/post/354678/
Я тут еще писал пост о том, что мне не нравится в Joomla: https://konservs.com/post/58.
Однако Joomla — отличное решение для того, чтобы за пару вечеров сваять сайт «на коленке», который будет выглядеть и работать более чем удовлетворительно. На Joomla+Virtuemart можно создать даже маленький интернет-магазинчик и он сразу же будет приносить доход.
С Drupal не работал, опыт разработки с Joomla - более 5 лет. Поэтому мне сравнивать сложно
Adding comments is temporarily disabled for unregistered users.