Для одной, а если их несколько, как я планирую сделать?
Импорт товаров через rabbitmq
Re: Импорт товаров через rabbitmq
Я правильно понял, что в конфиге несколько очередей, при отправке в очередь задачи указать только первую очередь, а дальше автоматически будет распределено по очередям?
Re: Импорт товаров через rabbitmq
Думаю да, если нескольким указать один и тот же exchange, то они все привяжутся к нему одному.
Re: Импорт товаров через rabbitmq
Ещё такой момент.
Сейчас все товары в одном файле записаны как json строка.
Запускается обработка импорта, json переводится в массив.
Полученный массив разбить на равные части и по очереди скормить очередям.
Как только последняя часть будет отправлена в очередь файл удаляется.
Каждая такая часть уже будет в rabbit-e и он сам будет обрабатывать эти данные.
Если какую-то часть не получится почему-то обработать, ошибка или что-то ещё. Каким путём можно это будет узнать? Как правильно это сделать? И, если произошла ошибка, то как можно сохранить именно данные по этой части импорта, чтобы не гонять опять весь массив данных с товарами? Чтобы не получилось как сейчас, если очередь отвалится по timeout, то заново стартующая очередь опять начинает всё сначала.
Re: Импорт товаров через rabbitmq
К товарам ещё прилагаются изображения. Сейчас я отключил (удалил из кода) запуск очереди для загрузки изображений.
Как лучше поступить с загрузкой изображений?
Вариант записи в базу ссылки на изображение на стороннем ресурсе не устраивает. Нужен вариант с загрузкой изображения в своё хранилище.
В старом коде собирались все ссылки на все изображения, после завершения импорта товаров запускалась очередь для загрузки изображений. Изображения загружались и сразу производился rezise всех изображений. Это отнимает очень много времени, особенно resize. И получается то, о чём я написал в предыдущем сообщении. Очередь отваливаться по timeout, запускается вторая(третья и т.д.) попытка и начинается всё с начала. Те изображения, которые успели загрузиться и обработаться при предыдущей попытке опять грузятся, но уже не выполняется resize.
Что Вы посоветуете в этом случае?
И вопрос не совсем в тему.
Сейчас изображения обрабатываются средствами php(resize). Но читал о том, что можно эту операцию выполнять при помощи nginx. Имеет право на жизнь такой подход в моём случае?
Re: Импорт товаров через rabbitmq
RabbitMQ работает с подтверждением по Ack. Если какая-то задача отвалилась или отвалился воркер, то он отправит её на выполнение ещё раз. Узнать об ошибках можно из логов.
Как раз для этого разбивайте импорт на мелкие задачи с маленькими массивами по 10..50 элементов. Мелкую задачу в случае ошибки будет не так напряжно гонять повторно.
Re: Импорт товаров через rabbitmq
Также посоветую разбивать на мелкие задачи и раскидывать по нескольким воркерам. Тогда никакой долгой задачи, отваливающейся по таймауту, нигде не будет.slo_nik писал(а): ↑2022.01.29, 17:22 Это отнимает очень много времени, особенно resize. И получается то, о чём я написал в предыдущем сообщении. Очередь отваливаться по timeout, запускается вторая(третья и т.д.) попытка и начинается всё с начала. Те изображения, которые успели загрузиться и обработаться при предыдущей попытке опять грузятся, но уже не выполняется resize.
Что Вы посоветуете в этом случае?
То есть вместо одной мегазадачи с массивом из 1000 изображений отправьте в очередь 1000 поштучных микрозадач для загрузки 1 изображения.
Re: Импорт товаров через rabbitmq
Но это же не может продолжаться до бесконечности? Надо же будет как-то и на сайте отобразить, что произошла ошибка и импорт не удался.
Может же сложиться такая ситуация, что сервер будет недоступен. Задачи будут висеть в rabbitmq. Подключать websoket для этого?
Предыдущий разработчик как-то странно, на мой взгляд, решил задачу по отслеживанию состояния импорта. Сделано это через ajax запросы на сервер, каждые пять секунд.
Re: Импорт товаров через rabbitmq
В yii2-queue для настройки максимального числа повторов есть параметр attempts.
Да, если нужно отображать результат в реальном времени, то при работе с очередью желательно посылать уведомления через WebSocket. Например, подключить сокет-сервер Centrifugo и помимо записи в лог отправлять сообщения в него.
Если не хочется подключать WebSocket, то как простой компромисс можно делать и так.
Re: Импорт товаров через rabbitmq
Да, я знаю, что можно ограничить количество повторов.
Получается, что желательно ограничивать количество попыток выполнить задание? Только я не до конца понимаю такую вещь.
Есть файл импорта с товарами, разбивается на равные части и запускается несколько очередей.
Допустим одна из очередей для этого импорта не выполнилась по какой-то причине. Значит для этой части импорта надо вернуть ошибку, записать её в лог. И желательно как-то обозначить, какие именно товары не записались. Есть ли возможность вернуть в ответе от rabbitmq такие данные?
Но тогда на сервер будет большое количество запросов. В тестовых целях запустил импорт на 15 000 товаров и количество запросов на проверку статуса импорта превысило 200 шт. и это только для одного импорта.
Re: Импорт товаров через rabbitmq
Да, можно при желании.
Вернуть нельзя. Только самому в своей задаче рядом с записью в лог записать в БД, какой товар не записался. Например, в таблицу import_errors добавлять строку (import_id, product_id, error).
Верно. Если одновременных активных пользователей и импортов много, то и запросов будет много. Если же не так много, то можно потерпеть и без сокетов. Потому это и компромисс.
Re: Импорт товаров через rabbitmq
Так сейчас и есть. Просто подумал, может получится как-то из самого rabbitmq получить данные.
Значит пока так и оставлю, сокеты потом уже крутить буду.
Re: Импорт товаров через rabbitmq
1. Для того чтобы не рандомно все же запихивать в очереди, а по порядку, можно сделать файл, в котором записывается число следующей очереди, если число 10, то скидываем на 1. Выйдет так, что в первой очереди 100 задач, а в 10ой всего 2. Если прям рандомно кидать в них. С файлами попроще, чем делать запрос в БД, но можно и в БД идти.
2. Для того, чтобы узнать какие данные обработала ваша очередь, а какие нет, просто записывайте в два файла свои задачи, в первый, то что нужно обработать, а во второй, что обработалось уже. И можно потом восстановить и начать обработку с тех данных, на которых остановились. Но тут большой гемор с этим. Нужно повозиться с файлами.
3. Для того, чтобы узнать когда отвалился сервер, зарегистрируйте метод на выключение сервера и при помощи него отправляйте сообщение в телеграм бот. https://www.php.net/manual/ru/function. ... nction.php
Re: Импорт товаров через rabbitmq
С файлами есть риск нарваться на блокировку, когда два процесса попытаются одновременно что-то записать в один файл.
И файл доступен только локально. Если запускать воркеры на нескольких виртуальных машинах, то на каждой файлы будут свои.
Так что общие данные лучше хранить в БД или подобных хранилищах.
Re: Импорт товаров через rabbitmq
Записывать что именно? Товары, которые ещё не обработались?unknownby писал(а): ↑2022.01.31, 22:42 2. Для того, чтобы узнать какие данные обработала ваша очередь, а какие нет, просто записывайте в два файла свои задачи, в первый, то что нужно обработать, а во второй, что обработалось уже. И можно потом восстановить и начать обработку с тех данных, на которых остановились. Но тут большой гемор с этим. Нужно повозиться с файлами.
- samdark
- Администратор
- Сообщения: 9489
- Зарегистрирован: 2009.04.02, 13:46
- Откуда: Воронеж
- Контактная информация:
Re: Импорт товаров через rabbitmq
Ресайз можно и на лету делать чем-то вроде https://imgproxy.net/. Для nginx тоже модули были какие-то.
Нравится Yii? Давайте сделаем его лучше!.
Re: Импорт товаров через rabbitmq
Получается, что если использовать этот подход, то изначально изображение загружается на сервер и хранится в оригинале.
И только если потребуется просмотр этого изображения через nginx происходит resize изображения и отдаётся клиенту.
Например. Есть 1 000 импортированных товаров, к каждому из товаров по три изображения, все эти изображения хранятся на сервере в оригиналах.
Если просматривается один товар из 1 000, то resize будет только для изображений этого товара, остальные так и останутся?
Я имел ввиду, что при импорте товаров через nginx делается resize всех изображений. Возможно такое сделать?
Или как правильно организовать загрузку и обработку изображений при импорте?