RTP DesportoPortugal qualificado para `oitavos` do Europeu de voleibol após derrota de IsraelInquirerMarcos yet to decide on fuel excise tax suspension – Palaceוואלהבגלל תקלה באתר העירייה: המידע רפואי ונתוני הרווחה של תושבי בית שמש היו חשופים לציבורESPNFacts vs. Feelings: What eight notable Week 1 performances mean for Week 2The Jerusalem PostNetanyahu’s New York UN visit sees unusual US Secret Service security involvementESPN DeportesEl mayor éxito y la mayor decepción de los 30 equiposDaily MaverickGROUNDUP: The N1 town’s decade of decay — Beaufort WestBollywood HungamaThe Vvaan Trailer: Sidharth Malhotra and Tamannaah Bhatia starrer explores Indian folklore, supernatural elements and adventure; watchCollider‘Anaconda’ Meets ‘Jurassic Park’ in New Creature Feature With a Truly Gigantic Predator [Exclusive]SCMP ChinaChina uses 100,000 home-grown AI chips to build leading weather forecast systemDeadlineChris Harrison’s Dating Series ‘The Vow’ Sets Premiere On Fox Nation
The Daily Newsstand · Free, Always
Wednesday, September 16, 2026

Firebase больше не тянет: как мы строили real-time-чаты на Centrifugo

Translate

Привет, Хабр! Меня зовут Илья Логинов, я Chats Team Lead в маркетплейсе «Флаувау». Расскажу, как мы отказались от внешних серверов, безболезненно пережили переезд, избежали сбоев в высокий сезон и сократили расходы на эксплуатацию чатов в 100 (сто!) раз. Эта история — о нашем пути от Firebase к Centrifugo.

Что не так с облаком, когда масштабы и нагрузка растут

Когда бизнес растет, внутренние чаты из просто необходимого превращаются в критически важный инструмент. От них зависит, как быстро cеллер и покупатель обсудят детали, а значит, — состоится ли заказ. Изначально для чатов мы использовали Firebase, но со временем это решение перестало справляться с нашими аппетитами.

Стало очевидно, что оно просто не создано для хранения и обработки такого массива данных, какой генерировали мы. Только представьте: в наши пиковые даты — 14 февраля, 8 Марта, День матери — к Firebase было около 60 тысяч одновременных подключений. В такие дни до 4% запросов к чатам стабильно отваливались с ошибкой. Для нас это означало не просто сбой, а реальные простои и потерю денег.

Одна из главных причин, по которой пришлось задуматься о переезде, — мы банально уперлись в потолок самого Firebase. Организация данных в формате JSON существенно затрудняла любые манипуляции с историей сообщений или их обработку (и добавляла головной боли). Что-то поменять, проанализировать или просто почистить требовало непропорционально много усилий. Было ясно: с такой архитектурой данных о дальнейшем масштабировании можно забыть.

Дерево Firebase

Дерево Firebase

Также одним из камней преткновения стала стоимость обслуживания в Firebase. Каждый запрос пользователя к чату, будь то отправка или получение сообщения, был платным. Соответственно, на наших объемах трафика счета откровенно перестали радовать.

Пазл сложился. Пора было искать альтернативу — платформу, которая смогла бы обеспечить устойчивость, гибкость управления данными и снижение затрат на следующих этапах роста маркетплейса.

Как мы искали стабильное real-time-решение «на вырост»

После решения уйти с Firebase следующим шагом стал выбор инструмента, который закроет наши потребности. Главный вопрос был: чем обеспечить тот самый real-time? Как мгновенно оповещать всех участников чата о новых сообщениях, создании диалога или его архивации?

У нас было несколько важных требований к новому техническому решению: персональные каналы, авторизация, выдерживание высоких нагрузок и возможность переключения с Firebase на новые чаты и обратно. Последнее нам нужно было для того, чтобы, во-первых, предусмотреть бесшовный переход, а во-вторых — подстраховать себя на случай проблем с новыми чатами.

Мы детально прорабатывали процесс переключения и rollback между двумя стеками, чтобы минимизировать любое потенциальное время простоя и не потерять события чата на любом этапе перехода.

Рассматривались разные решения на базе WebSocket, в том числе популярный Socket.IO. Но, честно говоря, эти технологии показались нам уже приветом из прошлого и требовали бы серьезной доработки напильником. Особенно смущало отсутствие готовой кластеризации и масштабирования из коробки.

Centrifugo оказался самым подходящим вариантом: он сразу предоставлял нужный функционал и справлялся с высокими нагрузками. Кстати, информацию о Centrifugo команда узнала на одной из конференций: там цифровые гиганты рассказывали об обороте огромного трафика именно через этот real-time-сервер. Выбор был сделан. Мы остановились на версии Centrifugo 5.0 — на момент внедрения это было оптимальное сочетание стабильности и функциональных возможностей. Дальше началось самое интересное — процесс перехода, который занял у нас больше года.

