Как стать автором
Обновить
116.38
Рейтинг
Luxoft
think. create. accelerate.

Сбор метрик SpringBoot-приложения в AWS CloudWatch

Блог компании LuxoftJava
Привет! Меня зовут Артем Арешко, я являюсь ведущим Java разработчиком в компании Luxoft на Fin-Tech проекте. Сегодня поговорим о метриках, Spring Boot и облаках Amazon.

В качестве вступления...


Промышленная эксплуатация требует знаний о том, как живет приложение. Этот тезис следует взять за аксиому. Таковыми знаниями являются метрики, производимые приложением. Метрики могут быть как чисто техническими (например, количество потребляемой ОЗУ) так и бизнесовыми (например, совершенные заказы).

Сам по себе срез метрик на текущий момент не всегда интересен и показателен. Встают базовые вопросы о сборе, хранении и отображении этих метрик.

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

О чем речь


Проект, на котором я участвую, как раз использует сервисы и развернут в AWS (Amazon Web Services). Основная масса сервисов построена с использованием Java 8+, Spring Boot и Docker. Доклад, прошедший на Luxoft IT Sreda #7 и данная статья выросли из нужд и задач проекта.

Моя цель — рассмотреть практическую сторону сбора метрик приложения, использующего Spring Boot, и экспорт их в AWS CloudWatch. Это будет, по сути, step-by-step guide с пояснениями, разбором нюансов и возможных граблей.

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

Рассмотрим, из чего состоит наш сегодняшний контекст:

  1. Как данность, наше приложение или сервис основано на Spring Boot. В качестве сборщика Maven, Java 8+
  2. Docker. Однако, его использование не является критическим моментом. Важно, что для приложения, запущенного в docker все тоже будет работать
  3. AWS EC2 — это наша инфраструктура, где запускается приложение. По своей сути это виртуальная машина в рамках AWS.
  4. AWS CloudWatch — система мониторинга, являющаяся приборной панелью AWS-инфраструктуры.

Spring Boot


Перейдем к SpringBoot и его возможностям, которые могут нам помочь. Первое и самое важное, что есть в арсенале — Actuator. Этот модуль дает возможность заглянуть внутрь работающего приложения и, до определенной степени, настроить его поведение. Например:

  • Health check: информация о состоянии приложения в целом и его компонентов по отдельности
  • Узнать настройки логирования и, при необходимости, скорректировать в runtime.
  • Получить сведения о бинах, поднятых в контексте
  • Считать метрики, производимые приложением, такие как: данные о памяти, процессорных ресурсам, поведению GC.
  • ...

Как и многие компоненты Spring, Actuator похож на конструктор и может быть кастомизирован, расширен и настроен довольно тонко. Начать изучение можно отсюда.

Из всего набора нас, в данный момент, интересуют метрики. Actuator и метрики в частности, не только расширяем, но и преднастроен, поэтому только категорий метрик, доступных “из коробки” наберется пару десятков. Конечно же, есть возможность регистрация собственных метрик. Если в проекте подключен модуль web, метрики можно получит через обращение к endpoint /metrics.

Сбор и предоставление метрик реализован через библиотеку micrometer, которая является продуктом компании Pivotal (ныне часть VMware), той же, что занимается разработкой Spring. micrometer позиционируется как вендорно-независимый фасад для экспорта метрик Java-приложений.

Для подключения actuator потребуется следующий starter:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Spring Cloud


Далее нам потребуется модуль из Spring Cloud, а именно spring-cloud-starter-aws.

У каждого модуля из семейства Spring Cloud свое версионирование и будет правильным использовать не конкретную версию модуля, а BOM spring-cloud-dependencies определенной версии (release train), где собраны совместимые версии модулей. На момент написания это Hoxton.RELEASE.

Кроме вкусных автоконфигураций, для работы с AWS, spring-cloud-starter-aws, в качестве транзитивной зависимости, дает aws-java-sdk.

В разделе dependencyManagement помещаем

