Документация

Документация

Создание сервисов на TypeScript

Сервисы Rockstat — независимые процессы на Node.js, которые общаются между собой через Redis Pub/Sub сообщениями в формате JSON-RPC 2.0. Всё общее — конфигурация, логирование, метрики, клиент Redis, RPC — вынесено в библиотеку @rockstat/rock-me-ts (репозиторий rockme-framework).

Это руководство написано по трём рабочим сервисам платформы, на них же построены примеры:

  • chwriter — пишет все события в ClickHouse.
  • kafkastream — отправляет события в топики Kafka.
  • mmgeo — определяет регион по IP и разбирает User-Agent.

Роли сервисов#

Входящие запросы принимает сервис Front. Он превращает запрос в событие с ключом маршрутизации вида in.gen.<service>.<name> и проводит его через три фазы (подробнее — Жизненный цикл и адресация):

  1. Обогащение (enricher). Front отправляет выбранные поля события в канал enrich и ждёт ответы от зарегистрированных обогатителей. Результаты дописываются в data события. Так работает mmgeo.
  2. Обработка (handler). Если на ключ события зарегистрирован удалённый обработчик, Front вызывает его и из ответа формирует HTTP-ответ клиенту.
  3. Рассылка слушателям (listener). Готовое событие уходит уведомлением в канал broadcast. Ответа Front не ждёт. Так работают chwriter и kafkastream.
РольКаналВызовКак Front узнаёт о сервисе
listenerbroadcastуведомление, без ответаникак, достаточно подписки на канал
enricherenrichзапрос, ответ за 200 мсрегистрация через __iamalive и __status
handlerимя сервисазапрос, ответ за 200 мсрегистрация через __iamalive и __status

Слушатель — самая простая роль: подписался на broadcast и обрабатывай поток. С него и стоит начинать новый сервис.

Что даёт rock-me-ts#

  • AppConfig — конфигурация из config/*.yml с EJS-шаблонами и переменными окружения.
  • Logger — pino с дочерними логгерами на каждый класс (log.for(this)).
  • Meter — метрики в StatsD: tick, incr, gauge, time, timenote.
  • RedisFactory и RedisClient — клиент Redis на redis-fast-driver для Pub/Sub и команд.
  • RPCAdapterRedis и RPCAgnostic — транспорт и JSON-RPC: register, notify, request.
  • TheIds — идентификаторы: snowflake для событий, короткий счётчик для RPC, xxhash.
  • response — конструкторы ответов для Front: data, redirect, pixel, error, statical.
  • Константы шины: BROADCAST, SERVICE_DIRECTOR, METHOD_IAMALIVE, METHOD_STATUS.

Как устроен сервис#

Во всех трёх сервисах один и тот же каркас. Точка входа src/index.ts импортирует AppServer, который при создании поднимает зависимости и подписывается на шину:

import 'reflect-metadata';
import {
  AppConfig, Logger, Meter, RedisFactory,
  RPCAdapterRedis, RPCAgnostic, AgnosticRPCOptions, BROADCAST
} from '@rockstat/rock-me-ts';

export class AppServer {
  constructor() {
    const config = new AppConfig<ModuleConfig>();   // config/*.yml + .env
    const log = new Logger(config.log);
    const meter = new Meter(config.meter);
    this.log = log.for(this);

    const redisFactory = new RedisFactory({ log, meter, ...config.redis });
    const channels = [config.rpc.name, BROADCAST];  // что слушаем
    const rpcOptions: AgnosticRPCOptions = { channels, redisFactory, log, meter, ...config.rpc };

    this.rpc = new RPCAgnostic(rpcOptions);
    this.rpc.setup(new RPCAdapterRedis(rpcOptions));

    this.setup().catch(exc => { this.log.error(exc); process.exit(1); });
  }

  async setup() {
    this.rpc.register(BROADCAST, async (msg) => { /* событие */ return {}; });
  }
}

export const appServer = new AppServer();

Дальше по разделу: