Географическая визуализация с открытым исходным кодом для журналов доступа NGINX

Вернитесь на 15 лет назад. Вы садитесь в машину, чтобы зайти в магазин, в котором никогда раньше не были, но у вас нет интерактивной карты в телефоне. Ваша машина не разговаривает с вами каждую минуту, предлагая «повернуть налево», когда вы приближаетесь к перекрестку. Вместо этого у вас есть список письменных инструкций, которым нужно следовать. В список входят такие шаги, как «Шаг 3: поверните направо и продолжайте движение 0,2 мили». Вы по-прежнему добираетесь до пункта назначения, но сегодня возможность видеть, куда вы собираетесь, значительно упростила навигацию.

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

Итак, мы создали Spectre, карту, которая показывает нам запросы шлюза в реальном времени. С первого взгляда вы можете увидеть, откуда возник запрос, в какой регион AWS он был направлен, а также HTTP-ответ на запрос. Мы поговорим о том, как мы создали Spectre, как это работает, и, что самое важное, о том, как начать использовать Spectre уже сегодня.

Обработка журналов в реальном времени

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

Мы нашли отличную библиотеку чтения журналов доступа NGINX satyrius / gonx и соединили ее с hpcloud / tail - пакетом Go для хвостовых файлов.

Объединив их возможности и составив около 200 строк кода, родилась служба Spectre Data. Служба Spectre Data считывает файл конфигурации NGINX и анализирует формат журнала для журнала доступа. Затем Spectre Data отслеживает файл access.log, анализируя строки журнала по мере их добавления, и отправляет данные через POST-запрос на веб-сервер Spectre.

Обработка журналов

Поскольку мы не хотели создавать дополнительную нагрузку на экземпляры, несущие шлюзы, большая часть обработки данных происходит на веб-сервере. Как только данные достигают веб-сервера, мы берем исходный и целевой IP-адреса и передаем их через oschwald / maxminddb-golang’s MaxMind DB Reader for Go.

Мы возвращаем широту и долготу на уровне города для источника и пункта назначения запросов. Мы также извлекаем из данных код состояния HTTP. Теперь, когда у нас есть все необходимые данные, мы передаем их в веб-интерфейс через WebSocket.

Отображение данных

Веб-интерфейс Spectre построен на React и использует D3 и mapbox для предоставления анимации и тайловой карты соответственно. Для каждой исходной геоточки мы размещаем на экране круг с рябью.

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

Если код состояния запроса был 2xx, исходные круги и линия имеют приятный доступный оттенок цвета морской волны. Для представления ошибок цвет желтый, если код состояния 4xx, и красный цвет, если код состояния 5xx.

Барьеры производительности

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

До того, как мы представили React и некоторые другие улучшения производительности веб-приложения, клиент был написан на обычном Javascript. Вскоре его стало трудно поддерживать, так как нам нужно было отлаживать проблемы с производительностью и добавлять функции пользовательского интерфейса. С помощью инструмента повышения производительности Google Chrome сначала это выглядело примерно так:

На этом изображении много всего происходит, однако, если вы посмотрите на нижнюю кольцевую диаграмму, мы увидели, что происходит много скриптов и рендеринга. Поэтому мы спросили себя: «В чем причина?» Было заметно отставание в пользовательском интерфейсе. Первоначально мы не уделяли много внимания части кадров в секунду вверху, потому что инструмент повышения производительности замораживает экран, вызывая остановку рендеринга во время анализа. Сборка мусора временами происходила спорадически, но мы мало что могли сделать, поскольку JS обрабатывает собственный сборщик мусора. Просматривая подвкладку производительности «Снизу вверх», мы смогли обнаружить, что сценарии и рендеринг D3 и SVG были главными виновниками наших проблем с производительностью.

Мы добавили эффективную библиотеку React, чтобы помочь с рендерингом. Когда мы начинали, интерфейс был чистым JS - без фреймворка - только javascript в браузере. Поскольку это был чистый JS, каждая запись на экран (рисование точки, рисование ряби, рисование линий) вызывала обновление DOM. Мы внедрили React, чтобы он мог более эффективно выполнять эти обновления DOM за счет использования Virtual DOM.

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

После дополнительных исследований стало очевидно, что было бы намного эффективнее визуализировать все, используя HTML5 Canvas API. В конце концов, он предназначался для рисования фигур, изображений и других объектов на отдельном слое холста, где графика ускоряется аппаратно. Однако Canvas API - это низкоуровневый API, который не совсем удобен для пользователя, что делает его довольно сложным. Мы перемещали объекты из SVG в Canvas построчно. Результаты были ошеломляющими!

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

Текущее представление

Мы используем Spectre внутри компании Shipt, поэтому мы подумали, что было бы неплохо написать немного о производительности, которую мы наблюдаем при использовании Spectre. Spectre показывает несколько мониторов в кампусах Шипта. Мы выбрали один из них, чтобы использовать его в качестве примера:

Технические характеристики оборудования:
Mac mini (2018) под управлением Mojave 10.14.5
Процессор: Intel Core i7 с тактовой частотой 3,2 ГГц
Память: 16 ГБ DDR4 2667 МГц
Графика: Intel UHD Graphics 630 < br /> Разрешение экрана: 3840 x 2160

Помня об этих характеристиках, у Spectre нет проблем с показом 900 запросов в секунду (измеряется по нашим внутренним метрикам шлюза). Однако в некоторые из наиболее загруженных дней мы наблюдали, как эта машина с трудом справляется с нагрузкой.

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

Попробуйте Spectre для себя

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

Шипт очень рад объявить об открытом исходном коде Spectre. Если вам интересен этот проект, убедитесь сами. Как и большинство других вещей, это развивающийся проект, и мы приветствуем вклад. Если вы хотите сделать карьеру, работая над подобными проектами, мы вас нанимаем. Посетите страницу карьеры Шипта!

Особая благодарность Джошу Флейхарту за соавторство этой статьи и Spectre. 🙌