<dependencyManagement>
...
   <dependencies>
       <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-dependencies</artifactId>
          <version>Hoxton.RELEASE</version>
          <type>pom</type>
          <scope>import</scope>
       </dependency>
   </dependencies>
...
</dependencyManagement>

А в зависимости:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-aws</artifactId>
</dependency>

Micrometer registry


Теперь у нас есть micrometer в составе Spring Actuator и aws-java-sdk. Из коробки, micrometer не умеет экспортировать данные в AWS CloudWatch, для этого требуется соответствующая реализация MeterRegestry — абстракции micrometer для сбора метрик. По умолчанию подставляется SimpleMeterRegistry, хранящий данные в памяти. Нужная реализация подключается вместе с micrometer-registry-cloudwatch. На момент написания, актуальная версия 1.3.5.

<dependency>
   <groupId>io.micrometer</groupId>
   <artifactId>micrometer-registry-cloudwatch</artifactId>
   <version>1.3.5</version>
</dependency>

Итоговый pom.xml, в нашем случае, имеет следующий вид: github.com/MrArtemAA/blog-demos/blob/master/export-metrics-to-cloudwatch/pom.xml

app.properties


Перейдем к настройке свойств приложения, которые в нашем случае играют немаловажную роль:

1. management.metrics.export.cloudwatch.namespace: нужно указать namespace, под которым в CloudWatch будут сохранятся метрики. Т.к. в самой метрике нет информации от какого именно инстанса приложения пришли данные, namespace как раз и будет определять метрики конкретного инстанса. В противном случае, если для нескольких инстансов определить один namespace, данные метрик будут перемешаны и не понятно откуда какие пришли.

image

2. management.metrics.export.cloudwatch.batch-size: требуется явно установить значение свойства batch-size равным 20. Что это за параметр и почему именно 20? Метрики посылаются клиентов Amazon CloudWatch асинхронно, партиями (batch) по 20 (это ограничение AWS) за раз.

3. cloud.aws.stack.auto=false: нужно отключить автоопределение AWS CloudFormation стека, т.к. по умолчанию оно имеет значение = true. Это свойство отвечает за то, будет ли приложение пытаться автоматически получить название стека для конфигурации приложения под облачное окружение (в парадигме infrastructure-as-code). При развертывании на EC2, как на обычной виртуалке, этой информации нет.

Важно понимать, что всю информацию, которую AWS SDK будет пытаться получить самостоятельно без дополнительной конфигурации, она [библиотека] будет брать из метаданных EC2. Для получения этой информации есть специальный служебный endpoint, куда и происходит обращение.

Разбор полетов


batch-size


Еще раз вернемся к свойству management.metrics.export.cloudwatch.batch-size и необходимости выставить его равным 20. Казалось бы, это все можно сделать на уровне соответствующих библиотек, работающих с AWS. Действительно, в micrometer-registry-cloudwatch есть интерфейс CloudWatchConfig с default методом, который корректно проверяет значение и кидает исключение при превышении 20. Однако, если посмотреть org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration, увидим, что конфигурация происходит с помощью org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchPropertiesConfigAdapter:

@Bean
@ConditionalOnMissingBean
public CloudWatchConfig cloudWatchConfig(CloudWatchProperties cloudWatchProperties) {
  return new CloudWatchPropertiesConfigAdapter(cloudWatchProperties);
}

Адаптер, в свою очередь переопределяет batchSize() как

@Override
public int batchSize() {
  return get(CloudWatchProperties::getBatchSize, CloudWatchConfig.super::batchSize);
}

Это значит, что если в CloudWatchProperties свойство определено — оно будет взято оттуда. Как раз в нем нет нужных проверок и, если свойство не выставлено явно, значение по умолчанию будет 10000.

Запросы к AWS


