0 Пользователей и 1 Гость просматривают эту тему.
  • 53 Ответов
  • 40244 Просмотров
*

userxp

  • Moderator
  • 2019
  • 403 / 6
  • Злой и ужасный бармалей
Сегодня запостили на форуме.
Original version (>>>ссылка<<<):

Hi, all!

Recently I've rewritten a pretty large site on Joomla (it has about 200 online users all the time, as Joomla backend stats shows, >17000 content items etc.) and noticed that the page generation time started to grow ftom 0.101 secs to 0.5 after the first day, 0.7 - 1 next day...). Not very good, right? First of all I went to the MySQL console at the time of high loads and... voila - there is a `opensef_sef` MySQL query present almost constantly.

Guys, if somebody can explain me why do you fetch into the memory almost all records in sef.php [Line #173]:


if ($sefSite->id == null$sefSite->id = -1;
  
$query "SELECT * FROM #__opensef_sef WHERE published = '1'" .
      
"\nAND valid = '1'" .
      
"\nAND (direction IS NULL OR direction = '' OR direction = 'o')" .
        
"\nAND (site_id IS NULL " .
        (
$sefSite->id ' OR site_id = ' $sefSite->id '') . ')' .
        
"\nORDER BY site_id DESC, published DESC, valid DESC, LENGTH(direction) DESC";
    
$database->setQuery$query );
    if (
$database->loadResult()) {
    
$opensef_aliases $database->loadObjectList();
  }  


A quick fix is to replace the query with this one:

if ($sefSite->id == null$sefSite->id = -1;
  
$query "SELECT * FROM #__opensef_sef WHERE published = '1'" .
      
"\nAND valid = '1'" .
      
"\nAND (direction IS NULL OR direction = '' OR direction = 'o')" .
        
"\nAND (site_id IS NULL " .
        (
$sefSite->id ' OR site_id = ' $sefSite->id '') . ')' .
        
"\nAND (external='{$_SERVER['REQUEST_URI']}'" .
        
"\nORDER BY site_id DESC, published DESC, valid DESC, LENGTH(direction) DESC";
    
$database->setQuery$query );
    if (
$database->loadResult()) {
    
$opensef_aliases $database->loadObjectList();
  }  


Hurray! It works as a charm. Page generation time is now 0.07 seconds.
Hope this will help somebody else.
Thanks.


Надо проверять
Как правильно задавать вопрос службе технической поддержки  yes!
SGA CM 7.2.0 RC0 KANG Build GWK74 + s95allinonescript + CWM 5.0.2.6 + Modem XWKT3

Приветствую!

userxp попросил меня отписать здесь о возможных исправлениях для OpenSEF RC5 SP2, так что все "спасибы" и претензии к нему :-)

Итак, корень всех зол заключается в том, что OpenSEF почти всю табличку jos_opensef_sef вытягивает в массив в самом начале своей работы а после этого полным перебором (ужас!) искать там соответствие внутренняю УРЛ - внешняя УРЛ и наоборот. При этом, в случае, если сайт довольно обширный, и ЧПУ на нем много, массив получается просто огроменным. У меня на сайте с 17000 статей ПХП умирал с воем "не хватает памяти" при ограничении в 16Мб. Первый фикс был просто призван уменьшить количество записей, размещаемых в памяти. Но.. не тут-то было. Оказывается, OpenSEF этот же глобальный массив использует для всех-всех ссылок, котрые Джумла пытается привести "человеский вид" (перекрывается ф-я sefRelToAbs). Естесственно, простая фильтрация результатов запроса по REQUEST_URI нас уже не спасет. Пробуем следующий фикс:

В файле administrator/components/com_sef/sef.class.php находим ф-ю lookupOutgoing, комментируем то, что там есть, и заменяем вот этим:

   
function lookupOutgoing(  $site_id$url ) { // static method 
        
global $opensef_aliases$database

        
$returnaliases = array(); 
/* 
        if ($site_id == null) $site_id = -1; 
        if (count($opensef_aliases) > 0)        { 
        foreach($opensef_aliases as $aliases){ 
                        if ( $aliases->internal == $url ) { 
                                $returnaliases[] = $aliases; 
                        } 
                } 
        } 
*/ 
      
if (!count($returnaliases)) 
      { 
          
$query "SELECT * FROM #__opensef_sef WHERE published = '1'" 
          
"\nAND valid = '1'" 
          
"\nAND (direction IS NULL OR direction = '' OR direction = 'o')" 
          
"\nAND internal='$url'"
          
"\nORDER BY site_id DESC, published DESC, valid DESC, LENGTH(direction) DESC limit 1"

          
$database->setQuery$query ); 
          if (
$database->loadResult()) 
          { 
            
$aliases $database->loadObjectList(); 
            foreach(
$aliases as $k=>$val
            { 
              
$returnaliases[] = $val
            } 
          } 
      } 

      if (
is_array$returnaliases ) && count$returnaliases )) { 
      
$returnaliases xclCastObjectList$returnaliases'JosOpenSEFAlias' ); 
      return 
$returnaliases[0]; 
    } 
    
$null null
    return 
$null
  } 


Если хостер додумался включить кеширование запросов для MySQL - работать будет отлично, в противном случае, придется Вам всем подождать, пока я не проверю свою идею с кешированием результатов для lookupOutgoing или кто-то другой не придумает чего-то получше.

Не забываем, что первый фикс тоже надо оставить (на самом деле, вообще надо убрать этот глобальный массив и запрос, который в него вытягивает данные, но я пока не знаю, как лучше всего это сделать).

Спасибо. Жду отзывов.
*

murat

  • Захожу иногда
  • 261
  • 13 / 0
Тестировал на локальном сервере (denwer). После установки хака для файла sef.class.php число запросов (кеширование отключено) с 84 увеличилось до 123. После установки хака для sef.php число запросов стало 122, но появилось несколько notice.

Приветствую!

Суть изменений не в том, чтобы уменьшить количество запросов, а в том, чтобы уменьшить нагрузку на веб-сервер. Я полагаю, что на Вашем локальном сервере очень мало статей (content items), а следовательно, совсем немного записей в таблице jos_opensef_sef (раздел Components - OpenSEF - Manage Friendly URLs). В таком случае подход RC5 себя вполне оправдывает. Проблемы начинаются с увеличением количества записей в jos_opensef_sef. На 3х тысячах sef.php начинает заметно замедляться, и требовать неоправданно большого количества ОЗУ. 8Mb, выделяемых в php.ini по-умолчанию, уже становится недостаточно. Плюс к этому в lookupOutgoing применяется поиск полным перебором, а это просто недопустимо, учитывая то, что данная ф-я вызывается для всех ссылок, имеющихся на странице. Я предлагаю заменить полный перебор запросами к базе MySQL. В случае наличия индексов по полям internal и external таблицы jos_opensef_sef и большого (>5000) количества записей, это работает заметно быстрее, а памяти требует меньше. В файле components/com_sef/sef.php можно вообще закомментировать строки

if ($sefSite->id == null$sefSite->id = -1;
  
$query "SELECT * FROM #__opensef_sef WHERE published = '1'" .
      
"\nAND valid = '1'" .
      
"\nAND (direction IS NULL OR direction = '' OR direction = 'o')" .
        
"\nAND (site_id IS NULL " .
        (
$sefSite->id ' OR site_id = ' $sefSite->id '') . ')' .
        
"\nORDER BY site_id DESC, published DESC, valid DESC, LENGTH(direction) DESC";
    
$database->setQuery$query );
    if (
$database->loadResult()) {
    
$opensef_aliases $database->loadObjectList();
  }

Или же применить хак, описанный в 1м посте.

Все мои слова не голословны. Есть живой сайт (адрес не могу светить по причине договоренности с заказчиком, если шибко интересно - пишите в приват), на котором в час пик нагрузка была >1000 одновременных подключений. С оригинальным OpenSEF на выделенном сервере с 2мя гигами ОЗУ и 4-хгигагерцовым процессором страница генерировалась очень долго (от 3х секунд и больше). И это независимо от кеширования (что естесственно, т.к. все записи вытягиваются в sef.php в самом начале работы). После применения описанных изменений, страница генерируется не дольше 0.1 секунды. Думаю, разница заметна. Выводы делайте сами.

