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



FastCGI


FastCGI — клиент-серверный протокол взаимодействия веб-сервера и приложения (один из вариантов подключения PHP к веб-серверу), развитие технологии CGI. Его лучше использовать в связке с Nginx. PHP-fpm (FastCGI контейнер для PHP) и Nginx по умолчанию поддерживают совместную работу.

Кроме того FastCGI обеспечивает дополнительную безопасность, как например запуск FastCGI-процесса под пользователем, отличным от пользователя веб-сервера.

FPM (Менеджер процессов FastCGI) — альтернативная реализация PHP FastCGI, имеющая дополнительные возможности, которые обычно используются для высоконагруженных сайтов.

Возможности включают в себя:
— продвинутое управление процессами с корректной процедурой остановки и запуска;
— возможность запуска воркеров с различными uid/gid/chroot-окружением, а также запуска на различных портах с использованием разных php.ini;
— логирование стандартных потоков вывода и ошибок;
— аварийный перезапуск в случае внезапного разрушения opcode-кэша;
— поддержка ускоренной загрузки;
— «slowlog» — логирование необычно медленно выполняющихся скриптов (не только их имена, но также и их трассировки);
— fastcgi_finish_request() — специальная функция для завершения запроса и сброса всех буферов данных, при этом процесс может продолжать выполнять какие-либо длительные действия (конвертирование видео, обработка статистики и т.п.).

Zend OPcache


Zend OPcache обеспечивает более быстрое выполнение PHP кода, посредством кэширования и оптимизации. Он улучшает PHP производительность, сохраняя скомпилированный байт-код в разделяемой памяти. PHP открывает файл с кодом, компилирует его, затем выполняет. Но с учетом того, что файлов бывает слишком много, процесс их открытия, чтения и компиляции проходит медленно и долго. Если же файлы не меняются, достаточно сделать компиляцию единоразово и закэшировать результат.

Собственно, что и делает модуль OРсache. Результат первой компиляции будет сохранен в кэш, с которым и будет работать PHP. Когда файлы изменяются, модуль сам сбросит кэш и обеспечит перекомпиляцию. Это сэкономит время и ресурсы. Упрощенный процесс компиляции и есть оптимизация.

Кэширование


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

Наиболее популярным решением для кэширования является Memcache. Данное ПО простое в использовании и достаточно быстрое, поскольку поддерживает только самое необходимое.

При кэшировании особо тяжелых запросов, выполнение которых занимает более нескольких секунд, порой возникают проблемы. По истечению времени кэша, таких тяжелых запросов вместо одного, может быть выполнено сразу несколько. Избавится от подобной проблемы можно с помощью методики дублирования ключей. Для каждого тяжелого запроса создается не один, а два ключа:
— основной ключ (после выполнения запроса сюда сохраняется результат со стандартным ttl);
— дополнительный ключ (сюда сохраняется результат запроса, но ttl устанавливается больше, чем у основного ключа. Больше на время выполнения запроса плюс небольшой запас).

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

Сессии


PHP по умолчанию хранит сессии в файлах. Эффективное решение до того момента, пока файлов не становится слишком много (десятки тысяч). Тогда работа с ними будет замедляться в рамках одной папки и лучше перенести сессии на Memcache (php.ini).

session.save_handler = memcache
session.save_path = «tcp://localhost:11211»

# localhost:11211 это стандартный хост и порт Memcache

Оптимизация кода


ООП — медленная методология. Объекты нужно создавать, где-то хранить и уничтожать. Если объекты не нужны, их не стоит использовать. Это лишь бессмысленно израсходует ресурсы. Как на примере:

<?

# $posts = список объектов Post, не понятно как полученных
foreach ( $posts as $post )
{
	echo $post->title . '<br/>';
}


Когда потребности в объектах нет, лучше использовать массивы:


<?
$posts = mysql::query('SELECT title FROM posts');
foreach ( $posts as $post )
{
	echo $post['title'] . '<br/>';
}



Детали


Дабы избежать лишних операций поиска файла, стоит использовать абсолютные пути:

<?
include '/var/www/file.php';
file_get_contents('/var/www/dir/data.txt');


Если возможно, лучше использовать функции работы со строками вместо регулярных выражений:

<?
strpos($post['title'], 'функция');


И строки с одинарными кавычками:

<?
$post['title'] = 'Не происходит дополнительная обработка переменных'


PHP cron-скрипты


Когда PHP используется для разработки скрипта, который будет выполняться по крону, следует избегать глобальных переменных:

<?
while ( true )
{
	$rss = file_get_contents('http://somesite.com/rss');
	preg_match_all('/title>(.+?)<\/title/', $rss, $matches);
}


Переменная $matches передается по ссылке. Это значит, что с каждым новым повторением, она будет расти.

Или использования общего массива:


<?
while ( true )
{
	$rss = file_get_contents('http://somesite.com/rss');
	$has_something = preg_match('/title>(.+?)<\/title/', $rss);
	if ( $has_something ) $updates[] = time();

	$rss = file_get_contents('http://othersource.com/rss');
	$has_something = preg_match('/title>(.+?)<\/title/', $rss);
	if ( $has_something ) $updates[] = time();
}


Подытожив выше написанное, вот основные моменты:
— для экономии ресурсов и ускорения процесса лучше использовать OPсache для PHP;
— пользоваться FastCGI;
— кэшировать медленные участки кода;
— не забывать о важных мелочах.

Комментарии (0)