Shlop
@Shlop
Full Stack Developer (PHP/Laravel/JavaScript)

Каждые 10 сек. сайт должен получать цены с 11 бирж, но этих бирж станет больше, как распределять нагрузку?

Добрый день, подскажите пожалуйста
Есть сайт на котором запускается команда каждые 10 сек. Данная команда отправляет 10 Job классов пакетом. Эти Job классы выполняют запросы к API бирж и сохраняют полученные цены в БД. На сервере я настроил supervisors, поставил numprocs=12 что-бы одновременно могло выполняться 10 скриптов.
Но у меня есть две проблемы:
  1. Замечаю что пакет ещё не завершился а следующий вызов команды происходит. Поэтому пока даже добавил проверку что-бы не отправлялся новый пакет пока не выполниться предыдущий;
  2. Со временем бирж станет ещё больше, и я так понимаю просто увеличение numprocs это не правильно т.к. будет нагрузка на сервер, но из-за того что ни разу ещё такого не делал не понимаю как это должно быть устроено;

Если у кого есть опыт в работе с таким буду очень благодарен за информацию, т.к. мне ещё не приходилось делать что-бы часто обновлялось что-то
  • Вопрос задан
  • 465 просмотров
Решения вопроса 4
alexey-m-ukolov
@alexey-m-ukolov Куратор тега Laravel
выполняют запросы к API бирж и сохраняют полученные цены в БД
При такой формулировке дальше я исхожу из того, что а) API отдают данные в более-менее нужном формате, б) цен не больше 1000 (наверняка же про крипту какую-то речь) и в) вам цены нужно только сохранить (простой INSERT/UPDATE), ничего с ними больше не делая.

просто увеличение numprocs это не правильно т.к. будет нагрузка на сервер
Если ваш сервер перестаёт справляться, вы масштабируетесь либо горизонтально, либо вертикально.
Перекладывание джейсонов (т.е. работа с API) - это очень простая в плане ресурсов операция и никакой особой нагрузки она не создаст, весь затык у вас будет (если будет) в сетевых задержках.

пакет ещё не завершился а следующий вызов команды происходит
Показывайте код. Если у вас обращение к API и обработка его ответа занимает больше 10 секунд - это совершенно не нормально.
Ну а проблему с наложением запусков друг на друга можно решать по-разному (и решение будет зависеть от конкретных условий задачи), начать стоит с добавления withoutOverlapping.
Ответ написан
Комментировать
@Everything_is_bad
Задача общая, не привязанная к фреймворкам, для начала переходишь на очередь, далее разделяешь загрузку (потому что почти всегда IO Bound по сети) и обработку данных (а тут часто работа с базой, CPU Bound и прочее). Мониторишь состояние очереди, регулируешь кол-во воркеров, дебажишь на поиск узкие мест, оптимизируешь (например, у многих бирж есть websocket, часто менее затратно подписаться на изменение цены, чем долбить своими запросами.)
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
Мысли.

1) У тебя есть требование периода 10 секунд. Но нет требования синфазности. Тоесть можешь
получать цены со сдвигом примерно в 10/11 секунды.

00:00:00.00 - Market 01
00:00:00.90 - Market 02
00:00:01.80 - Market 03


2) Вряд-ли все биржи будут поддерживать одинаковый сетевой протокол и одинаковый план обновления.
Рассмотри вариант MQ если таковой будет. Подпишись на события.
Ответ написан
Комментировать
@rPman
10секунд * сотни бирж - с этим справится любой асинхронный движок работы с http... если нет, меняй инструмент.

У тебя скорее всего проблема не в загрузке, а в организации запуска процессов. Настрой таймауты, по умолчанию они большие. Отслеживай зависшие процессы или лучше всего настрой штатным php.ini длительность выполнения скрипта.

У тебя должен быть четкий алгоритм получения следующей ссылки на загрузку, например сохраняй в базе время последнего запроса к бирже, и соответственно запрашивай N серверов, с наибольшим временем с последнего запроса со статусом - требуется загрузка,.. так же отслеживай зависшие биржи, те кто слишком давно не выдавал корректного ответа можно переводить в замедленный режим опросов (менять условие, например не чаще раз в час, пока состояние - 'не было ответа').

Очень мало какие биржи позволят делать часто запросы, обычно там лимиты. И если тебе нужно мало валютных пар, это подойдет, но для бОльшего количества валютных пар часто для каждой нужно делать отдельный запрос, и получается что для биржи ихз будет десятки-сотни, получается значительная задержка по сбору информации для каждой конкретной валюты. Для бирж, у которых есть потоковые протоколы (для криптовалютных обычно на websocket) советую для них реализовать загрузку на нем. Форматы там у каждой биржи свои но зато оперативность получения информации - максимальная. Не нужно тратить своих ресурсов на анализ данных, не нужно долбить биржу постоянными запросами, ты получаешь информацию в тот момент, как событие произошло на бирже. Только таким способом к примеру можно собирать стаканы лимитных ордеров со всей биржи (на топовых биржах это гигабайты json в сутки).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Giperoglif
Очередь + воркер с несколькими инстансами, под pm2, например. То что кроном вызывается сейчас - должно просто заполнять очередь заданиями для воркеров.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы