По большей части я не люблю докер, потому что субьективно мне было проще поднять сервер и установить туда nginx/php/mysql/supervisor, а далее обычным образом запускать воркеры через proc_open из главного воркера.
Сегодня мне лид сказал, что докер сам по себе супервайзер, и потому один файл Dockerfile чем-то похож на файл конфига supervisor. То есть как он сказал "нет возможности из процесса, поднятого в докере запускать под-процессы" - то есть когда работаешь с докером вопрос поднятия нескольких обработчиков для очередей - это проблема в плане создания множества dockerfile и тд.
Может кто-то пояснить простейший способ организовать чтение очереди в несколько стримов и обработка сообщений подымая пхп скрипты, чтобы выполнить консольную команду, и обеспечивая, разумеется, "если неудача, то получить сообщение из очереди заново и опять поднять процесс и сделать по новой" позже.
Román Mirilaczvili, ты чтобы 100 заказов обсчитать 100 файлов Dockerfile копируешь и запускаешь по одному? Причем тут рутина? Из дочернего процесса создавать родительский проблема, а не файлы копировать блин
Идея то в чем в итоге? На каждый обработчик пишем один докер файл и подымаем по нему процесс? Плюс один главный докерфайл для воркера-диспетчера, который будет их подымать реагируя на входящее в очереди?
Условно если я хочу поднять 5 очередей, то на каждую очередь пишу докерфайл, потом запускаю 5 процессов и каждая из них пошла работать со своей очередью, так?
Может кто-то пояснить простейший способ организовать чтение очереди в несколько стримов и обработка сообщений подымая пхп скрипты, чтобы выполнить консольную команду, и обеспечивая, разумеется, "если неудача, то получить сообщение из очереди заново и опять поднять процесс и сделать поновой" позже.
А как бы ты выполнил это без Docker? В чем же сложности сделать тоже самое с оным?
обработчики очереди - они относительно долгоживущие процессы.
Román Mirilaczvili, Пока на самом деле не знаю откуда там проблема, мне лид сказал.
Если бы я делал примитивную очередь на редисе, я бы в коде своего контроллера подрубился к очереди редиса, отправил сообщение. До этого я бы написал консольную команду для пхп приложения, которая запускает while (true) и в середине в каждом шаге с паузами по 1 секунде проверял бы что там в очереди пришло не пришло, обрабатывал и возвращал бы результат. Если результат косяковый или кривой - добавлял бы исходное сообщение обратно в очередь, чтоб повторить (как с курлом, если неверный ответ, просто запускай курл еще раз с другой проксей например). Современные очереди типа Nats уже умеют в Consumer, который по сути точка слива сообщений, где они хранятся и сами перезапускаются если нет подтверждения "обработано", но смотрим дальше...
При этом (предположим приложение безбраузерное, а только консольное) - я бы сначала выполнил команду "подыми воркер", потом выполнил команду "сделай действие". ВОРКЕР (висящий) зацепил бы сообщение, полученное из КОМАНДЫ и вот тут магия - ЗАПУСТИЛ БЫ ТРЕТИЙ ПРОЦЕСС (в смысле - нам что, надо копировать Dockerfile зачем-то здесь?) избегая простоя от синхронного выполнения.
Отчего фраза лида "там есть проблема" приобретает смысл на тему "чтобы третий запустить" - там получается третий докер файл должен быть, по которому выполняется не просто "php child.php", а "docker exec" ? То есть по сути зачем докер файл если это разовая операция, сделал, ответ получил, потушил, не надо там демон никакой.
То есть если слушатель подымается в начале, команда - вручную либо если браузер - то из nginx, то откуда берется третий, когда докер? В обычных условиях я бы внутри второго воркера сделал бы proc_open и поднялся бы новый процесс, хоть 100 процессов. Но если я правильно понял ПРОБЛЕМУ, то работая в докере так нельзя?
А, кажется уловил, сам по себе вызов proc_open() тоже синхронный. Стало быть если я даже в цикле сделаю пять раз proc_open() то выполняться будут по-очереди. А чтобы параллельку сделать как-минимум придется подключить react/async либу. Но это не про докер, это и в самой пыхе так.
А вопрос поднять третий процесс по прежнему вопрос - в докере это как-то иначе делается, чем просто вызвать proc_open из worker-диспетчера, пусть даже в React\Async\parallel() ?
поды сервисы маршрутизация масштабирование балансировка нагрузки ингрес синхронизация и все все все
к сожалению
ваш сценарий что то многовато форков
думаю что то с ним не так
сергей кузьмин, то есть команды из 10 человек для которых нанимали моего лида, чтобы он им показал куда там нажимать, тратили полгода, чтобы вьехать в кубы, а вы предлагаете мне их побыстрому "посмотреть"???
я знаю что это неизбежно.
я пытаюсь понять принцип прежде чем изучать кубы. в этом и суть вопроса.
Есть очередь 'commands.booking', туда могут прилетать тысяча команд типа "commands.booking.post.123" или "commands.booking.put.123", пусть будет - в час.
Разгребать одним воркером (под воркером я понимаю скрипт-демон) эту очередь - это бред. Разгребать в параллельке сотней воркеров - бред еще больший.
Идея как бы в том, чтобы один воркер (диспетчер) читал очередь по 10-15 записей и раскидывал её на исполнители, желательно параллельные.
И поднять 10 демонов, чтобы все присосались в очередь и конкурировали кто быстрее считает пришедшее сообщение, а то того и гляди считают вообще все, очередь то не редисовая, а хранит "последнее" пока вручную не пометишь в "обработано", это ерунда полная.
Демон 1, исполнителей - куча. Исполнители все не опишешь же докер файлами. Демон можно описать. А параллельку?
про message queue не уверен но из аналогии с веб реквестом кажется что в каждом контейнере процесс должен уметь читаь ровно одно сообщение и завершаиться обработав ее
ничего больше делать не должен
если умеет не заврешаться а опять узнвавать есть ли и одно сообщение из очеди брат то конечно делать так но не так как вы хотите "все сразу"
а то что я упоминал про сервис то бишь лоад балансер раздавать - но это наверное только для веба важно так как урл транслировать не обязательно с очередями
"нет возможности из процесса, поднятого в докере запускать под-процессы"
Это неправда. Те же самые nginx и php-fpm запускают мастер процесс и стартуют кучу своих воркеров как отдельные процессы.
Простейший способ сделать то что вы хотите - запустить скрипт внутри контейнера
docker run -d -v /home/project:/var/www php:8.1-cli php /var/www/worker.php
В дальнейшем если воркер упадет, докер его перезапустит. И таких docker run команд выполняете столько, сколько хотите одновременно работающих воркеров.
Спамим proc_open($cmd, $spec, $pipes) + stream_set_blocked($pipes[0], false)? Под них не пишут конфиги докеровские?
Или react/php + Loop::get()->run()?
Получается сие работает в рамках одного процесса, значит лимит памяти может исчерпаться по мере числа тредов, в этом беда основная? (лид сказал трабла, какая - ему пояснить не удалось, и мне не понятно, судя по вашему ответу - тоже траблы нет)
Григорий Васильков, ну так запускайте каждый чилд в отдельном контейнере:
docker run -d -v /home/project:/var/www --name child1 php:8.1-cli php /var/www/worker.php
docker run -d -v /home/project:/var/www --name child2 php:8.1-cli php /var/www/worker.php
docker run -d -v /home/project:/var/www --name child3 php:8.1-cli php /var/www/worker.php
docker run -d -v /home/project:/var/www --name child4 php:8.1-cli php /var/www/worker.php
Спамим proc_open($cmd, $spec, $pipes) + stream_set_blocked($pipes[0], false)? Под них не пишут конфиги докеровские?
Не нужны отдельные Dockerfile для этого. Слежение за процессами, запущенными через proc_open, - это проблема скрипта, а не докера. В данном случае скрипт у вас получается самописным аналогом supervisor. Если вы уверены, что ваш скрипт сможет нормально управлять этими дочерними процессами, не допускать их превращения в зомби, автоматически перезапускать упавшие - то всё в порядке. Но на мой взгляд проще запустить каждый воркер в своём контейнере без всех этих заморочек с proc_open.
Получается сие работает в рамках одного процесса, значит лимит памяти может исчерпаться по мере числа тредов, в этом беда основная? (лид сказал трабла, какая - ему пояснить не удалось, и мне не понятно, судя по вашему ответу - тоже траблы нет)
Если на докер контейнер при запуске не накладывались ограничения по памяти, то скрипту доступна вся память в системе, а значит ситуация никак не отличается от запуска скрипта прямо на хосте безо всякой контейнеризации. Так что если вдруг скрипту в контейнере не хватило памяти, то ему не хватит её и при запуске напрямую с хоста. И это снова проблема скрипта, а не докера или линукса.
Запуск процесса в докере по сути ничем не отличается от запуска процесса сразу на хосте. Вот прям одно и то же. Буквально. Единственное отличие тут только в том, что на процесс в контейнере система накладывает ограничения. Например, видна не вся файловая система хоста, а только часть.
А ещё сегодня попробовал запустить тесты из пхпшторма на их дредноуте, оно не пошло. У них оказывается тесты выполняются только из мейк-файла, иначе никак (причем никто не знает почему из мейкфайла, просто оно сработало как-то, так и запомнили). С целью это спросить - я решил ему позвонить. "Почему?" - "Потому что мы так работаем!" Эти МЫ уже просто в каждой компании, так устал...
Я вызвонил его на мит, он сказал "запушить в ветку", на вопрос "так оно же еще не работает" - услышал "ничего страшного".
Когда запушил - был унижен, что мол мой код это монолитовский код, а код правильный это не монолитовский, но какой - он показать опять не смог.
Было много демагогии на тему
"я хочу чтобы ты был членом команды"
и "в нашей стране так не работают",
и "я же вчера сказал тебе, что я от тебя хочу",
а потом "я хочу чтобы код был минимально возможным",
а потом "понимаешь, я хочу чтобы твой код работал на той платформе что я тебе дал",
а потом что код должен быть "как в ларавеле, потому что всем так удобно",
а потом "что он не хочет меня обидеть, просто я сам это неверно понимаю"
При всем при этом я постоянно задаю вопрос "покажи что ты хочешь" и постоянно снова и снова получаю набор риторики о том, что такое "умно", "красиво", "чисто" и бережно, но не вижу ни одного ценного слова в этих речах. Они не про код, а про какие-то моральные установки, которым нужно поверить, и как следствие "просто сделать свою работу".
Я сижу и слушаю этот противоречивый набор пустых и ненужных оценок и похоже, совершенно всё понимаю.
Докер контейнеры писал "кто-то" и "когда-то", работает "никак", времени ни у кого нет, баги исправляются путем "мне удалось", в глубину никто не лезет, "в пхп есть проблемы поэтому мы идем в GoLang" и "я обучал целые команды и 20 лет уже этим занимаюсь".
Прям тебе целый набор установок по списку "я читал хабр, поверил всему сразу, поверь и ты".
Вот если бы он еще мог словами объяснить что он хочет, то я бы поверил, что он 20 лет разных людей обучает. Я в жизни обучил 4 разработчика всего "от тракториста до мидла". И я блин понимаю, когда нужно объяснить другим языком. Но это обучало 20 лет целые команды и не может тупо пояснить чего хочет - всё я понял. Улыбаемся и машем до ближайшей фразы "почему ты просто киваешь но не делаешь" и забираем доки.
Нет никакой проблемы в создании N контейнеров с воркерами, балансировке между ними и масштабировании количества воркеров в зависимости от нагрузки - это называется уже не особо даже модным термином "оркестрация". Понятно, что "субьективно вам проще" - но добро пожаловать в 2022 год.
Григорий Васильков, я очень часто так отвечаю. Потому что спрашивающие, скажем, интересуются, как им лучше ловить рыбу - руками или сделать из палки острогу? Между тем человечество давно придумало спиннинги, сети - а то и прямо в магазине можно рыбу приобрести. Но не все про это в курсе - как тут не проинформировать?
ky0, и снова риторика, которая не дает ответ на вопрос и пытается выехать на метафорах, что ответ был дан, просто я дурак. я признаю что дурак, иначе б вопрос не задал. Зачем вы продолжаете мне показывать, что я не знаю, когда я сам пришел и сказал не знаю - я бы спросил, но вот это уже я знаю.
Это вроде понятный вопрос, и метафоры тут не нужны.
Вопрос - какие особенности работы с хендлерами, когда используем докер, чтобы не повесить в синхронную работу диспетчер этих самых хендлеров, который является воркером?
Лид говорит, что спамить процессы в пыхе проблема, они дескать поэтому любят GoLang, потому что там это легко. Я пытаюсь понять почему в пыхе это проблема. Всё.
Лид говорит, что спамить процессы в пыхе проблема, они дескать поэтому любят GoLang, потому что там это легко. Я пытаюсь понять почему в пыхе это проблема. Всё.
Это особенность не только и не столько РНР, сколько докера - предполагается, что один контейнер - один процесс. Можно сделать и по-другому, но любой нормальный девопс-инженер вам сразу скажет, что это кривота.
Хотите делать пачку процессов - лучше не используйте контейнеры приложений, подумайте насчёт другой технологии, контейнер ОС, виртуалку и т. д.