Статьи

Хранение месяцев исторических метрик от Hystrix в графите

Одной из главных особенностей  Hystrix  является красивая латентная панель с интенсивным использованием данных и высокой задержкой  :

Хотя это всего лишь побочный эффект от того, что на самом деле делает Hystrix (автоматические выключатели, пулы потоков, тайм-ауты и т. Д.), Это, как правило, самая впечатляющая функция. Чтобы заставить его работать, вы должны включить  hystrix-metrics-event-stream зависимость:

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-metrics-event-stream</artifactId>
    <version>1.4.0-RC6</version>
</dependency>

и зарегистрируйте встроенный сервлет, например, во встроенном Jetty:

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
 
//...
 
Server server = new Server(8090);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
server.setHandler(context);
final HystrixMetricsStreamServlet servlet = new HystrixMetricsStreamServlet();
final ServletHolder holder = new ServletHolder(servlet);
context.addServlet(holder, "/hystrix.stream");
server.start();import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
 
//...
 
Server server = new Server(8090);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
server.setHandler(context);
final HystrixMetricsStreamServlet servlet = new HystrixMetricsStreamServlet();
final ServletHolder holder = new ServletHolder(servlet);
context.addServlet(holder, "/hystrix.stream");
server.start();

Конечно, если у вас уже есть веб-приложение, это намного проще. Вот пример в Spring Boot:

@Bean
public ServletRegistrationBean servletRegistrationBean() {
    return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream");
}

Отныне ваше приложение будет транслировать метрики в реальном времени в формате JSON, которые легко можно использовать с помощью инструментальной панели с открытым исходным кодом, почти полностью написанной на JavaScript:

$ git clone git@github.com:Netflix/Hystrix.git
$ cd Hystrix
$ ./gradlew :hystrix-dashboard:jettyRun

Через несколько секунд вы можете просмотреть  localhost:7979 и указать свой /hystrix.stream сервлет. Предполагая, что ваше приложение кластеризовано, скорее всего, вы добавите  Turbine  на вечеринку. 

Если вы используете Hystrix, вы уже знаете обо всем этом. Но один из вопросов, которые мне задают чаще всего, таков:  почему эти показатели такие краткосрочные ? Действительно, если вы посмотрите на панель инструментов выше, показатели агрегируются со скользящим окном в диапазоне от 10 секунд до 1 минуты. Если вы получили автоматическое уведомление по электронной почте о каком-либо происшествии на производстве, испытали кратковременную медлительность или услышали о проблемах с производительностью от клиента, соответствующая статистика об этом инциденте уже может быть утеряна или может быть скрыта из-за общей нестабильности, возникшей впоследствии. 

Это на самом деле разработано — вы не можете иметь как статистику с низкой задержкой, так и статистику, близкую к реальному времени, которая также надежна и может просматриваться дни, если не месяцы назад. Но вам не нужны две системы мониторинга для краткосрочных метрик и долгосрочных трендов. Вместо этого вы можете  напрямую использовать Graphite с помощью метрик Hystrix. Почти без кода, только немного клея здесь и там.

Публикация метрик в метриках Dropwizard

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

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-codahale-metrics-publisher</artifactId>
    <version>1.4.0-RC6</version>
    <exclusions>
        <exclusion>
            <groupId>com.codahale.metrics</groupId>
            <artifactId>metrics-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-core</artifactId>
    <version>3.1.0</version>
</dependency>

Вы должны соединить эти две библиотеки в явном виде, я использую Spring Ботинок для оркестровки, заметьте , что  MetricRegistry будет  создана автоматически по загрузке :

@Bean
HystrixMetricsPublisher hystrixMetricsPublisher(MetricRegistry metricRegistry) {
    HystrixCodaHaleMetricsPublisher publisher = new HystrixCodaHaleMetricsPublisher(metricRegistry);
    HystrixPlugins.getInstance().registerMetricsPublisher(publisher);
    return publisher;
}

В тот момент, когда Hystrix публикует метрики Dropwizard, мы можем перенаправить эти метрики в SLF4J, JMX или … Graphite!

Графит и Графана

Нам нужна еще одна зависимость:

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-graphite</artifactId>
    <version>3.1.0</version>
</dependency>

Это позволяет  metrics библиотеке публиковать данные прямо в Graphite, снова немного склеивая:

@Bean
public GraphiteReporter graphiteReporter(MetricRegistry metricRegistry) {
    final GraphiteReporter reporter = GraphiteReporter
            .forRegistry(metricRegistry)
            .build(graphite());
    reporter.start(1, TimeUnit.SECONDS);
    return reporter;
}
 
@Bean
GraphiteSender graphite() {
    return new Graphite(new InetSocketAddress("localhost", 2003));
}

Очевидно, вы хотели бы настроить адрес графита. Настройка Graphite и Grafana довольно громоздка, к счастью, для этого есть  образ Docker :

$ docker run -d \
    -p 8070:80 -p 2003:2003 -p 8125:8125/udp -p 8126:8126 \
    --name grafana-dashboard \
    choopooly/grafana_graphite

Если все настроено правильно, пройдите прямо  localhost:8070 и поиграйте с некоторыми инструментальными панелями. Вот мой:

Новые возможности

Встроенная  панель управления Hystrix  очень отзывчива и полезна. Однако наличие статистики дней, недель или даже месяцев открывает много возможностей. Выбор функций, недоступных с помощью встроенной панели инструментов, которую вы можете легко настроить с помощью Graphite / Grafana:

  • Months of statistics (obviously), compared to seconds
  • Metrics ignored in standard dashboard, like lower percentiles, total counters, etc.
  • Full history of some metrics, rather than instant value (e.g. thread pool utilization)
  • Ability to compare seemingly unrelated metrics on single chart, e.g. several different commands latency vs. thread pool queue size — all with full history
  • Drill down — look at weeks or zoom in to minutes

Examples can be found on previous screenshot. It totally depends on your use case, but unless your system is on fire, long-term statistics that you can examine hours or weeks after incident are probably more useful than built-in dashboard.

* There is a tiny bug in Hystrix metrics publisher, will be fixed in 1.4.0-RC7
** Features described above are available out-of-the-box in our micro-infra-spring open source project