Спасибо.
*

murat

  • Захожу иногда
  • 261
  • 13 / 0
У меня на сайте 27 статей. Стоит ли мне применять эти хаки? Ускорится ли зашрузка сайта?

Считаю, что если и ускорится, то очень незначительно. Посмотрите, сколько записей в разделе Components - OpenSEF - Manage Friendly URLs. Их там должно быть не больше 100-200 (если больше -- надо почистить). Я уже писал, что хак имеет смысл применять если записей в меппинг-табличке больше нескольких тысяч.

Проще говоря - Вы можете смело использовать оригинальный OpenSEF RC5 SP2 :)
*

userxp

  • Moderator
  • 2019
  • 403 / 6
  • Злой и ужасный бармалей
ну он не совсем оригинальный ;)
Как правильно задавать вопрос службе технической поддержки  yes!
SGA CM 7.2.0 RC0 KANG Build GWK74 + s95allinonescript + CWM 5.0.2.6 + Modem XWKT3

Он оригинальный относительно тех изменений, который предлагаю я...
*

userxp

  • Moderator
  • 2019
  • 403 / 6
  • Злой и ужасный бармалей
я имел ввиду, что есть "оригинальный" RC5 + к нему SP2.
а я на форуме выкладывал переделанный и локализованный RC5_SP2
Как правильно задавать вопрос службе технической поддержки  yes!
SGA CM 7.2.0 RC0 KANG Build GWK74 + s95allinonescript + CWM 5.0.2.6 + Modem XWKT3
*

moro

  • Новичок
  • 4
  • 0 / 0
Товарищи! Сказано: "Если хостер додумался включить кеширование запросов для MySQL - работать будет отлично". На мастерхосте ответили - не включено! Что же делать? имеет смысл использовать приведенные хаки? или подождать Вашего глубокоуважаемого экспертного мнения на этот счет?
На самом деле - это реальная проблема - очень реальная. на сайте - около 300-400 статей и страницы грузятся по 20 секунд. хостер вопит - отрубает периодически. очень неприятно....

Включайте! И дайте знать, если думать будет больше 3х секунд. Не забудьте про индексы для external и internal в табличке joom_opensef_sef.
*

murat

  • Захожу иногда
  • 261
  • 13 / 0
А как включить кэширование запросов для Mysql самостоятельно? У меня тоже хостер masterhost.

Если у Вас есть доступ к /etc/my.cnf файлу, добавьте эти строки:

query-cache-size=50M
query-cache-type=1
key_buffer_size=128M

Первые две строки включают кеширование запросов (с размером памяти можно экспериментировать, вплоть до 20% от общего количества RAM, установленного на сервере. Третья увеличивает объем памяти, отводимого под кеширование ключей и индексов. Тоже можно ставить до 20% от общего количества ОЗУ. Я ставил 5%. Но у меня очень большие нагрузки на веб-сервер (Apache). Экспериментируйте.

В ближайшем будущем собираюсь написать статью об оптимизации сайта с Джумлой и всех ее подводных камнях. Следите за моим блогом :).

Если будут какие-то вопросы еще с OpenSEF - не стесняйтесь, задавайте здесь или на блоге.  Чем смогу, помогу.

Удачи!
*

murat

  • Захожу иногда
  • 261
  • 13 / 0
у меня нет доступа к этому файлу.

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

murat

  • Захожу иногда
  • 261
  • 13 / 0
немного. А что за индексы и куда их добавлять?

Я уже, по-моему, писал -- если статей немного (меньше 1000), эти патчи Вам не нужны. Все и так работать должно нормально. Если какие-то проблемы и есть, то явно не от OpenSEF.
*

moro

  • Новичок
  • 4
  • 0 / 0
