Рубрики
Без рубрики

Как измерять и контролировать Ваше приложение Spring Boot 2 в Kubernetes использует Wavefront

В этом посте я расскажу вам об инструментах и мониторинге простого автономного приложения, разработанного с помощью Spring Boot 2.0.

Автор оригинала: Sravan Cynixit.

В этом посте я расскажу вам об инструментах и мониторинге простого автономного приложения, разработанного с помощью Spring Boot 2.0. Приложение работает как контейнер в Kubernetes. Spring Boot-это платформа на основе Java с открытым исходным кодом, используемая для создания микросервисов. Kubernetes – популярная система оркестровки контейнеров. Смотрите ссылки в конце страницы, чтобы узнать больше о Spring Boot и Kubernetes. Если вы хотите получить углубленные знания о Java Spring, пожалуйста, перейдите по этой ссылке Онлайн-Тренинг по Весенней Загрузке Предположим, что я хочу наблюдать за производительностью своего приложения на всех уровнях стека. Вот такой сценарий:

• Я слежу за своей средой Kubernetes. • Я собираю показатели, поступающие из самого приложения. • Я добавляю еще одно измерение, используя приложение для отправки распределенных трассировок.

Поскольку все эти показатели видны в Wavefront, теперь у меня есть представление о богатом наборе данных, поступающих от Kubernetes, приложения и трассировок приложения.

Приложение, которое я создал для этого блога, было разработано в качестве демо-версии. Это Java-приложение, имеющее конечные точки REST API для приема запросов. Ответы генерируются в формате JSON. Я назвал приложение “loadgen”, потому что оно генерирует имитацию загрузки процессора и памяти для использования вычислительных ресурсов системы. Найдите исходный код loadgen в моем репозитории GitHub.

При разработке этого приложения я решил использовать:

• Spring Boot 2.0 в качестве базовой платформы, потому что я думал, что это поможет мне быстро создать приложение • Библиотека микрометрических приборов • Репортер волнового фронта, который хорошо сочетается с библиотекой микрометров • Я использовал Maven и добавил следующую зависимость в свой pom.xml файл, позволяющий использовать микрометр:


    io.micrometer
    micrometer-registry-wavefront
    ${micrometer.version}

Шаг 1. Отправка Метрик приложений

Инструментарий моего приложения loadgen был довольно простым. Я добавил следующий код в свой класс приложений (который использует реестр измерителей волнового фронта в качестве реестра).

// create a new registry
registry = new WavefrontMeterRegistry(config, Clock.SYSTEM);

// default JVM stats
new ClassLoaderMetrics().bindTo(registry);
new JvmMemoryMetrics().bindTo(registry);
new JvmGcMetrics().bindTo(registry);
new ProcessorMetrics().bindTo(registry);
new JvmThreadMetrics().bindTo(registry);
new FileDescriptorMetrics().bindTo(registry);
new UptimeMetrics().bindTo(registry);

давайте посмотрим, Как Тренировка Кубернетеса Воля Помогает

Настройки прокси-сервера

В файле application.properties указаны следующие параметры конфигурации прокси-сервера:

wf.prefix = kubernetes.loadgen
wf.proxy.enabled = true
wf.proxy.host = wavefront-proxy
wf.proxy.port = 2878
wf.duration = 10

Показатели, которые будет генерировать это приложение Spring Boot, включают показатели, связанные с JVM, такие как “загрузка классов”, скорость сбора мусора, загрузка процессора процессором, потоки, операции с файлами, время работы системы и т. Д., Все под префиксом “kubernetes.loadgen”, указанным как wf.префикс выше.

Я решил добавить kubernetes в качестве префикса, чтобы подчеркнуть, что это приложение связано с ним. Когда мое приложение Spring Boot начнет работать, оно будет собирать эти показатели и отправлять их на прокси-сервер Wavefront каждые 10 секунд, как определено в разделе wf.продолжительность выше.

Когда мое приложение Spring Boot начнет работать, оно будет собирать эти показатели и отправлять их на прокси-сервер Wavefront каждые 10 секунд, как определено в разделе wf.продолжительность выше.

Шаг 2: Простое оборудование Для Распределенной Трассировки

Я хотел убедиться, что я также могу отправлять распределенные трассировки из приложения в Wavefront. SDK для открытого отслеживания основан на открытом исходном коде и генерирует данные отслеживания нейтральным для платформы способом.

Понимание того, как ваш код, компоненты, вызовы и службы взаимодействуют друг с другом, имеет решающее значение для понимания производительности приложения. Я добавил следующий код для создания компонента Spring Boot, ответственного за поддержание экземпляра трассировщика. Экземпляр трассировщика можно использовать для создания интервалов вызовов приложения, чтобы отслеживать производительность приложения.

Это потребовало добавления следующей зависимости в мой pom.xml файл:


    io.opentracing
    opentracing-api
    0.32.0


    io.opentracing
    opentracing-util
    0.32.0


    com.google.guava
    guava
    19.0


    com.wavefront
    wavefront-opentracing-sdk-java
    1.7