Приложение (сервис) не может просто так делать запросы к сервисам Amazon. Они [запросы] должны содержать учетные данные. Для этого в AWS SDK есть цепочка провайдеров учетных данных, которую и рекомендуется использовать. Среди этих провайдеров есть Instance Profile, который как раз может получить данные на основе метаданных EC2. Чтобы это работало, необходимо убедиться, что к EC2 привязана роль.



Роль должна предоставлять права на выполнение запросов к CloudWatch и быть доступной для EC2. Роль можно указать как при создании нового EC2 instance, так и прикрепить к существующему. Применение роли происходит на лету.

Отключение метрик


Для локальной сборки или тестового окружения экспорт метрик может быть излишним. Установка свойства management.metrics.export.cloudwatch.enabled=false позволяет отключить экспорт метрик в CloudWatch, при этом сам сбор метрик будет производится и, если у вас подключен модуль web, то по endpoint /metrics они все также будут доступны.

Micrometer собирает и поставляет большое количество метрик. Если какие-то из них не нужны, их можно отключить. Можно отключать как индивидуально, так и целыми категориями. Так, например, свойство management.metrics.enable.some.metric=false, отключит все метрики, чьи id будут начинаться с some.metric. Имейте ввиду: отключенные метрики не будут собираться вообще.

Запуск все AWS


Еще один сюрприз поджидает, если попытаться запустить приложение с минимально необходимыми настройками все AWS. Для работы необходимые данные региона, где работает приложение. Как мы уже знаем, все что не указано явно, AWS SDK будет пытаться получить из метаданных… которых нет. Поэтому явно указываем нужный регион через свойство cloud.aws.region.static=us-east-2. Как и в случае с названием стека (свойство cloud.aws.stack.auto), имеет место быть свойство cloud.aws.region.auto равное true по умолчанию. Но просто выставление значения в false нам не поможет, т.к. нужно именно значение региона.

Также, как мы помним, запросы к AWS требуют учетных данных, поэтому если требуется передавать в CloudWatch метрики (или делать другие запросы к AWS), необходимо явным образом указать параметры для учетных данных через, например, свойства приложения или переменные окружения.

Передача через свойства приложения выглядит следующим образом:
cloud.aws.credentials.access-key=YOUR_ACCESS_KEY
cloud.aws.credentials.secret-key=YOUR_SECRET_KEY


Итоги


Как, я думаю, вы могли заметить, заставить работать всю схему и передавать метрики из приложения в CloudWatch не так сложно: потребовалось 3 зависимости и 3 свойства.

Самое важное как раз кроется в деталях. Библиотеки (фреймворки) такие, как Spring, AWS SDK, пытаются облегчить жизнь и максимально сделать всю работу за нас, но при этом любой шаг в сторону может привести к появлению stacktrace, попыткам понять, почему метрики никуда не идут, почему приложение вообще не запускается и как это все исправить. Раздел с разбором нюансов и описание некоторых деталей работы сервисов EC2 и CloudWatch, надеюсь, облегчат ваше понимание происходящего.

Если говорить об использовании самого CloudWatch, то, на мой взгляд, это достаточно естественный выбор при использовании инфраструктуры AWS.

Метрики — это глаза и уши нашего приложения, однако это не отменяет того факта, что нужно понимать как метрики собираются, считаются и отображаются. Что за данные вы будете видеть на своих графиках. Особенно остро этот вопрос встанет при возникновении аномалий и разборе инцидентов. Если говорить о библиотеке micrometer — стоит обратиться к документации, там, например, довольно подробно рассказано о типах измерителей (Meter).

Ссылки


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

Spring Boot: Metrics With Micrometer and AWS CloudWatch
Spring Cloud. Using Amazon Web Services. Spring Boot auto-configuration
Spring in Action 5, Craig Walls, Manning
Популярно об Amazon Web Services

Готовый проект можно найти на GitHub.

Автор: Артем Арешко, Lead Java Developer

Теги:javaspring bootaws
Хабы: Блог компании Luxoft Java
Всего голосов 2: ↑2 и ↓0+2
Просмотры1.7K

Похожие публикации

Лучшие публикации за сутки