Comments 23
из 1 входящего запроса на мой вебсайт “вырастают” под 200 запросов на API разных грузоперевозчиковя в похожей ситуации применил отдельный процесс на nodejs, он под такие задачи лучше подходит.
+3
Честно, не стал читать полностью, но похоже ваша проблема решается через cURL mutli handle
Помимо всего прочего, вам скорее всего ещё будет интересен HTTP Pipeline a.k.a Keep-Alive, который удобно реализовать для PHP через HTTP 1.1 [nginx] reverse proxy на той же машине.
Помимо всего прочего, вам скорее всего ещё будет интересен HTTP Pipeline a.k.a Keep-Alive, который удобно реализовать для PHP через HTTP 1.1 [nginx] reverse proxy на той же машине.
0
Понял за что минус, действительно я перелистнул упоминание автора об этой фиче. но для конкретной проблемы с 200 запросами из одного своего это подходит лучше. Логика получается достаточно простая, а вот запуск ведомых процессов из PHP запроса — это скорей путь к катастрофе в контексте планирования и контроля ресурсов.
Примечание: глобальный lock зависит от специфики данных и может зависеть от параметров запроса. В технологическом стеке PHP хорошо подойдёт redis distlock, хитрый лок с транзакцией на базе данных или банальный flock, если сервер только один.
- Пройти по кэшу
- Взять глобальный lock (!)
- Пройти по кэшу ещё раз (!)
- Спланировать запросы на недостающую информацию
- Подождать и обработать ответы.
- Запихнуть в кэш
- Отпустить глобальный lock
- Отдать ответы.
Примечание: глобальный lock зависит от специфики данных и может зависеть от параметров запроса. В технологическом стеке PHP хорошо подойдёт redis distlock, хитрый лок с транзакцией на базе данных или банальный flock, если сервер только один.
0
Спасибо за довольно подробный анализ!
Остается вопрос почему не взять готовое решение, коих уже куча? Они ведь уже делали такой же анализ до вас!
Вот навскидку https://github.com/symfony/process/blob/master/Process.php
Остается вопрос почему не взять готовое решение, коих уже куча? Они ведь уже делали такой же анализ до вас!
Вот навскидку https://github.com/symfony/process/blob/master/Process.php
0
Я их не нашел, видел какие-то решения на culr_multi_exec(), которые внушали 0 доверия. С Simfony я не знаком. У меня не было так много времени, и мне нужно было решить задачу не навека, а всего лишь кое-как. Если тот вебсайт пойдет вверх, то естественно я сам при первой же возможности перепишу свою асинхронность, а пока текущее решение справляется с возложенными на него обязанностями и масштабируется приемлимо для меня.
0
решения на culr_multi_exec()
Решение на culr_multi_exec не очень плохо если обращения происходят к одному сайту. Но если надо получить результаты с разных доменов то он может сильно тормозить на процедуре определения ip адреса запрашиваемого сайта.
Мне как то надо было прочитать с миллиона доменов по одной странице и это через culr_multi_exec было очень медленно. Потому что операция "Resolve hostname to IP address" не параллелится.
Запуск множества процессов php тоже не очень привлекательная мысль если нужно делать десятки тысяч запросов.
0
Об этом я даже не знал. Я у себя в конечном итоге остановился на следующем варианте: создавать дочерние curl процессы (не php и внутри него вызывать curl, а сразу "curl http://google.com"). Так у меня на каждый подпроцесс уходит 600 кб ОЗУ. Я с пхп спрыгнул на нативный curl именно для более оптимальной памяти.
0
пхп создан чтобы умирать ))
-4
Знатный костыль. Так делать не стоит. И похоже присутствует путаница между понятиями асинхронности и параллельности. Для асинхронных задач на php есть такое решение — http://reactphp.org/
Межпроцессорная коммуникация — redis, rabbitMq, beanstalkd, gearman — много их. Через stdin\stdout то же хорошо, но не так удобно.
Ну и 8 лет сидеть на одном php сам по себе плохой выбор, для приведённой задачи можно было выбрать инструменты эффективнее как на самом php (я привёл их выше), так и абсолютно другой ЯП. В моей практики задачи где просто необходимо асинхронное или параллельное выполнение кода возникают на каждом втором шагу.
Межпроцессорная коммуникация — redis, rabbitMq, beanstalkd, gearman — много их. Через stdin\stdout то же хорошо, но не так удобно.
Вообще-то, я считаю, что в 99% случаев оно не надо (и заметьте, это пишет автор статьи на тему параллелизации). Я проработал 8 лет с PHP и до прошлой недели всегда считал большой глупостью пытаться вкрутить многопоточность в PHP.
Ну и 8 лет сидеть на одном php сам по себе плохой выбор, для приведённой задачи можно было выбрать инструменты эффективнее как на самом php (я привёл их выше), так и абсолютно другой ЯП. В моей практики задачи где просто необходимо асинхронное или параллельное выполнение кода возникают на каждом втором шагу.
+5
хамелион
Ну, нет.
+3
Делал как-то тестовое задание, надо было реализовать параллельное вычисление числа pi методом Монте-Карло. Тоже сделал через proc_open(). Одним из условий была работоспособность на любой ОС, поэтому коммуникацию сделал через файлы. Результат можно посмотреть тут, может кому пригодится.
0
Судя по всему вы просто не очень технологично подошли к решению вашей проблемы. Думаю, намного более эффективно было бы просто складывать все номера на обработку в очередь, а её уже молотил бы отдельный процесс. Если правда то, что процесс создается просто, чтобы висеть и ждать, то это чрезвычайно расточительно. Судя по перечисленным "возможностям параллельного исполнения", для эффективной реализации, лучше было бы взять другой инструмент. В java, например, есть неблокирующий io, который позволяет делать обработку большого числа соединений в одном потоке, при этом никому не надо будет ждать.
+1
Я изначально понимал, что пхп предоставляет мало инструментария на эту тему. У меня задача была по-быстрому слепить решение, чтобы ответ моего пхп кода не занимал дольше 1 минуты. Я понимаю, что мое текущее решение обладает большим количеством недочетов, но на данном этапе оно закрывает все мои потребности (ответ получается генерировать приемлимо быстро, по ОЗУ оно масштабируется в рамках приемлимого, и у моего решения нет внешних зависимостей). Вебсайт, на котором это все крутится, находится на этапе прототипа, и я просто не готов был туда писать красивое решение проблемы сразу. Если я в какой-то момент почувствую, что эта часть кода становится узким местом, то я вернусь к нему и тогда уже подойду серьезно к задаче. Хехе, и тогда как раз и последую советам вашим и других людей, которые упоминали технологии и архитектуры (с этой целью я и писал статью — прощупать почву у людей о том, как они бы решали эту проблему).
0
Представляю себе, что будет, когда вы увидите, что такое goroutine в go :). Процессы в Erlang, наверное, тоже должны быть ничего.
0
На самом деле proc_open() тоже работает через системный вызов fork() в UNIX нет способа создать дочерний процесс без этого вызова. Все остальные варианты это просто обертки вокруг fork()/exec().
Но все равно на мой взгляд прекрасное решение в описанных условиях, что бы не говорили об этом другие коллеги )
Но все равно на мой взгляд прекрасное решение в описанных условиях, что бы не говорили об этом другие коллеги )
0
Не забывайте про POSIX Spawn API.
0
При разработке сервиса загрузки видео с разных видео-сервисов я это делал так:
Понимаю, что поздно, но может кто и решит использовать такую схему.
Что касается асинхронности в ПХП — тут очень философский вопрос, так что надо использовать те инструменты, которые больше для этого предназначены.
Я работал в рекламе, там большинство бэкграундовских сервисов написано на GO, с использованием горутин
- Скрипт генерит некоторый SID
- далее Скрипт передает некоторые данные в очередь + SID
- HTTP страница по AJAX опрашивает готовность задания по SID, а в это время HTTP страница показывает Клиенту некоторую анимашку
- Скрипт выполнения задач читает данные из очереди, выполняет задачу
- После выполнения задач, кладет выходные данные в кеш с ключом SID
- AJAX Скрипт опроса по SID вытаскивает из кеша данные, удаляет их и возвращает Пользователю
- Счастливый пользователь видит результаты работы долгоиграющего скрипта
Понимаю, что поздно, но может кто и решит использовать такую схему.
Что касается асинхронности в ПХП — тут очень философский вопрос, так что надо использовать те инструменты, которые больше для этого предназначены.
Я работал в рекламе, там большинство бэкграундовских сервисов написано на GO, с использованием горутин
0
Sign up to leave a comment.
Асинхронное параллельное исполнение в PHP