Это отрывок из руководства по созданию панелей мониторинга реального времени с помощью React и Cube.js. Вы можете ознакомиться с полным руководством здесь.

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

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

Cube.js, который действует как посредник между вашей базой данных и аналитической панелью, может предоставлять API-интерфейс на основе WebSockets в реальном времени для внешнего интерфейса, одновременно опрашивая базу данных на предмет изменений в данных.

Вы можете посмотреть демонстрацию панели управления в реальном времени, созданной с помощью Cube.js здесь.

На интерфейсе Cube.js предоставляет API для загрузки исходных исторических данных и подписки на все последующие обновления.

import cubejs from '@cubejs-client/core';
import WebSocketTransport from '@cubejs-client/ws-transport';
const cubejsApi = cubejs({
  transport: new WebSocketTransport({
    authorization: CUBEJS_TOKEN,
    apiUrl: 'ws://localhost:4000/'
  })
});
cubejsApi.subscribe({
  measures: ['Logs.count'],
  timeDimensions: [{
    dimension: 'Logs.time',
    granularity: 'hour',
    dateRange: 'last 1440 minutes'
  }]
}, (e, result) => {
  if (e) {
    // handle new error
  } else {
    // handle new result set
  }
});

В нашем руководстве мы собираемся использовать React в качестве внешнего интерфейса. Cube.js имеет пакет @cubejs-client/react, который предоставляет компоненты React для легкой интеграции Cube.js в приложение React. Он использует перехватчики React для загрузки запросов и подписки на изменения.

import { useCubeQuery } from '@cubejs-client/react';
const Chart = ({ query, cubejsApi }) => {
  const {
    resultSet,
    error,
    isLoading
  } = useCubeQuery(query, { subscribe: true, cubejsApi });
  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (error) {
    return <pre>{error.toString()}</pre>;
  }
  if (!resultSet) {
    return null;
  }
  return <LineChart resultSet={resultSet}/>;
};

В этом руководстве я покажу вам, как создать панель управления в реальном времени с помощью
MongoDB. Такой же подход можно использовать для любых баз данных, поддерживаемых Cube.js.

В течение довольно долгого времени выполнение аналитики с помощью MongoDB требовало дополнительных накладных расходов по сравнению с современными СУБД SQL и хранилищами данных, связанными с конвейером агрегации и практиками MapReduce. Чтобы заполнить этот пробел, MongoDB выпустила коннектор MongoDB для BI, который действует как сервер MySQL поверх ваших данных MongoDB. Под капотом он связывает существующие механизмы агрегации с протоколом MySQL, позволяя стандартным клиентам MySQL подключаться и выдавать запросы SQL.

Настройка MongoDB и BI Connector

Если у вас нет экземпляра MongoDB, вы можете скачать его здесь. BI Connector можно скачать здесь. Убедитесь, что вы используете версию MongoDB, которая поддерживает коннектор MongoDB для BI.

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

$ bin/mongod

Сам коннектор BI можно запустить таким же образом:

$ bin/mongosqld

Обратите внимание, что mongosqld находится в другом bin каталоге. Если все работает правильно, вы должны увидеть в своей оболочке сообщение об успешном выполнении процесса mongosqld:

[initandlisten] waiting for connections at 127.0.0.1:3307

Если вы используете MongoDB Atlas, вы можете использовать это руководство для включения коннектора BI.

Получение образца набора данных

Вы можете пропустить этот шаг, если у вас уже есть данные для панели управления.

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

$ curl https://cube.dev/downloads/events-dump.zip > events-dump.zip
$ unzip events-dump.zip
$ bin/mongorestore dump/stats/events.bson

Не забудьте перезапустить экземпляр коннектора MongoDB BI, чтобы сгенерировать актуальную схему MySQL из только что добавленной коллекции.

Создание приложения Cube.js

Мы собираемся использовать Cube.js CLI для создания нашего серверного приложения; давайте сначала установим его.

$ npm install -g cubejs-cli

Затем создайте новое приложение Cube.js с драйвером MongoBI.

$ cubejs create real-time-dashboard -d mongobi

Перейдите в только что созданную папку real-time-dashboard и обновите файл .env своими учетными данными MongoDB.

CUBEJS_DB_HOST=localhost
CUBEJS_DB_NAME=stats
CUBEJS_DB_PORT=3307
CUBEJS_DB_TYPE=mongobi
CUBEJS_API_SECRET=SECRET

Теперь давайте запустим сервер разработки Cube.js.

