В продолжение темы. Очень кратко опишу свой опыт с экспериментом сохранения кода страницы в memcached, который в дальнейшем уже отдает nginx без лишних запросов, получая код непосредственно из memcached. Общая идея: генерировать страницу средствами MODX-а и сохранять ее код полностью в memcached, чтобы в дальнейшем nginx проверял наличие кода страницы в memcached-е, и если есть, отдавал код сразу, не отправляя запрос на php. Пока что это только для сайтов-визиток и т.п. (так как на таких страницах нельзя использовать логику с учетом авторизации пользователей и т.п.), но в дальнейшем планирую страницы делать полностью статическими, а всю динамику переносить на Javascript + AJAX. Основные проблемы, с которыми столкнулся:
Молодец! все толково расписал. Насчет только для визиток, я бы не был так категоричен. Nginx много чего умеет…
Так я сказал «пока». Докрутить многое можно. Да и на уровне плагина можно разрулить что кешировать так, а что нет (допустим, личный кабинет не кешировать). Но это так, эксперимент. Я более плотно планирую делать это на уровне node.js То есть нода не все еще умеет, чтобы так сразу фрейм заменить, но ее можно использовать как умный кешер. То есть и данные в памяти держать, и логику рулить можно. В общем, планирую nginx+MODX+node.js
memcache зараза страницу компрессирует как ни крути, а вот с memcached все нормально) вот это у тебя <code>$key = '/index.php?';</code> вообще лишнее, можно выкинуть… и добавить еще $expire <code>$modx->cacheManager->set($key , $modx->resource->_output, $expire);</code> выставить время жизни кеша. и в nginx правильнее наверно будет "default/$args"
memcache зараза страницу компрессирует как ни крути А ты смотри phpinfo() раздел memcache. У него тоже свои настройки есть, типа max_chunk_size или типа того. Наверняка тоже можно поднять значение. вообще лишнее, можно выкинуть… и в nginx правильнее наверно будет «default/$args» Да? А кто запрещает создать еще какой-нибудь внутренний php-файл? И что тогда? И тогда нафиг все побьется. А ты предлагаешь все жестко завязать на единственный php-файл. Не, я так не буду делать. и добавить еще $expire Это я может позже поковыряю, но у меня есть подозрение, что это не так работает, как хотелось бы. Думаю, что это значение для самого MODX-а, а не для мемкеша. То есть как работает этот параметр для MODX-а? — кеш есть, но время уже не актуальное, и MODX его игнорит. Но если это так, то gnixn-у на это пофигу будет, он получит кеш и все. Хотя это только предположение, проверять надо.
да настройки есть конечно, аналогичные кстати… но не получилось, возможно механизм сжатия по другому работает. насчет побьется я не совсем уверен, так как неделю назад вообще про nginx не слышал. Но я думаю ты ошибаешся… Пройдись по конфигу nginx и посмотри логику. $expire работает — уже проверял.
насчет побьется я не совсем уверен, так как неделю назад вообще про nginx не слышал. Но я думаю ты ошибаешся… Пройдись по конфигу nginx и посмотри логику. Я вчера часов 6 с этим конфигом провозился, так что испробовал различные варианты. Смотри вот правило: # Именнованная лакация (правило) location @modx { # выполняем подмену на index.php rewrite ^/(.*)$ /index.php?q=$1 last; } Так как ЧПУ MODX-а построено полностью на реврайтах, а не на реальных файлах, именно благодаря ему все УРЛы и преобразуются в index.php Но это происходит только потому что запрашиваемый файл не найден. Но если файл будет найден, то этого преобразования не будет, а останется реальный УРЛ. И в итоге ключ /index.php не будет соответствовать никогда в этом случае. Но это конечно же ситуация исключительная, поэтому конечно ты можешь пренебрегать этим моментом и сделать так, как ты предложил — в 99% случаев оно действительно будет работоспособным. Но у меня свои тараканы в голове и я терпеть не могу неуниверсальность, поэтому у себя оставлю так.
ну в данном случае у тебя # устанавливаем ключ-переменную для запроса к мемкешу set $memcached_key "default/$uri?$args"; и все! это же касается только memcached. При чем тут реальные файлы? только лишняя переменная=index.php? в ключе
При чем тут реальные файлы? При том, что здесь используется переменная $uri. Как я писал выше, если файл не найден, то УРЛ меняется на /index.php?q=$1 Повторюсь: # Именнованная лакация (правило) location @modx { # выполняем подмену на index.php rewrite ^/(.*)$ /index.php?q=$1 last; } Так как в большинстве случаев при ЧПУ файлов тупо нет, то постоянно и происходит подмена УРЛа на index.php. При этом и переменная $uri и принимает это значение. А если файл будет найден, то $uri не будет изменена, и будет иметь значение реально запрошенного адреса. Теперь понятно? Плагин конечно я тоже упростил. Изначально он был примерно такой: $query = '/';
$query_str = str_replace('&', '&',($_SERVER['QUERY_STRING']));
if(!empty($query_vars['q'])){
$query .= $query_vars['q'];
unset($query_vars['q']);
}
else{
$query .= 'index.php';
}
$query .= "?";
$vars = array();
foreach($query_vars as $k => $v){
$vars[] = "{$k}={$v}";
}
if($vars){
$query .= implode("&", $vars);
}
$modx->log(1, print_r($query, 1));
$modx->cacheManager->set($query , $modx->resource->_output); И то, что сейчас в плагине осталось — это публичный упрощенный вариант, для которого твои замечания очень обоснованный. Но для меня мой nginx-конфиг более актуальный :-)
ну так бы сразу и сказал, что у тебя свои замуты)
у меня не замуты, а универсальность :-)
как думаешь, имеет смысл memcached на сокеты перекинуть? По идее еще прирост в скорости должен быть… вот эти настройки в обработчике меняю ('memcached_server', $options, 'localhost:11211') и по идее будет работать? или тут все сложнее устроено?
Честно скажу: сам с сокетами особо не работал. Знаю, что сокеты быстрее всяко, но настройку этого всего не делал.
подскажи как и где переключиться на сокет? пробовал в конфиге прописать как $config_options = array ( "cache_handler" => "cache.xPDOMemCached", 'memcached_server' => 'unix:///var/run/memcached/mem.socket', 'system_settings_memcached_server' => 'unix:///var/run/memcached/mem.socket', 'db_memcached_server' => 'unix:///var/run/memcached/mem.socket',
); не срабатывает нифига! хелп!)))
подключился, тут тестик небольшой сделал
Я же говорил, что с сокетами особо не заморачивался. Ты топик напиши как сокеты подключал, с какими подводными камнями столкнулся.
я пока что локально подключился и тесты провел, чтоб узнать будет ли какая выгода от такого перехода. Ты как спец по кешированию подскажи — как перевести всю систему кеширования modx на сокеты теперь? я немного не допонимаю, это именно в файле обработчика кеша нужно сделать? или еще где то нужно пилить? по идее нужна только замена $memcache->connect('localhost', 11211) на $memcache->connect('unix:///var/run/memcached/mem.socket', 0) и все должно пахать!
Так ты в исходники почаще заглядывай. Вот __construct мемкеша: $servers = explode(',', $this->getOption($this->key . '_memcached_server', $options, $this->getOption('memcached_server', $options, 'localhost:11211'))); foreach ($servers as $server) { $server = explode(':', $server); $this->memcache->addServer($server[0], (integer) $server[1]); } $compressThreshold = $this->getOption($this->key . '_memcached_compress_threshold', $options, $this->getOption('memcached_compress_threshold', array(), '20000:0.2')); То есть укажи в системных настройках memcached_server и должно все заработать. Это именно что касается memcache. И, ксттаи, там же ответ на твои проблемы с компрессией: $compressThreshold = $this->getOption($this->key . '_memcached_compress_threshold', $options, $this->getOption('memcached_compress_threshold', array(), '20000:0.2')); То же самое и для memcached: $servers = explode(',', $this->getOption($this->key . '_memcached_server', $options, $this->getOption('memcached_server', $options, 'localhost:11211'))); Только вот с компрессией у него лучше дела обстоят, так как он значение берет из системы: $this->memcached->setOption(Memcached::OPT_COMPRESSION, (boolean) $this->getOption($this->key . '_memcached_compression', $options, $this->getOption('memcached_compression', $options, $this->getOption(Memcached::OPT_COMPRESSION, $options, true)))); И, кстати, как я и предполагал, должна быть возможность в принципе отключить для него компрессию.
да компрессия бог с ней… на memcached работает и ладно. Исходники я видел, но если прописать туда 'unix:///var/run/memcached/mem.socket', 0 то не пашет! неужели ты думаешь я сначала не попробовал?)) выдает ошибку Error caching time of next auto publishing event Could not cache context settings for mgr. Could not cache context settings for web. я в коде не разбираюсь но у меня чувство что explode(':', $server) это разбор строки… и если сокет прописывать то и тут надо как то менять…
поэтому нужна твоя помощь!)
Так ты не пиши 'unix:///var/run/memcached/mem.socket', 0 Это же сразу два параметра. Пиши только unix:///var/run/memcached/mem.socket
я в коде не разбираюсь но у меня чувство что explode(':', $server) Да, это разбивка строки. Но мне сечас некогда с этим экспериментировать, я пока очень занят.
да я уже и так и сяк пробовал… Как время будет посмотри
а как то можно прописать в обработчике, чтоб он мне логи скинул в журнал чему какая переменная равна?
Так залезь в код и посмотри что чему равно.
все вроде понял что, к чему… только вот эта строчка непонятна $servers = explode(',', $this->getOption($this->key . '_memcached_server', $options, $this->getOption('memcached_server', $options, 'unix:///var/run/memcached/mem.socket'))); explode разбирает на строки — это ясно. getOption — получает параметр по ключу, но их тут сразу несколько одна в одной… вот это мне не совсем ясно… $options мы его в данном случае получаем, или наоборот формируем? мне кажется все дело в этой строке, так как я пробовал все это убирать и просто делал $this->memcached->addServer('unix:///var/run/memcached/mem.socket', 0); но не работает! может эти настройки еще где-то в modx торчат?
$options — это то, что можно передать в инициализацию объекта. В данном случае вообще на это забей. Два раза getOption(), потому что второй раз, это значение по умолчанию. Разбей на два раза, чтобы понятней было. $servers = explode(',', $this->getOption($this->key. '_memcached_server', $options, $this->getOption('memcached_server', $options, 'unix:///var/run/memcached/mem.socket'))); Это буквально так: $servers_default = $this->getOption('memcached_server', $options, 'unix:///var/run/memcached/mem.socket');
$servers_str = $this->getOption($this->key . '_memcached_server', $options, $servers_default);
$servers = (array)explode(',', $servers_str); То есть может быть указано несколько серверов. Укажи memcached_server в настройках и все.
ну я логически так и додумал, но ошибка все таже — Error caching time of next auto publishing event Could not cache context settings for mgr. Could not cache context settings for web. вот у меня чувство что где то еще — localhost:11211 торчит по умолчанию…
Вот и ковыряй. Думаешь у меня всегда все сразу получается? Нет, иногда часами сидишь воюешь, а иногда и днями.
тогда может на $options всетаки нельзя забивать? он ведь у нас в каждой функции идет $options= array()) либо еще какая то фигня мешает работе с сокетами либо я хз
у меня к тебе одна просьба будет — можешь в своем обработчике закомментировать строчку вот эту $this->memcached->setOption(Memcached::OPT_COMPRESSION, (boolean) $this->getOption($this->key . '_memcached_compression', $options, $this->getOption('memcached_compression', $options, $this->getOption(Memcached::OPT_COMPRESSION, $options, true)))); сбрось кеш и посмотри какую ошибку выдаст. спасибо!
Мне реально сейчас не до этого. Так что будь настоящим джедаем и воюй до последнего сам.
порадовал)))
все разобрался, все правильно я прописывал, надо было просто чуток подождать. настройки тоже кешировались и мои изменения с кешером не сразу применялись. сейчас все по новой прописал, подождал 5 минут — и все ок! Работает!)
и насчет компрессии ты был прав, можно прям в кешере указать, а не лезть в системные настройки-тоже пашет! p.s. и может конечно это кажется только, но админка вроде еще шустрее стала!)
новый косяк обнаружил. если сайтов несколько, а кеш получается обший, то они в кеше перезаписывают настройки друг друга. Это я имею ввиду не кешированные странички, а именно работу в админке. то есть надо какой то общий ключ вводить для сайта по типу site_name… добавить системную настройку cache_prefix и все работает!
единственное при очистке кеша — очищается кеш сразу у всех сайтов, тогда либо вешать на каждый сайт по отдельному сокету, и все будет работать независимо, либо если сайты небольшие то я думаю можно на это дело забить…
Вот и славно.
Админка будет шустрее работать, так как каждый Ajax-запрос — это инициализация MODX-а со всеми конфигами и т.п. А раз они в кеше, то хоть чуть-чуть, но быстрее все.
Так про cache_prefix вообще забывать не стОит.
Вот это уже точно не скажу.
Проверка на GET чтобы если отправили форму не кешировалась страница с ответом. Но это как раз и не стоит делать. Ведь GET — это в том числе и постраничность и прочие моменты, включая гет-поиск. Все, что не должно кешироваться — надо выносить в Ajax. Либо предусматривать какой-то GET-параметр типа nocache=1, чтобы явно указывать, что ее кешировать не надо. Если добавится в запрос этот параметр, для нгинкса это уже будет новый адрес, и он отправит запрос на MODX. MODX не сформирует полный кеш страницы в мемкеш, а значит и нгинкс все время будет отдавать не кешированную страницу.
Приветь! Николай настроил по заметкам! html контент работает но в админке вот таки логи ошибок [2016-03-12 15:23:52] (ERROR @ /index.php) Key: '/index.php?q=news/1453/' [2016-03-12 15:23:54] (ERROR @ /index.php) Key: '/index.php?' [2016-03-12 15:25:26] (ERROR @ /index.php) Key: '/index.php?'
Привет. Удали $modx->log(1, «Key: '{$key}'»); Это для отладки было.