Традиционный проект Spring MVC интегрирует Prometheus

Spring

undefined

предисловие

За две недели до Весеннего фестиваля я написал две статьи об интеграции приложений Spring Boot Prometheus + Grafana для реализации функции мониторинга и оповещения.

С модулем Spring Boot Actuator +micrometer-registry-prometheusМодули, приложения Spring Boot и интеграция с Prometheus стали проще.

Но некоторые старые проекты могут быть проектами Spring MVC, которые не являются Spring Boot. На этот раз я расскажу о том, как традиционный Spring MVC интегрирует Prometheus. Это полный комплект этой серии.

Соответствующая теоретическая часть фактически объяснена в двух предыдущих статьях, поэтому я не буду здесь вдаваться в подробности и перейду сразу к практической части.

Практичный

1. Введите зависимости

На самом деле это введение самых основных зависимостей Java-клиента Prometheus.

		<properties>
			...
            <io.prometheus.version>0.8.0</io.prometheus.version>
        </properties>
        
		<!-- The client -->
		<dependency>
			<groupId>io.prometheus</groupId>
			<artifactId>simpleclient</artifactId>
			<version>${io.prometheus.version}</version>
		</dependency>
		<!-- Hotspot JVM metrics-->
		<dependency>
			<groupId>io.prometheus</groupId>
			<artifactId>simpleclient_hotspot</artifactId>
			<version>${io.prometheus.version}</version>
		</dependency>
        <!-- https://mvnrepository.com/artifact/io.prometheus/simpleclient_servlet -->
        <dependency>
            <groupId>io.prometheus</groupId>
            <artifactId>simpleclient_servlet</artifactId>
            <version>${io.prometheus.version}</version>
        </dependency>

картинаsimpleclient_hotspotЭто поможет собрать метрики Hotspot JVM, и на некоторые другие зависимости можно ссылаться.Официальный гитхабсобственные варианты исследования

2. Настройте новую конечную точку

    <servlet>
        <servlet-name>metrics</servlet-name>
        <servlet-class>io.prometheus.client.exporter.MetricsServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>metrics</servlet-name>
        <url-pattern>/metrics</url-pattern>
    </servlet-mapping>

если интегрированоshiro,spring securityЕсли это так, не забудьте настроить соответствующий путь.

3. Включить параметры мониторинга JVM

Добавьте следующий код в класс запуска,

@PostConstruct
public void init() {
    //输出JVM信息
    DefaultExports.initialize();
}

контрольная работа

Начните проект сейчас, посетитеhttp://ip:port/metrics, вы можете увидеть соответствующие данные индикатора:

# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.
# TYPE jvm_buffer_pool_used_bytes gauge
jvm_buffer_pool_used_bytes{pool="direct",} 1791403.0
jvm_buffer_pool_used_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.
# TYPE jvm_buffer_pool_capacity_bytes gauge
jvm_buffer_pool_capacity_bytes{pool="direct",} 1791403.0
jvm_buffer_pool_capacity_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.
# TYPE jvm_buffer_pool_used_buffers gauge
jvm_buffer_pool_used_buffers{pool="direct",} 44.0
jvm_buffer_pool_used_buffers{pool="mapped",} 0.0
# HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.
# TYPE jvm_memory_pool_allocated_bytes_total counter
jvm_memory_pool_allocated_bytes_total{pool="Code Cache",} 2.4131136E7
jvm_memory_pool_allocated_bytes_total{pool="PS Eden Space",} 1.157973728E9
jvm_memory_pool_allocated_bytes_total{pool="PS Old Gen",} 4.2983992E7
jvm_memory_pool_allocated_bytes_total{pool="PS Survivor Space",} 2.3271936E7
jvm_memory_pool_allocated_bytes_total{pool="Compressed Class Space",} 6964912.0
jvm_memory_pool_allocated_bytes_total{pool="Metaspace",} 5.9245208E7
# HELP jvm_classes_loaded The number of classes that are currently loaded in the JVM
# TYPE jvm_classes_loaded gauge
......

После того, как у вас есть данные, следующие шаги (метрики сбора Prometheus, визуализация)Приложение микросервиса SpringBoot интегрирует Prometheus + Grafana для реализации мониторинга сигналов тревоги.Есть подробная инструкция.

4. Точка сокрытия данных (настраиваемый индикатор Metrics)

Prometheus предоставляет 4 различных типа метрик: счетчик, датчик, гистограмма, сводка.

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

Что касается того, как использоватьофициальный документВ подробном описании вот два простых примера:

Вы можете сначала объявить специальный перехватчик для обработки статистических метрик:

public class PrometheusMetricsInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }
}

Counter

Счетчики можно использовать для записи типов метрик, которые только увеличиваются, а не уменьшаются, например, запись общего количества запросов приложений (http_requests_total).

Для индикаторов типа Counter включен только один метод inc(), который используется для счетчика +1.

public class PrometheusMetricsInterceptor extends HandlerInterceptorAdapter {

    // 用请求路径和http method 当做标签
    private Counter requestCounter = Counter.build()
            .name("io_namespace_http_requests_total")
        	.labelNames("path", "method")
            .help("Total requests.")
        	.register();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        
        // 调用inc() 技术+1
        requestCounter.labels(request.getRequestURI(), request.getMethod()).inc();
        super.afterCompletion(request, response, handler, ex);
    }
}

Некоторые соответствующие PromQL для часто используемых операций агрегирования:

# 常用PromQL
## 查询应用的请求总量
sum(io_namespace_http_requests_total)
## 查询每秒Http请求量
sum(rate(io_wise2c_gateway_requests_total[5m]))
## 查询当前应用请求量Top N的URI
topk(10, sum(io_namespace_http_requests_total) by (path))

Histogram

В основном используется для записи размера (например, байтов HTTP-запроса) или количества событий в указанном диапазоне распределения (сегменты).

Возьмем в качестве примера время ответа запроса request_latency_seconds, если нам нужно записать время ответа HTTP-запроса в соответствии с диапазоном распределения {.05, .01, .025, .05, .075, .1, .25, .5 , .75, 1, Количество раз в 2,5, 5, 7,5, 10}.

public class PrometheusMetricsInterceptor extends HandlerInterceptorAdapter {

    private Histogram requestLatencyHistogram = Histogram.build()
            .labelNames("path", "method", "code")
            .name("io_namespace_http_requests_latency_seconds_histogram")
            .help("Request latency in seconds.")
            .register();

    // spring interceptor 单例,线程不安全,所以使用threadlocal
    private ThreadLocal<Histogram.Timer> timerThreadLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Histogram.Timer histogramRequestTimer = requestLatencyHistogram.labels(request.getRequestURI(), request.getMethod()).startTimer();
        timerThreadLocal.set(histogramRequestTimer);
        return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        Histogram.Timer histogramRequestTimer = timerThreadLocal.get();
        histogramRequestTimer.observeDuration();
        timerThreadLocal.remove();
        super.afterCompletion(request, response, handler, ex);
    }
}

Наконец, получите доступ к ранее настроенному/metricsКонечная точка, просмотрите данные соответствующих скрытых точек.

Эпилог

На этом то, как традиционный Spring MVC интегрирует Prometheus, закончено, и его можно есть вместе с первыми двумя статьями.

Надеюсь принести вам некоторую прибыль.

Если эта статья была вам полезна, я надеюсь, что вы можете поставить лайк, это самая большая мотивация для меня 🤝🤝🤗🤗.

Ссылаться на