Импорт товаров через rabbitmq

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.28, 22:58
slo_nik писал(а): 2022.01.28, 20:27 Для большинства задач, как я понимаю, достаточно будет exchenge с типом direct?
Да, для одной очереди всё равно, какой маршрутизатор.
Для одной, а если их несколько, как я планирую сделать?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.29, 02:02 Для одной, а если их несколько, как я планирую сделать?
Для нескольких нужен с типом x-random, как я и сказал.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.28, 20:06 ... чтобы он привязал все очереди автоматом к одному exchange. И потом все сообщения отправлять только в первый Yii::$app->queue1->push(...).
Я правильно понял, что в конфиге несколько очередей, при отправке в очередь задачи указать только первую очередь, а дальше автоматически будет распределено по очередям?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.29, 16:33 Я правильно понял, что в конфиге несколько очередей, при отправке в очередь задачи указать только первую очередь, а дальше автоматически будет распределено по очередям?
Думаю да, если нескольким указать один и тот же exchange, то они все привяжутся к нему одному.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.29, 16:39
Ещё такой момент.
Сейчас все товары в одном файле записаны как json строка.
Запускается обработка импорта, json переводится в массив.
Полученный массив разбить на равные части и по очереди скормить очередям.
Как только последняя часть будет отправлена в очередь файл удаляется.
Каждая такая часть уже будет в rabbit-e и он сам будет обрабатывать эти данные.

Если какую-то часть не получится почему-то обработать, ошибка или что-то ещё. Каким путём можно это будет узнать? Как правильно это сделать? И, если произошла ошибка, то как можно сохранить именно данные по этой части импорта, чтобы не гонять опять весь массив данных с товарами? Чтобы не получилось как сейчас, если очередь отвалится по timeout, то заново стартующая очередь опять начинает всё сначала.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.29, 16:39
К товарам ещё прилагаются изображения. Сейчас я отключил (удалил из кода) запуск очереди для загрузки изображений.
Как лучше поступить с загрузкой изображений?
Вариант записи в базу ссылки на изображение на стороннем ресурсе не устраивает. Нужен вариант с загрузкой изображения в своё хранилище.

В старом коде собирались все ссылки на все изображения, после завершения импорта товаров запускалась очередь для загрузки изображений. Изображения загружались и сразу производился rezise всех изображений. Это отнимает очень много времени, особенно resize. И получается то, о чём я написал в предыдущем сообщении. Очередь отваливаться по timeout, запускается вторая(третья и т.д.) попытка и начинается всё с начала. Те изображения, которые успели загрузиться и обработаться при предыдущей попытке опять грузятся, но уже не выполняется resize.

Что Вы посоветуете в этом случае?

И вопрос не совсем в тему.
Сейчас изображения обрабатываются средствами php(resize). Но читал о том, что можно эту операцию выполнять при помощи nginx. Имеет право на жизнь такой подход в моём случае?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.29, 17:08 Если какую-то часть не получится почему-то обработать, ошибка или что-то ещё. Каким путём можно это будет узнать? Как правильно это сделать?
RabbitMQ работает с подтверждением по Ack. Если какая-то задача отвалилась или отвалился воркер, то он отправит её на выполнение ещё раз. Узнать об ошибках можно из логов.
slo_nik писал(а): 2022.01.29, 17:08 И, если произошла ошибка, то как можно сохранить именно данные по этой части импорта, чтобы не гонять опять весь массив данных с товарами?
Как раз для этого разбивайте импорт на мелкие задачи с маленькими массивами по 10..50 элементов. Мелкую задачу в случае ошибки будет не так напряжно гонять повторно.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.29, 17:22 Это отнимает очень много времени, особенно resize. И получается то, о чём я написал в предыдущем сообщении. Очередь отваливаться по timeout, запускается вторая(третья и т.д.) попытка и начинается всё с начала. Те изображения, которые успели загрузиться и обработаться при предыдущей попытке опять грузятся, но уже не выполняется resize.

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

То есть вместо одной мегазадачи с массивом из 1000 изображений отправьте в очередь 1000 поштучных микрозадач для загрузки 1 изображения.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.29, 22:46 RabbitMQ работает с подтверждением по Ack. Если какая-то задача отвалилась или отвалился воркер, то он отправит её на выполнение ещё раз. Узнать об ошибках можно из логов.
Но это же не может продолжаться до бесконечности? Надо же будет как-то и на сайте отобразить, что произошла ошибка и импорт не удался.
Может же сложиться такая ситуация, что сервер будет недоступен. Задачи будут висеть в rabbitmq. Подключать websoket для этого?

