booblik
DocsServices

booblik-app

1. Зона ответственности

Запуск. Модуль превращает набор библиотек в процесс: читает конфигурацию, открывает брокер, поднимает сервер, печатает метрики, применяет retention по таймеру и корректно закрывается.

Чем не занимается:

  • не реализует ни хранение, ни протокол — только собирает их;
  • не демонизируется, не пишет PID-файл, не тянет логгер. Всем этим уже занимается то, что запускает брокер, — systemd, контейнерный рантайм, тест, — и у каждого свои представления. Вывод идёт в stdout, потому что его читают все трое;
  • не создаёт топики: их набор фиксируется при старте.

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

2. Контракт

Конфигурация — properties-файл первым аргументом плюс переменные окружения. Имя переменной — ключ заглавными с точками, заменёнными на подчёркивания: booblik.portBOOBLIK_PORT. Окружение важнее файла, файл важнее умолчания.

КлючУмолчаниеСмысл
booblik.data.dirdataкорень, внутри — каталог на партицию <топик>-<номер>
booblik.port90920 = любой свободный
booblik.bind.addressнетадрес прослушивания; без него — все интерфейсы, см. §1.16 и M-64
booblik.topicsdefault:1orders:3,clicks:1
booblik.segment.modeMAPPEDпуть записи; FILE_CHANNEL — путь отката, см. Р1 и M-45
booblik.segment.capacity.bytes512 МиБпотолок — Int.MAX_VALUE у обоих путей записи
booblik.index.interval.bytes4096сколько лога приходится на одну запись индекса
booblik.flush.every.recordsнетбарьер раз в N записей
booblik.flush.every.millisнетбарьер раз в T миллисекунд
booblik.retention.bytesнетсколько живого лога держать на партицию
booblik.retention.millisнетпо возрасту файла сегмента
booblik.retention.check.millis30000как часто применять retention
booblik.transportSELECTORVIRTUAL_THREADS — линейка для замеров, не рабочий режим
booblik.fetch.modeZERO_COPYHEAP — контроль в эксперименте M-35
booblik.metrics.interval.millis100000 отключает строку метрик

2а. Ключевые файлы (якоря кода)

ФайлЧто там
src/main/kotlin/.../app/Main.ktсборка всего вместе, репортер метрик, таймер retention, shutdown
src/main/kotlin/.../app/BooblikConfig.ktчтение и проверка всех ключей
../ci/smoke.shпроверка поставки: старт, обмен по проводу, рестарт

3. Как устроено

Политика сброса — не долговечность. booblik.flush.every.* ограничивает окно потери: при everyMillis=100 в худшем случае теряются последние сто миллисекунд принятого. Продюсеру, которому ответили WRITTEN, ответили до всякого барьера, и фоновый сброс этого не меняет. Ждёт барьера только FORCED. Путать эти две вещи — самый простой способ считать систему надёжнее, чем она есть; вся история с msync (§1.9) случилась ровно так.

Оба триггера нужны вместе. Счётчик один оставляет простаивающий брокер с несброшенными данными навсегда: последние записи перед тем, как трафик прекратился, — как раз те, до которых счётчик уже не дойдёт. Таймер один игнорирует нагрузку, и всплеск успевает положить под удар больше, чем задумано.

Метрики печатаются скоростями, а не счётчиками. Счётчик, напечатанный раз в десять секунд, — это то, что читателю придётся дифференцировать в уме ровно в тот момент, когда он разбирает инцидент. Сами счётчики остаются в снимке.

Retention применяется отсюда, а не из брокера. У Broker.applyRetention нет часов: он делает то, что сказали, когда сказали. Так тест двигает время вызовом, а не ожиданием, и здесь — единственное место, которое решает «когда».

4. Зависимости

ТипИмяДля чего
Module:booblik-netброкер, сервер, метрики

5. Локальный запуск

./gradlew :booblik-app:run --args="broker.properties"

Собрать дистрибутив:

./gradlew :booblik-app:installDist

Проверить, что он действительно работает (это же гоняет CI):

./ci/smoke.sh

6. Сознательные ограничения / грабли

  • Дистрибутив стартует с тем же профилем JVM, что и все замеры (applicationDefaultJvmArgs). Разойдись они — и каждое число в benchmarking описывало бы не тот процесс, который поставляется.
  • booblik.metrics.interval.millis=0 выключает строку метрик молча. Выключенная метрика неотличима от исправной работы, поэтому ноль стоит ставить осознанно.
  • Порядок остановки: сервер → фоновые задачи → брокер. Брокер закрывается последним и закрывает писателей первыми, так что принятый батч доезжает до диска раньше, чем исчезает лог под ним.
  • ci/smoke.sh нашёл единственный настоящий баг вехи, которого не увидели тесты: писатель терял батч, если таймер сброса срабатывал одновременно с приходом сообщения. Тесты поднимают сервер из кода, а поставку проверяет только это.

On this page