Создание данных диапазона Я создал новый класс Java под названием Trace Util. Мое приложение может получить доступ к инициализированному экземпляру трассировщика из этого класса и может начать создавать данные диапазона для трассировок:

package com.vmware.wavefront.loadgen;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import com.wavefront.opentracing.WavefrontTracer;
import com.wavefront.opentracing.reporting.CompositeReporter;
import com.wavefront.opentracing.reporting.ConsoleReporter;
import com.wavefront.opentracing.reporting.Reporter;
import com.wavefront.opentracing.reporting.WavefrontSpanReporter;
import com.wavefront.sdk.common.WavefrontSender;
import com.wavefront.sdk.common.application.ApplicationTags;
import com.wavefront.sdk.direct.ingestion.WavefrontDirectIngestionClient;
import com.wavefront.sdk.entities.tracing.sampling.ConstantSampler;
import com.wavefront.sdk.proxy.WavefrontProxyClient;

import java.net.InetAddress;
import java.net.UnknownHostException;

import io.opentracing.Tracer;
import io.opentracing.util.GlobalTracer;

@Component("traceutil")
public class TraceUtil {

  /* its own tracer */
  public Tracer tracer;

  public TraceUtil() {

  }

  @Value("${wf.proxy.enabled}")
  public boolean proxyEnabled;

  @Value("${wf.proxy.host}")
  public String proxyhost;

  @Value("${wf.proxy.port}")
  private String proxyport;

  @Value("${wf.trace.enabled}")
  public boolean traceEnabled;

  @Value("${wf.proxy.histogram.port}")
  private String histogramport;

  @Value("${wf.proxy.trace.port}")
  private String traceport;

  @Value("${wf.direct.enabled}")
  public boolean directEnabled;

  @Value("${wf.direct.server}")
  public String server;

  @Value("${wf.direct.token}")
  public String token;

  @Value("${wf.application}")
  public String application;

  @Value("${wf.service}")
  public String service;

  protected final static Logger logger = Logger.getLogger(TraceUtil.class);

  @PostConstruct
  public void init() {
    if(traceEnabled == true && application != null && service != null) {

      ApplicationTags appTags = new ApplicationTags.Builder(application, service).build();
      String hostname = "unknown";
      try {
        hostname = InetAddress.getLocalHost().getHostName();
      } catch (UnknownHostException e) {
        e.printStackTrace();
      }

      WavefrontSender wavefrontSender = null;
      if(proxyEnabled == true) {
        wavefrontSender = new WavefrontProxyClient.Builder(proxyhost).
            metricsPort(Integer.parseInt(proxyport)).
            distributionPort(Integer.parseInt(histogramport)).tracingPort(Integer.parseInt(traceport)).build();
      } else if(directEnabled == true){
        wavefrontSender = new WavefrontDirectIngestionClient.Builder(server, token).build();
      }
      Reporter wfspanreporter = new WavefrontSpanReporter.Builder().withSource(hostname).build(wavefrontSender);
      Reporter consoleReporter = new ConsoleReporter(hostname);
      Reporter composite = new CompositeReporter(wfspanreporter, consoleReporter);
      logger.info("created new tracer with " + application + " : " + service);
      tracer = new WavefrontTracer.Builder(composite, appTags).withSampler(new ConstantSampler(true)).build();
    }
    else {
      logger.info("created new Global Tracer...");
      tracer = GlobalTracer.get();
    }
  }

  public Tracer getTracer() {
    return tracer;
  }
}

Шаг 3. Создание образа Docker

Чтобы приложение работало внутри контейнера, я создал образ Docker, используя следующий файл Dockerfile.

# base image
FROM openjdk:8-jdk-alpine

LABEL maintainer="hgy@gmail.com"
VOLUME /tmp
EXPOSE 8080

RUN apk update
RUN apk add curl

ARG JAR_FILE=target/loadgen-0.0.1-SNAPSHOT.jar
ADD ${JAR_FILE} loadgen-0.0.1.jar

# run the jar file
ENTRYPOINT ["java","-Djava.security.edg=file:/dev/./urandom","-jar","/loadgen-0.0.1.jar"]
Чтобы приложение работало внутри контейнера, я создал образ Docker, используя следующий файл Dockerfile.

Шаг 4. Настройка кластера Kubernetes

Есть много способов запустить Kubernetes, но я решил использовать самый простой способ, который заключается в использовании KIND (Kubernetes в Docker). Он использует мой локальный механизм докеров для запуска одноузлового кластера Kubernetes, идеально подходящего для моих целей тестирования. Давайте посмотрим, Как Обучение Весенней загрузке Уилл Поможет тебе

kind create cluster --name kind-wf
export KUBECONFIG="$(kind get kubeconfig-path --name="kind-wf")"