Предыдущий разработчик как-то странно, на мой взгляд, решил задачу по отслеживанию состояния импорта. Сделано это через ajax запросы на сервер, каждые пять секунд.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.30, 01:02 Но это же не может продолжаться до бесконечности?
В yii2-queue для настройки максимального числа повторов есть параметр attempts.
slo_nik писал(а): 2022.01.30, 01:02 Надо же будет как-то и на сайте отобразить, что произошла ошибка и импорт не удался.
Может же сложиться такая ситуация, что сервер будет недоступен. Задачи будут висеть в rabbitmq. Подключать websoket для этого?
Да, если нужно отображать результат в реальном времени, то при работе с очередью желательно посылать уведомления через WebSocket. Например, подключить сокет-сервер Centrifugo и помимо записи в лог отправлять сообщения в него.
slo_nik писал(а): 2022.01.30, 01:02 Предыдущий разработчик как-то странно, на мой взгляд, решил задачу по отслеживанию состояния импорта. Сделано это через ajax запросы на сервер, каждые пять секунд.
Если не хочется подключать WebSocket, то как простой компромисс можно делать и так.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.30, 06:06
В yii2-queue для настройки максимального числа повторов есть параметр attempts.
Да, я знаю, что можно ограничить количество повторов.
Получается, что желательно ограничивать количество попыток выполнить задание? Только я не до конца понимаю такую вещь.
Есть файл импорта с товарами, разбивается на равные части и запускается несколько очередей.
Допустим одна из очередей для этого импорта не выполнилась по какой-то причине. Значит для этой части импорта надо вернуть ошибку, записать её в лог. И желательно как-то обозначить, какие именно товары не записались. Есть ли возможность вернуть в ответе от rabbitmq такие данные?
ElisDN писал(а): 2022.01.30, 06:06 Если не хочется подключать WebSocket, то как простой компромисс можно делать и так.
Но тогда на сервер будет большое количество запросов. В тестовых целях запустил импорт на 15 000 товаров и количество запросов на проверку статуса импорта превысило 200 шт. и это только для одного импорта.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.01.31, 01:26 Получается, что желательно ограничивать количество попыток выполнить задание?
Да, можно при желании.
slo_nik писал(а): 2022.01.31, 01:26 И желательно как-то обозначить, какие именно товары не записались. Есть ли возможность вернуть в ответе от rabbitmq такие данные?
Вернуть нельзя. Только самому в своей задаче рядом с записью в лог записать в БД, какой товар не записался. Например, в таблицу import_errors добавлять строку (import_id, product_id, error).
slo_nik писал(а): 2022.01.31, 01:26 Но тогда на сервер будет большое количество запросов.
Верно. Если одновременных активных пользователей и импортов много, то и запросов будет много. Если же не так много, то можно потерпеть и без сокетов. Потому это и компромисс.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.01.31, 15:16 Вернуть нельзя. Только самому в своей задаче рядом с записью в лог записать в БД, какой товар не записался. Например, в таблицу import_errors добавлять строку (import_id, product_id, error).
Так сейчас и есть. Просто подумал, может получится как-то из самого rabbitmq получить данные.
ElisDN писал(а): 2022.01.31, 15:16 Верно. Если одновременных активных пользователей и импортов много, то и запросов будет много. Если же не так много, то можно потерпеть и без сокетов. Потому это и компромисс.
Значит пока так и оставлю, сокеты потом уже крутить буду.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение unknownby »

slo_nik писал(а): 2022.01.31, 20:38
Так сейчас и есть. Просто подумал, может получится как-то из самого rabbitmq получить данные.

Значит пока так и оставлю, сокеты потом уже крутить буду.
1. Для того чтобы не рандомно все же запихивать в очереди, а по порядку, можно сделать файл, в котором записывается число следующей очереди, если число 10, то скидываем на 1. Выйдет так, что в первой очереди 100 задач, а в 10ой всего 2. Если прям рандомно кидать в них. С файлами попроще, чем делать запрос в БД, но можно и в БД идти.

2. Для того, чтобы узнать какие данные обработала ваша очередь, а какие нет, просто записывайте в два файла свои задачи, в первый, то что нужно обработать, а во второй, что обработалось уже. И можно потом восстановить и начать обработку с тех данных, на которых остановились. Но тут большой гемор с этим. Нужно повозиться с файлами.

3. Для того, чтобы узнать когда отвалился сервер, зарегистрируйте метод на выключение сервера и при помощи него отправляйте сообщение в телеграм бот. https://www.php.net/manual/ru/function. ... nction.php
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

unknownby писал(а): 2022.01.31, 22:42 С файлами попроще, чем делать запрос в БД, но можно и в БД идти.
С файлами есть риск нарваться на блокировку, когда два процесса попытаются одновременно что-то записать в один файл.

И файл доступен только локально. Если запускать воркеры на нескольких виртуальных машинах, то на каждой файлы будут свои.

Так что общие данные лучше хранить в БД или подобных хранилищах.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

unknownby писал(а): 2022.01.31, 22:42 2. Для того, чтобы узнать какие данные обработала ваша очередь, а какие нет, просто записывайте в два файла свои задачи, в первый, то что нужно обработать, а во второй, что обработалось уже. И можно потом восстановить и начать обработку с тех данных, на которых остановились. Но тут большой гемор с этим. Нужно повозиться с файлами.
Записывать что именно? Товары, которые ещё не обработались?
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.02.01, 09:56
Я уже спрашивал выше по теме, но Вы не ответили на вопрос по поводу resize изображений при импорте. Предлагают рассмотреть вопрос resize при помощи nginx.
Возможен такой подход в моём случае или нет?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение samdark »

Ресайз можно и на лету делать чем-то вроде https://imgproxy.net/. Для nginx тоже модули были какие-то.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Импорт товаров через rabbitmq

Сообщение ElisDN »

slo_nik писал(а): 2022.02.01, 19:49 Возможен такой подход в моём случае или нет?
Всегда возможен. При импорте тогда нужно будет только скачать фото к себе без resize.
slo_nik
Сообщения: 344
Зарегистрирован: 2013.10.07, 19:08

Re: Импорт товаров через rabbitmq

Сообщение slo_nik »

ElisDN писал(а): 2022.02.02, 08:37 Всегда возможен. При импорте тогда нужно будет только скачать фото к себе без resize.
Получается, что если использовать этот подход, то изначально изображение загружается на сервер и хранится в оригинале.
И только если потребуется просмотр этого изображения через nginx происходит resize изображения и отдаётся клиенту.
Например. Есть 1 000 импортированных товаров, к каждому из товаров по три изображения, все эти изображения хранятся на сервере в оригиналах.
Если просматривается один товар из 1 000, то resize будет только для изображений этого товара, остальные так и останутся?

Я имел ввиду, что при импорте товаров через nginx делается resize всех изображений. Возможно такое сделать?
Или как правильно организовать загрузку и обработку изображений при импорте?
Ответить