Статьи

Асинхронная обработка в PHP

PHP имеет особый подход к генерации веб-страниц (и, как следствие, к генерации веб-приложений). Его общая природа «ничего» делает PHP-скрипты связанными с входящим HTTP-запросом, на который они отвечают, так что они не только не могут сохранять структуры данных в памяти между различными запросами без повторения сеансов или кэшей, но и не могут запускать определенные подпрограммы в заранее определенную дату или время, в основном потому, что нет гарантии, что HTTP-запрос прибудет только для того, чтобы вызвать их в нужный час.

Архитектура без совместного использования ресурсов также является одним из факторов, делающих PHP очень масштабируемым, поскольку сценарии PHP можно реплицировать на разные серверы, не создавая устаревших данных, хранящихся в памяти разных машин. Когда нам нужно переместить обработку за пределы HTTP-запросов или запланировать действия для выполнения на определенную дату или время, мы должны вернуться к решениям, которые работают вне среды PHP (но которые могут обернуть только те сценарии PHP, которые выполняют реальное действие). Хотя обычно веб-сервер поддерживает пул процессов для быстрого реагирования на запросы, они отвечают только на внешние события и не имеют автономии.

Человеческое решение

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

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

хрон

cron — классический планировщик заданий для платформ Unix. Хотя для его конфигурации обычно требуются права доступа root, многие службы общего хостинга предоставляют поддержку cron через настройку с панели управления.

Конфигурация cron позволяет запускать команду в указанное время, если запущен демон cron. Например:

0 12 * * *  php /var/www/command.php

будет запускать command.php каждый день в 12:00. Это стандартное автоматизированное решение для периодического выполнения сценариев.

Необходимость использования cron-подобных функций в службах общего хостинга, которые не предоставляют доступ к этой службе, проложила путь для взломанных решений, таких как модуль Poormanscron для Drupal, который впоследствии был интегрирован в ядро ​​Drupal 7. По сути, это Модуль проверяет время получения HTTP-запросов и запускает действия cron, если он соответствует определениям (но он требует, чтобы по крайней мере HTTP-запрос был получен в заданный интервал времени).

Gearman

Gearman — это решение, которое набирает обороты в мире PHP, и я только что присутствовал на лекции об этом на конференции phpDay, которую провел Феликс де Флигер из iBuildings. По словам его официального сайта, Gearman

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

Имя Gearman — это анаграмма менеджера, потому что она говорит другим, что делать, фактически ничего не делая самостоятельно. Когда работает немецкий сервер заданий (опять же, это решение, которое может быть затруднено для сред общего хостинга), к нему можно получить доступ на стороне клиента или рабочего с помощью API почти на любом языке, и, конечно, на PHP.

Является ли Gearman заменой cron? Еще нет. Инфраструктура Gearman предназначена для аутсорсинга задач нескольким работникам, поэтому сценарии PHP могут немедленно возвращать ответ пользователю, не дожидаясь завершения тяжелой операции, такой как обработка загрузки файла. Тем не менее, мы по-прежнему говорим об асинхронной обработке, если выполняемые операции не выполняются, пока HTTP-ответ отправляется веб-клиенту.

Конечно, вы можете реализовать некоторые из тех же функций Gearman посредством разветвления процесса PHP, но Gearman представляет собой стандартизированную среду, которая отделяет рабочих (которые выполняют задачу) от клиентов, что приводит к гораздо более универсальному и масштабируемому решению. А код для использования Gearman с клиентской точки зрения прост:

$client= new GearmanClient();
$client->addServer("localhost", PORT);
echo $client->do("operationName", "Argument");

Существует множество вариантов использования Gearman: Zend Framework теперь использует его для выполнения перехватов после фиксации без задержек взаимодействия с коммиттером (на самом деле это перехваты после получения, поскольку в качестве системы управления исходным кодом используется Git.) Gearman поддерживает оба синхронных вызова. Как показано в примере кода, и фоновые вызовы, которые возвращаются немедленно и выполняются в фоновом режиме.

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