$ npm run dev

Это запускает сервер разработки с игровой площадкой. Мы будем использовать его для генерации схемы Cube.js, тестирования наших данных и, наконец, создания информационной панели. Откройте в браузере http: // localhost: 4000.

Cube.js использует схему данных для генерации кода SQL, который будет выполняться в вашей базе данных. Схема данных - это код JavaScript, который определяет меры и измерения и способ их сопоставления с запросами SQL.

Cube.js может генерировать простую схему данных на основе таблиц базы данных. Выберите events таблицу и нажмите «Создать схему».

После того, как схема сгенерирована, мы можем перейти на вкладку «Сборка» и выбрать некоторые меры и измерения для проверки схемы. Вкладка «Построить» - это место, где вы можете создавать образцы диаграмм с различными библиотеками визуализации и проверять, как была создана эта диаграмма, начиная с сгенерированного SQL и заканчивая кодом JavaScript для визуализации диаграммы. Вы также можете проверить запрос JSON, который отправляется в серверную часть Cube.js.

Хотя автоматически сгенерированная схема - это хороший способ начать работу, во многих случаях вам потребуется добавить более сложную логику в схему Cube.js. Подробнее о схеме данных и ее возможностях вы можете узнать здесь. В нашем случае мы
хотим создать несколько дополнительных показателей и измерений для нашей панели мониторинга в реальном времени.

Замените содержимое schema/Events.js следующим.

cube(`Events`, {
  sql: `SELECT * FROM stats.events`,
  refreshKey: {
    sql: `SELECT UNIX_TIMESTAMP()`
  },
  measures: {
    count: {
      type: `count`
    },
    online: {
      type: `countDistinct`,
      sql : `${anonymousId}`,
      filters: [
        { sql: `${timestamp} > date_sub(now(), interval 3 minute)` }
      ]
    },
    pageView: {
      type: `count`,
      filters: [
        { sql: `${eventType} = 'pageView'` }
      ]
    },
    buttonClick: {
      type: `count`,
      filters: [
        { sql: `${eventType} = 'buttonCLicked'` }
      ]
    }
  },
  dimensions: {
    secondsAgo: {
      sql: `TIMESTAMPDIFF(SECOND, timestamp, NOW())`,
      type: `number`
    },
    anonymousId: {
      sql: `anonymousId`,
      type: `string`
    },
    eventType: {
      sql: `eventType`,
      type: `string`
    },
    timestamp: {
      sql: `timestamp`,
      type: `time`
    }
  }
});

Сначала мы определяем меры для нашей панели инструментов. Мера count - это просто подсчет всех общих событий; pageView и buttonClick - количество соответствующих событий. Мера online немного сложнее. Он возвращает количество уникальных пользователей, которые выполнили какое-либо событие за последние 3 минуты.

Внутри dimensions есть простые anonymousId, eventType и timestamp, которые просто показывают значения из соответствующих столбцов. Мы также определили измерение secondsAgo, которое вычисляет количество секунд с момента возникновения события.

Наконец, мы устанавливаем собственный refreshKey. Он управляет
обновлением слоя кэша в памяти Cube.js. Если установить значение SELECT
UNIX_TIMESTAMP()
, кеш будет обновляться каждую секунду. Вам нужно тщательно выбирать лучшую стратегию обновления в зависимости от ваших данных, чтобы получать самые свежие данные, когда они вам нужны, но в то же время не перегружать базу данных множеством ненужных запросов.

Пока что мы успешно настроили базу данных и создали схему Cube.js для нашей панели инструментов. Пришло время построить саму дашборд!

Cube.js Playground может сгенерировать шаблонное интерфейсное приложение.
Это удобный способ начать разработку дашборда или аналитического приложения. Вы можете выбрать свой любимый интерфейсный фреймворк и библиотеку диаграмм, и Playground сгенерирует новое приложение и соединит все вместе для работы с серверным API Cube.js.

В нашем руководстве мы будем использовать React и Chart.js. Чтобы создать новое приложение, перейдите в «Приложение панели инструментов», выберите «Реагировать на Antd Static» с помощью «Chart.js» и нажмите кнопку «Создать приложение панели мониторинга».

Создание приложения и установка всех зависимостей может занять некоторое время. Как только это будет сделано, у вас будет папка dashboard-app внутри папки проекта Cube.js. Чтобы запустить приложение приборной панели, либо перейдите на вкладку «Dashboard App» на игровой площадке и нажмите кнопку «Пуск», либо выполните следующую команду в папке dashboard-app:

$ npm start

Убедитесь, что серверный процесс Cube.js запущен и работает, поскольку наша панель инструментов использует его API. Внешнее приложение работает на http: // localhost: 3000.

Чтобы добавить диаграмму на панель инструментов, вы можете либо отредактировать файл dashboard-app/src/pages/DashboardPage.js, либо использовать Cube.js Playground. Чтобы добавить диаграмму через Playground, перейдите на вкладку «Построить», постройте диаграмму, которую хотите, и нажмите кнопку «Добавить в панель управления».

Настройте Cube.js для получения данных в реальном времени

Нам нужно сделать несколько вещей для поддержки в реальном времени в Cube.js. Во-первых, давайте
включим транспорт WebSockets на сервере, установив переменную среды CUBEJS_WEB_SOCKETS.

Добавьте следующую строку в файл .env.

CUBEJS_WEB_SOCKETS=true

Затем нам нужно обновить файл index.js, чтобы передать несколько дополнительных параметров серверу Cube.js.

Обновите содержимое файла index.js следующим образом.

const CubejsServer = require('@cubejs-backend/server');
const server = new CubejsServer({
  processSubscriptionsInterval: 1,
  orchestratorOptions: {
    queryCacheOptions: {
      refreshKeyRenewalThreshold: 1,
    }
  }
});
server.listen().then(({ port }) => {
  console.log(`🚀 Cube.js server is listening on ${port}`);
}).catch(e => {
  console.error('Fatal error during server start: ');
  console.error(e.stack || e);
});

Мы передали бэкэнд Cube.js два варианта конфигурации. Первый, processSubscriptionsInterval, определяет интервал опроса. Значение по умолчанию - 5 секунд; мы устанавливаем его на 1 секунду, чтобы сделать его немного более реальным.

Второй, refreshKeyRenewalThreshold, определяет частоту выполнения refreshKey. Значение этого параметра по умолчанию - 120, что составляет 2 минуты. В предыдущей части мы изменили refreshKey для сброса кеша каждую секунду, поэтому нам не имеет смысла ждать еще 120 секунд, чтобы сделать недействительным сам результат refreshKey, поэтому мы также изменили его на 1 секунду .

Это все обновления, которые нам нужно внести в серверную часть. Теперь давайте обновим код нашего приложения для панели инструментов. Сначала давайте установим пакет @cubejs-client/ws-transport. Он предоставляет транспорт WebSocket для работы с API реального времени Cube.js.

Выполните следующую команду в своем терминале.

$ cd dashboard-app
$ npm install -s @cubejs-client/ws-transport

Затем обновите файл src/App.js, чтобы использовать транспорт в реальном времени для работы с Cube.js API.

-const API_URL = "http://localhost:4000";
+import WebSocketTransport from '@cubejs-client/ws-transport';
 const CUBEJS_TOKEN = "SECRET";
-const cubejsApi = cubejs(CUBEJS_TOKEN, {
-  apiUrl: `${API_URL}/cubejs-api/v1`
+const cubejsApi = cubejs({
+  transport: new WebSocketTransport({
+    authorization: CUBEJS_TOKEN,
+    apiUrl: 'ws://localhost:4000/'
+  })
 });

Теперь нам нужно обновить способ запроса самого запроса в src/components/ChartRenderer.js. Сделайте следующие изменения.

-const ChartRenderer = ({ vizState }) => {
+const ChartRenderer = ({ vizState, cubejsApi }) => {
   const { query, chartType } = vizState;
   const component = TypeToMemoChartComponent[chartType];
-  const renderProps = useCubeQuery(query);
+  const renderProps = useCubeQuery(query, { subscribe: true, cubejsApi });;
   return component && renderChart(component)(renderProps);
 };

Вот и все! Теперь вы можете добавить больше диаграмм на свою панель инструментов, внести изменения в базу данных и посмотреть, как диаграммы обновляются в реальном времени.

На GIF-изображении ниже показана панель управления с общим количеством событий, количеством пользователей в сети и таблицей с последними событиями. Вы можете видеть обновления графиков в реальном времени, когда я вставляю новые данные в базу данных.

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

Поздравляем с изучением этого руководства! 🎉

Я хотел бы услышать от вас о вашем опыте использования этого руководства, не стесняйтесь оставлять комментарии ниже!

Чтобы узнать, как развернуть эту панель мониторинга, вы можете проверить полную версию Руководства по работе с панелью мониторинга в реальном времени здесь.