LINUX.ORG.RU

Запуск дополнительных процессов(задач) в PHP

 , , , ,


1

2

Добрый день, вечер, утро.

Просто интересно ваше мнение. Действия ведутся на территорий подвластной ПХП.
Есть большой шматок кода, в одном месте нужно добавить дополнительно код обработки(чистки, задачи, ну скажем считает баранов) который никак не связан с основным кодом. При этом максимально никак не повлиять на скорость и ресурсозатраты того процесса. Скажем так: страница должна после того блока кода много чего еще сделать и вернуть результат клиенту.
Ну наверное можно процесс(форкнуть, родить новый), создать задачу(task) для обработчика(gearman) на этом или другом сервере, в другом потоке, добавить в memcache данные чтоб что-то в другом месте читала и пахала, магия или ...
Главное чтоб этот код максимально не влиял на ресурсы и время выполнения кода который его возбудил.

Спасибо за внимание
Как это лучше сделать?

Самое простое решение. В старом коде делаем

<?php

//...

// Сохраняем данные для последующей обработки отдельным процессом
file_put_contents('/tmp/tasks/'.date('Ymd-His-').uniqid(), json_encode(['some' => 'data']));

// ...


где в json_encode засовываем нужные для последующей работы данные.

В консоли отдельно вешаем что-то типа:
#!/bin/bash

inotifywait -m --format '%w%f' -e moved_to,close_write /tmp/tasks/ | while read -r line
do
    php do-task.php "$line"
done


И в do-task.php:
<?php
require 'vendor/autoload.php';
require 'config.php';

$file = $argv[1];

if(!is_file($file))
    return;

$data = json_decode(file_get_contents($file), true);

// тут что-то делаем с этими данными
// ...
// сносим ненужный файл с задачей
unlink($file);


Более сложные варианты — класть запросы в БД/MQTT/Redis и разбирать их в несколько потоков. Но там будет заметно сложнее, так как по уму нужно уметь корректно обрабатывать ошибки и реагировать на них нужным образом — у нас файл с ошибкой автоматически окажется необработанным и его можно будет обработать потом вручную.

KRoN73 ★★★★★
()
Последнее исправление: KRoN73 (всего исправлений: 1)
Ответ на: комментарий от r_asian

Петросян
Легаси код на нем, ничего не поделать, да и нормально все работает.
Нужно просто каким то образом выполнять дополнительные работы. А их можно хоть не C# делать, там вопрос уже не в языках и инструментах

zipzipzip
() автор топика
Ответ на: комментарий от KRoN73

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

Какие еще есть варианты? Нужно чтоб девушка родила и при этом не заметила как залетела

Скорее всего буду делать почти как вы сказали. Посмотрим что еще могут предложить люди
P.S.: вот я извращенец однако

zipzipzip
() автор топика
Ответ на: комментарий от Deleted

/thread

Еще не закрыт. Пока только один человек нормально написал. Надеюсь есть еще идей у людей

zipzipzip
() автор топика
Ответ на: комментарий от zipzipzip

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

Jaberwock ★★★
()

Как уже было сказано выше KRoN73, самый простой вариант, в общем случае - просто передавать куда-бы то ни было данные для обработки + любым скриптом запускать отдельный php-процесс. Ресурсы на выполнение новой задачи, вам не обязательны как я понял, ведь:

При этом максимально никак не повлиять на скорость и ресурсозатраты того процесса.

То есть вы боитесь только за родительский процесс? А выбор уведомления через БД / запись в файл / memcached|redis|etc будет простой экономией на спичках. Как было верно подмечено, вариант с файлом будет одним из самых простых в реализации, хоть относительно и не самым надежным. По поводу ваших сомнений, правильно, это не самое лучшее решение. Но ведь вам необходимо наиболее простое решение? Все зависит от более четкой постановки задачи. Может быть, вам требуется постоянно выполнять какие-то действия над данными, которые будут уходить в большом кол-ве, и требовать больших ресурсов для обработки, тогда, скорее всего, вам придется задуматься о написании какого-либо сервиса RESTful на более производительном языке, к которому вы будете посылать запросы с помощью того же curl, например. Но, как видите, это будет уже намного сложнее. Поэтому, тут либо более конкретное описании задачи, либо, решение, которое вам предложил KRoN73.

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

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

zipzipzip
() автор топика
30 января 2016 г.

форкнуть

Только в cli. Будешь форкать процессы демона пхп - быстро упрешься в максимальное кол-во воркеров и положишь сайт.

Если я правильно понял задачу, то тебе нужны очереди. Возьми тот же rabbit, с вебморды отсылай сообщения, в скрипте-слушателе, который работает постоянно, это сообщения обрабатывай.

drull ★☆☆☆
()
Последнее исправление: drull (всего исправлений: 1)
Ответ на: комментарий от drull

Да, для задач в основном используем gearman. Так же и rabbitmq будет, но она уже будет чуток для других задач.

Именно в этом моменте запили схожее как предлагал KRoN73. Вроде бы сервер не нагружается. И так сойдет.

По затратам еще толком не смотрел, надо будет разобраться как смотреть ресурсозатраты на рабочих серверах и посчитать все. Сухие бенчмарки думаю не интересны

zipzipzip
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.