= Collector Полная система состоит из 3 компонентов, соединённых по сети: коллектор <-> бэкенд <-> клиент (браузер) == В идеале В идеале коллектор это демон, который - сам опрашивает биржи через их кривой API (JSON REST или Websocket) - обрабатывает все ошибки API - приводит данные от разных бирж к единому виду - активно (см. ниже) отдает эти унифицированные данные в бэкенд по выпрямленному стандартному протоколу Financial Information Exchange (FIX) 4.x == Сейчас в продакшене (pre-2019 код) - между бэкендом и сервером наш кривой протокол - коллектор постоянно падает и бывает что тянет за собой бэкенд - код коммуникаций кривой и хрупкий - коллектор частично пассивный (бэкенд запрашивает данные) частично активный (коллектор пушит данные в бэкенд) == Сделано в btcanalytics-collector на август 2019 Позитивные моменты: - С# вменяемый язык и инфраструктура по сравнению с нодой Негативные моменты: - С# это ёбаная джава, то есть - инфраструктурный выигрыш в-основном (Студия, VSCode, профайлеры, nuget...) - языковой выигрыш по сравнению с Typescript минимальный - Akka скорее говно и не нужна - Обмазывание кода отчётами и метриками болезненно и трудоёмко Что сделано (но не работает): - коллектор на гирмане/C# - две биржи - btctradeua и bitstamp - по каждой бирже все BTC-тикеры - нормализация курса для "перевёрнутых" пар (в случае X BTC за Y альткоина биржи могут отдавать цену в виде X или Y по усмотрению; мы всегда пересчитываем в Х) - обработка ошибок HTTP и парсинга - частичное обмазывание Sentry (сортировка эксепшенов по частоте) и Prometheus (mrtg-метрики) Что не сделано: - дельты ордербуков == Предлагаемое краткосрочное решение - между бэкендом и коллектором очередь сообщений, например Gearman (проще чем FIX, легко найти библиотеки клиентов под любой язык). Но можно MQTT или что иное. - формат сообщений не унифицированный, такой, в каком отдает API биржи - активность-пассивность тоже максимально простая: - если API REST polling - то работаем через request-response гирмана, бэкенд делает SUBMIT_JOB, а коллектор регистрируется как воркер - если API websocket streaming (или другой стриминг) - то используем background jobs (sic!) гирмана. Коллектор делает SUBMIT_JOB_BG, а бэкенд регистрируется воркером. Примеры API: - простой REST https://www.bitstamp.net/api/v2/order_book/BTCUSD/ - websocket API и FIX от них же: https://www.bitstamp.net/api/ - купуй украйинське: https://docs.google.com/document/d/1ocYA0yMy_RXd561sfG3qEPZ80kyll36HUxvCRe5GbhE/edit Простейший вариант пассивного коллектора: - коллектор регистрируется воркером для джоба с названием bitstampUSD - когда приходит джоб, выполняется HTTP GET https://www.bitstamp.net/api/v2/order_book/BTCUSD/ и гирман-воркер возвращает его тело Обработка ошибок (адвансед): - таймаут - non-200 HTTP error code - неправильный content-type - битый json - json не в том формате Сигнализация ответом на джоб в формате `{err: "код_ошибки"}`