Статьи

Лучшая производительность — ускорение вашего сайта CakePHP

Кажется, что когда я упоминаю CakePHP сообществу разработчиков, те, кто не использовал его, думают о нем как о медленной среде. Действительно, он не самый быстрый по результатам многих тестов — «из коробки» — но то, что ему может не хватать в производительности, наверняка компенсирует быструю разработку приложений.

Применив несколько простых модификаций и даже несколько более сложных улучшений, CakePHP может быть значительно ускорен. К тому времени, как вы проработаете хотя бы половину этих изменений, производительность вашего сайта CakePHP будет сопоставима со многими другими популярными средами PHP, с тем преимуществом, что скорость вашей разработки никогда не будет колебаться!

Существует два типа модификаций, которые я буду описывать в следующей статье. Первый — это изменения кода, например, они будут работать для всех, даже если вы работаете в среде общего хостинга. Второй тип предназначен для пользователей, у которых есть собственный выделенный или виртуальный сервер, который они могут добавлять и удалять программное обеспечение по мере необходимости.

Не бойтесь, хотя, если вы можете только следовать за первым сетом, вы не будете разочарованы.

Обновление CakePHP Версии

Важно отметить, что неправильное представление людей о скорости CakePHP, вероятно, восходит к версии 1.1 или 1.2. В версии 1.3 команда разработчиков ядра провела серьезный пересмотр базовой архитектуры CakePHP. Фактически, я провел несколько тестов производительности, сравнивая версии 1.2 CakePHP с 1.3 против 2.0. Результаты были поразительными. Простое обновление с 1.2 до 1.3 привело к немедленному снижению более чем на 70% среднего времени загрузки страницы.

Если вы откладывали обновление своей версии CakePHP и по-прежнему используете версию 1.2 или менее, первое, что вы должны сделать, — это обновить хотя бы до версии 1.3, но желательно, чтобы версия 2.3.x была бы еще лучше.

CakePHP Cookbook предоставляет несколько очень подробных руководств по миграции:

Отключить режим отладки

Не смейся! Это может показаться очевидным, но в безумной схватке за перенос кода в производство очень легко забыть отключить отладку. Типичная настройка, которой я следую, — это создание нескольких файлов app / Config / core.php: один для моей локальной среды, один для dev, один для подготовки и один для производства. Эти файлы содержат различные настройки в зависимости от целевой среды.

Ключевым оператором для изменения является Configure::write('debug', 2) для Configure::write('debug', 0) .

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

Отключить рекурсивные операторы поиска

Когда вы выполняете запрос с использованием метода find() , рекурсия по умолчанию устанавливается в 0. Это указывает на то, что CakePHP должен попытаться присоединиться к любым моделям первого уровня. Например, если у вас есть пользовательская модель, которая имеет много пользовательских комментариев, каждый раз, когда вы выполняете запрос к таблице пользователей, она также присоединяется к таблице комментариев.

Время обработки при выполнении, возврате и создании ассоциативного массива с этими данными может быть значительным, и я действительно видел, как сайты CakePHP зависали в работе из-за этого!

Мой предпочтительный подход к тому, чтобы убедиться, что рекурсия по умолчанию не равна никому, — переопределить параметр в app/Model/AppModel.php , добавив следующий код:

 <?php class AppModel extends Model { public $recursive = -1; } 

Результаты запроса кеша

Это действительно моя любимая оптимизация. Я хотел бы думать, что я обнаружил это сам, но я уверен, что это будет обсуждаться, поскольку я видел, что другие статьи обсуждают подобное решение.

Во многих веб-приложениях, вероятно, существует множество запросов к базе данных, которые не обязательно нужны. Переопределив функцию find() по умолчанию внутри app/Model/AppModel.php , я упростила кеширование полных ассоциативных массивов результатов запросов. Это означает, что я не только избегаю попадания в базу данных, но даже избегаю времени обработки CakePHP, преобразующего результаты в массив. Требуемый код выглядит следующим образом:

 <?php class AppModel extends Model { public $recursive = -1; function find($conditions = null, $fields = array(), $order = null, $recursive = null) { $doQuery = true; // check if we want the cache if (!empty($fields['cache'])) { $cacheConfig = null; // check if we have specified a custom config if (!empty($fields['cacheConfig'])) { $cacheConfig = $fields['cacheConfig']; } $cacheName = $this->name . '-' . $fields['cache']; // if so, check if the cache exists $data = Cache::read($cacheName, $cacheConfig); if ($data == false) { $data = parent::find($conditions, $fields, $order, $recursive); Cache::write($cacheName, $data, $cacheConfig); } $doQuery = false; } if ($doQuery) { $data = parent::find($conditions, $fields, $order, $recursive); } return $data; } } 

Необходимо внести небольшие изменения в запросы, которые мы хотим кэшировать. Основной запрос, который выглядит так:

 <?php $this->User->find('list'); 

требует обновления для включения информации о кешировании:

 <?php $this->User->find('list', array('cache' => 'userList', 'cacheConfig' => 'short') ); 

Добавляются два дополнительных значения: имя кэша и конфигурация кэша, которые следует использовать.

Два последних изменения должны быть внесены в app/Config/core.php . Кэширование должно быть включено, и значение cacheConfig должно быть определено. Во-первых, раскомментируйте следующую строку:

 <?php Configure::write('Cache.check', true); 

Затем добавьте новую конфигурацию кэша следующим образом (обновив параметры в соответствии с требованиями для имени и срока действия):

 <?php Cache::config('short', array( 'engine' => 'File', 'duration'=> '+5 minutes', 'probability'=> 100, 'path' => CACHE, 'prefix' => 'cache_short_' )); 

Все вышеперечисленные параметры могут быть обновлены, чтобы увеличить продолжительность, изменить имя или даже определить, где должен храниться кэш.

Чтобы получить более подробное объяснение о том, как добавлять, обновлять и очищать кэш, продолжайте читать об определенной оптимизации кэширования в моем блоге .

Не считайте это концом кеширования CakePHP. Вы также можете кэшировать действия контроллера, представления и даже вспомогательные функции. Исследуйте Компонент Cache в книге CakePHP для получения дополнительной информации.

Установить кеширование на основе памяти

По умолчанию сеансы PHP хранятся на диске (обычно во временной папке). Это означает, что каждый раз, когда вы получаете доступ к сеансу, PHP должен открывать файл сеанса и декодировать содержащуюся в нем информацию. Проблема в том, что дисковый ввод-вывод может быть довольно дорогим. Доступ к элементам из памяти, в отличие от дискового ввода-вывода, значительно быстрее.

Есть два хороших подхода к дисковым операциям ввода-вывода, связанным с сеансом Первый — настроить RAM-диск на вашем сервере. После настройки диск будет смонтирован, как и любой другой диск, и session.save_path value в php.ini будет обновлено, чтобы указывать на новый RAM-диск. Второй способ — установка программного обеспечения, такого как Memcached , система кеширования с открытым исходным кодом, позволяющая хранить объекты в памяти.

Если вам интересно, какой подход лучше для вас, вы можете решить это, ответив на следующий вопрос: потребуется ли более одного сервера для одновременного доступа к этой памяти? Если да, вы можете выбрать Memcached, так как он может быть установлен в отдельной системе, позволяющей другим серверам получать к нему доступ. Принимая во внимание, что если вы просто хотите ускорить работу своего единого веб-сервера, выбор решения для оперативной памяти приятен и быстр и не требует дополнительного программного обеспечения.

В зависимости от вашей операционной системы установить Memcached можно так же просто, как набрать sudo aptitude install memcached .
После установки вы можете настроить PHP для хранения сеансов в памяти, а не на диске, обновив php.ini :

  session.save_handler = memcache
 session.save_path = 'tcp: //127.0.0.1: 11211' 

Если Memcached установлен на другом порту или хосте, измените ваши записи соответствующим образом.

После того, как вы закончили установку на свой сервер, вам также нужно будет установить модуль memcache PHP. Еще раз в зависимости от вашей операционной системы, одна из этих команд будет работать для вас:

  pecl установить memcache 

или:

  sudo aptitude устанавливает php5-memcache 

Удаление Apache и установка Nginx

Согласно последним статистическим данным , Apache по-прежнему является фаворитом, но внедрение Ngnix набирает обороты, когда речь заходит о сайтах с наибольшей посещаемостью в Интернете. Фактически, Nginx становится чрезвычайно популярной заменой Apache.

Apache похож на Microsoft Word, у него есть миллион вариантов, но вам нужно всего шесть. Nginx делает эти шесть вещей и пять из них в 50 раз быстрее, чем Apache. Крис Ли

Nginx отличается от Apache тем, что это сервер на основе процессов, тогда как Nginx управляется событиями. Когда нагрузка на ваш веб-сервер растет, Apache быстро начинает становиться нехваткой памяти. Чтобы правильно обрабатывать новые запросы, рабочие процессы Apache ускоряют новые потоки, вызывая увеличение памяти и времени ожидания, создавая новые потоки. Между тем, Nginx работает асинхронно и использует один или очень мало легких потоков.

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

В конце концов, если у вас недостаточно памяти, Nginx будет потреблять всего 20-30 МБ, тогда как Apache может потреблять до 200 МБ при той же нагрузке. Память может быть дешевой для вашего ПК, но не в том, что касается оплаты серверов в облаке!

Для более подробной разбивки между Apache и Nginx посетите страницу Apache vs Nginx WikiVS .

HowToForge имеет отличную статью для настройки Nginx на вашем сервере. Я предлагаю следовать пошаговому руководству по установке и настройке Nginx с помощью php-fpm.

Настройте Nginx для использования Memcached

После того, как вы установили Nginx и Memcached, использование их друг друга еще больше увеличит вашу производительность. Несмотря на то, что приложения CakePHP являются динамическими, скорее всего, 80-90% все еще относительно статичны, то есть они изменяются только через определенные промежутки времени.

После внесения следующих изменений в файл конфигурации Nginx Memcached начнет обслуживать ваши запросы Nginx, которые уже были обработаны и сохранены в памяти. Это означает, что только несколько запросов фактически вызовут PHP, что значительно увеличивает скорость вашего сайта.

  сервер {
     слушай 80;
     имя_сервера endyourif.com www.endyourif.com;
     access_log /var/log/nginx/endyourif-access.log;
     error_log /var/log/nginx/endyourif-error.log;
     root /www/endyourif.com/;
     index index.php index.html index.htm;

     # обслуживать статические файлы
     место расположения / {
         # это обслуживает статические файлы, которые существуют без
         # запуск других тестов перезаписи
         if (-f $ request_filename) {
             истекает 30 дней;
             перемена;
         }
         # это отправляет все несуществующие запросы файлов или каталогов
         # to index.php
         if (! -e $ request_filename) {
             переписать ^ (. +) $ /index.php?q=$1 last;
         }
     }

     местоположение ~ .php $ {
         set $ memcached_key '$ request_uri';
         memcached_pass 127.0.0.1:11211;
         default_type text / html;
         error_page 404 405 502 = @no_cache;
     }

     location @no_cache {
         try_files $ uri = 404;
         fastcgi_split_path_info ^ (. +. php) (/.+) $;
         fastcgi_pass unix: /var/run/php5-fpm.sock;
         fastcgi_index index.php;
         включить fastcgi_params;
     }
 } 

Приведенная выше конфигурация указывает, что статические файлы должны обслуживаться немедленно. Файлы PHP должны быть направлены в Memcached для обслуживания страницы, если она была кэширована. Если он не существует в кеше, @nocache местоположение @nocache которое действует как ваша предыдущая настройка PHP для обслуживания страницы через php-fpm.

Не забудьте обновить app/Config/core.php чтобы app/Config/core.php кэш memcache. Следующее:

 <?php $engine = 'File'; if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) { $engine = 'Apc'; } 

будет выглядеть так:

 <?php $engine = 'Memcache'; 

Наш код для кеширования запросов ранее также требует обновления:

 <?php Cache::config('short', array( 'engine' => 'Memcache', 'duration'=> '+5 minutes', 'probability'=> 100, 'path' => CACHE, 'prefix' => 'cache_short_' )); 

Удалить MySQL и установить Percona

Последняя модификация сервера, которую я рекомендую, — установить сборку PerSQL MySQL. Команда Percona потратила много лет на понимание и точную настройку архитектуры базы данных для оптимальной производительности. Лучше всего следовать инструкциям по установке от Percona, так как она описывает несколько различных вариантов установки.

Резюме

Существует множество методов, позволяющих CakePHP работать молниеносно. Некоторые изменения могут быть более сложными, чем другие, но не отчаивайтесь. Независимо от того, какой у вас фреймворк или язык, оптимизация обходится дорого, а способность CakePHP позволить вам быстро разрабатывать чрезвычайно сложные веб-приложения значительно перевесит усилия по оптимизации, когда ваше приложение будет завершено.

Изображение через Fotolia