Теперь, когда мой кластер kind-wf Kubernetes запущен и запущен, а также при правильной настройке среды KUBECONFIG, я могу начать использовать kubectl для настройки интеграции волнового фронта для этого кластера.

Чтобы настроить интеграцию Wavefront для Kubernetes, просто следуйте инструкциям в документации Wavefront. Я загружаю файлы yaml развертывания как для прокси-сервера Wavefront, так и для сборщика Wavefront, который будет собирать и отправлять системные показатели Kubernetes в Wavefront.

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

Найдите диаграмму управления, связанную с интеграцией волнового фронта Kubernetes, здесь.

Шаг 5. Развертывание Модуля Loadgen В Кластере Kubernetes

Теперь мы можем развернуть наш loadgen в кластере kind-wf. Для этого я создал следующий простой файл yaml для развертывания (loadgen-svc.yaml):

---
apiVersion: v1
kind: Namespace
metadata:
  name: loadgen
---
apiVersion: v1
kind: Service
metadata:
  name: wavefront-proxy
  namespace: loadgen
spec:
  type: ExternalName
  externalName: wavefront-proxy.default.svc.cluster.local
  ports:
  - name: wavefront
    port: 2878
    protocol: TCP
  - name: traces
    port: 30000
    protocol: TCP
  - name: histogram
    port: 40000
    protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: loadgen
  namespace: loadgen
  labels:
    app: loadgen
    user: howard
    version: 0.0.5
spec:
  selector:
    matchLabels:
      app: loadgen
  replicas: 2
  template:
    metadata:
      labels:
        app: loadgen
    spec:
      containers:
      - name: loadgen
        image: howardyoo/loadgen:0.0.4
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        resources:
          limits:
            memory: 512Mi
          requests:
            memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
  namespace: loadgen
  name: loadgen-svc
  labels:
    app: loadgen-svc
    user: howard
spec:
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
  type: LoadBalancer
  selector:
    app: loadgen

Этот файл yaml создает модуль, который запускает два экземпляра контейнеров loadgen, сбалансированных по нагрузке как служба на порту 8080 и доступных через этот порт. В приведенном выше фрагменте loadgen ссылается на прокси-службу Wavefront, используя ее внешнее имя и определяя ее как “прокси-сервер wavefront” с соответствующими тремя портами. Прокси-сервер волнового фронта слушает:

• для обычных показателей на его порту по умолчанию 2878 • для гистограмм на порту 40000 • для трассировок на порту 30000. Мы должны определить эти порты, чтобы инструментальный код loadgen мог отправлять все свои показатели, гистограммы и диапазоны прокси-серверу Wavefront, который затем будет пересылать данные на сервер Wavefront, работающий в облаке.

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

Шаг 6: Запуск Loadgen и мониторинг его с помощью волнового фронта

Теперь мы должны иметь следующие типы метрик, поступающих в волновой фронт:

• Системные показатели Kubernetes – как работает ваш кластер, узлы, модули, контейнеры – доставляются сборщиком wavefront • Метрики приложений-(сосредоточены на производительности JVM) для loadgen • Распределенные трассировки для устранения неполадок при запуске loadgen Если вы используете это на своем ноутбуке, вы, вероятно, должны услышать, как вентилятор процессора увеличивается, так как loadgen будет достигать максимума загрузки процессора. Дайте ему поработать некоторое время и проверьте, как работает наш кластер kind-wf, используя панель мониторинга Wavefront Kubernetes на рисунке ниже:

Дайте ему поработать некоторое время и проверьте, как работает наш кластер kind-wf, используя панель мониторинга Wavefront Kubernetes на рисунке ниже:

Наблюдаемость Полного стека

Объединив три отдельные области, в которых вы можете собирать метрики приложений, метрики Kubernetes и данные распределенной трассировки в Wavefront, разработчики теперь имеют полную возможность наблюдать за тем, что происходит сверху донизу в их приложениях. • Разработчики могут понять, как работают их приложения, понимая количество запросов, ошибок и продолжительность их конкретных услуг. Кроме того, они могут понять, как каждый компонент выполняется по отношению к другим компонентам. • Разработчики могут отслеживать все пользовательские метрики для конкретных приложений, которые они использовали. Он включает в себя информацию о том, сколько запущено экземпляров, сколько ресурсов используется и из какого контейнера они запущены. • С приложением, работающим поверх платформы оркестровки, такой как Kubernetes, разработчики могут легко развертывать и запускать свои приложения в любом месте. Они могут сопоставлять и быстро определять, откуда запущено их приложение и сколько запущено экземпляров. Кроме того, можно наблюдать за всем, что происходит на платформе, отслеживая производительность приложений. Все это дает разработчикам полное представление об их стеках.

Все это дает разработчикам полное представление об их стеках.

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

Оригинал: “https://www.codementor.io/@sravancynixit/how-to-instrument-and-monitor-your-spring-boot-2-application-in-kubernetes-using-wavefront-151u5l6wna”