Стратегия перехода: бесшовно и без сбоев

После принятия решения о миграции стало понятно, что откладывать процесс нельзя: к следующему праздничному сезону необходимо было подготовить систему к росту нагрузки. Поэтому в нашем распоряжении был примерно год, чтобы закрыть задачу. Мы начали переход без предварительной подготовки и, как водится, надеялись успеть все закончить за несколько дней, но это оказалось возможным только в мечтах.

В Centrifugo мы решили использовать приватные каналы для реал-тайм оповещений о событиях. Это дает нам уверенность в том, что мы всегда отправляем обновления чата конкретному пользователю. Реконнект или пинг к веб-сокету не нужен, так как он уже реализован внутри Centrifugo. Подписка на приватные каналы Centrifugo осуществляется непосредственно клиентами — мобильными приложениями — с использованием JWT, который сгенерирован на стороне сервера. А в JWT уже зашито название приватного канала, на который может подписаться клиент.

Схема получения авторизационных данных в Centrifugo

Схема получения авторизационных данных в Centrifugo

В теории план перехода выглядел элементарно: поднять свой микросервис, настроить рассылку для Centrifugo и выкачать всю базу из Firebase. Чтобы не уронить прод и сделать переход незаметным для пользователей, мы разработали детальный план.

Шаг первый: взяли весь трафик, связанный с чатами (сообщения, статусы, картинки), и завели его в единую точку входа. Все это должно было проходить не напрямую, как раньше, а через общий API. Как раз к тому моменту начал подрастать наш API-монолит, который сейчас является входной точкой для всех приложений компании: два клиентских приложения на iOS и Android и два приложения селлеров. Это действие позволило не только упростить интеграцию нового чата, но и усилить контроль над потоками данных.

Шаг второй: взялись за клиентские приложения. Архитектура на iOS и Android исторически отличалась, и это мешало внедрять общие решения. Несколько месяцев мы приводили все к единому стандарту и общей логике.

Параллельно с этим пилили новый микросервис для обработки сообщений. Важный момент: чтобы не рисковать, мы создали отдельные тестовые среды на реальных данных. Часть сервисов запускали в режиме «только для чтения» — это позволило точно оценить нагрузку и подготовиться к реальным нагрузкам.

Чаты мы разворачивали в трех независимых территориальных кластерах, каждый из которых сейчас обслуживается собственным инстансом Centrifugo, чтобы снизить задержки и повысить отказоустойчивость. Все инстансы поднимаются в Kubernetes, масштабируются через балансировщик нагрузки — это позволяет масштабировать поды для API-чатов и очередей.

Инфраструктура новых чатов

Инфраструктура новых чатов

Такой подход дал нам гибкость: мы могли одновременно писать данные и в старый Firebase, и в новый микросервис. Старые версии приложений продолжали работать, а данные синхронизировались. Каждую настройку мы обернули в «рубильник», чтобы в любой момент контролировать, куда идут данные. Для мобильных приложений также внедряли отдельные настройки, информирующие, какой механизм используется для работы с чатом.

Механизм переключения трафика

Механизм переключения трафика

Следующий квест: выкачать всю базу из Firebase. Это заняло недели две, потому что сервис отдавал информацию маленькими порциями и периодически падал. Процесс копирования пришлось повторять около 3 раз, чтобы убедиться, что мы ничего не потеряли. Вся база сообщений сейчас у нас хранится в MySQL.

Миграция данных в MySQL

Миграция данных в MySQL

Финал: выпиливание Firebase из нашей системы. Это было непросто: за годы у нас накопилось огромное количество кода, завязанного на Firebase, — фоновые команды, скрипты архивации и прочее легаси, которое помогало снизить нагрузку на облако. Раньше перед каждым пиком мы вручную чистили базу. Теперь в этом просто нет необходимости.

Через месяц после старта работы на новом решении мы полностью отключили Firebase. Наше первое боевое крещение — День матери — прошло идеально. Система спокойно выдержала более 90 тысяч одновременных соединений. А главное — мы знаем, что Centrifugo выдержал бы и в 10 раз больше.

Грабли переезда: с чем пришлось столкнуться на практике

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

Главной проблемой стали мобильные приложения. Им больше 7 лет, писали их другие разработчики, и что там творилось под капотом, никто до конца не понимал. Будем честны, история знакома многим: уровень грамотности кода растет вместе с разработчиками. Привести две разные логики приложений к общему знаменателю, чтобы просто начать что-то менять, — вот на это и ушла львиная доля времени.

Вдобавок ко всему наш переезд совпал с глобальной перестройкой всей архитектуры Флаувау. Раньше система была монолитным приложением на старой версии Yii. Так что чаты мы переносили, одновременно распиливая наш старый монолит на микросервисы. Но это уже совсем другая история…

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.