ну вот смотрите, какая картина: стоит Opensef последний,то есть Release Candidate 5 SP2. применен хак из первого поста alfim. проставлены индексы. Хостинг Мастерхост. То есть доступа к конфигурации сервера нет. Ограничения стандартные для этого хостера, то есть крутые. ПЛюс как мы знаем nginx.
Работает шустро сначала (для чистоты эксперимента удалены все ЧПУ). Дальше при 1000 накопившихся ЧПУ - заметные тормоза. При 2000 ЧПУ - половина сайта демонстрирует 502 ошибку, в базе появляется много одинаковых ЧПУ (по два-три на одну и ту же страницу). При этом дебаг joomla показывает, что количество запросов к базе увеличивается в два раза по сравнению с отключенным OpenSEF.

Кто-нибудь видит решение? Такое впечатление, что для обеспечения работы сервера, надо очищать таблицу opensef_sef постоянно.
Отказаться от OpenSEF можно, конечно, но не хочется, потому что сервер давно на нем стоит - поисковики все сожрали... Обидно терять позиции.
*

userxp

  • Moderator
  • 2019
  • 403 / 6
  • Злой и ужасный бармалей
на каких компонентах?
Как правильно задавать вопрос службе технической поддержки  yes!
SGA CM 7.2.0 RC0 KANG Build GWK74 + s95allinonescript + CWM 5.0.2.6 + Modem XWKT3

moro, надо обязательно применить ОБА хака! ОБЯЗАТЕЛЬНО! Я же писал выше. Один только первый хак уложит вам сайт. Всерьез и надолго. ПРимените, и отпишитесь, пожалуйста.

Спасибо.
*

Димитрий

  • Захожу иногда
  • 65
  • 0 / 0
  • Добра и счастья!
что значит уложит?  я применил хак из 1го поста, и все очень быстро стало пахать. 1000 статей на сайте.

То и значит :). Таблица SEF вырастет быстро, пойдут ошибки типа "you have no access" и так далее. Настоятельно советую применить и второй.

Спасибо.
*

murat

  • Захожу иногда
  • 261
  • 13 / 0
*

userxp

  • Moderator
  • 2019
  • 403 / 6
  • Злой и ужасный бармалей
с точки зрения пхп это логично
Как правильно задавать вопрос службе технической поддержки  yes!
SGA CM 7.2.0 RC0 KANG Build GWK74 + s95allinonescript + CWM 5.0.2.6 + Modem XWKT3

murat, только что отписался там. Не решает основную проблему -- вся табличка все-равно будет грузиться в память. На отечественных (украинских, русских) хостингах популярный сайт с большим количеством статей долго не проживет.
*

Димитрий

  • Захожу иногда
  • 65
  • 0 / 0
  • Добра и счастья!
а подробнее? что значит популярный? и что значит с большим количеством статей? сколько заходов и сколько статей?

Димитрий, я уже писал выше про ограничения. В числовом виде. Перечитайте еще раз :)
*

Димитрий

  • Захожу иногда
  • 65
  • 0 / 0
  • Добра и счастья!
Включайте! И дайте знать, если думать будет больше 3х секунд. Не забудьте про индексы для external и internal в табличке joom_opensef_sef.

я перешел на быстрый хостинг firstvds, и пошли тормоза с сефом.. 1000 статей,посещаемость 60 человек в день.
генерится по 10 секунд. что делать?
что за индексы, про которые вы пишите?

Индексы на соответсвующие поля в табличке jos_opensef_sef
А хаки Вы применяли?
*

Димитрий

  • Захожу иногда
  • 65
  • 0 / 0
  • Добра и счастья!
оба хака применил. все равно не понимаю, что за индексы. обьясните, если не сложно- для тех, кто в танке- что надо сделать? могу зайти через phpmyadmin и сделать данное действо.
когда я был на другом хостинге все летало, сегодня перешел- сделал полную копию. сначала SEF показалось вообще не работал. просто висяк полный.  посмотрел логи, там везде 404 стоит от яндекса-бота.
потом переставил openSEF, стало жутко долго открывать- 10-20 секунд.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться