Статьи

Мониторинг микросервисов с помощью Spring Cloud Sleuth, ELK и Zipkin

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

Тем не менее, основным требованием к архитектуре микросервисов является то, что доступ к истории вызовов относительно прост, включая возможность просмотра распространения запросов между несколькими микросервисами. Очистка журналов не является правильным решением для этой проблемы. Есть несколько полезных инструментов, которые можно использовать при создании микросервисов с платформами Spring Boot и Spring Cloud.

инструменты

  • Spring Cloud Sleuth : библиотека, доступная как часть проекта Spring Cloud. Позволяет отслеживать прогресс последующих микросервисов, добавляя соответствующие заголовки к HTTP-запросам. Библиотека основана на концепции MDC (Mapped Diagnostic Context ), где вы можете легко извлечь значения, помещенные в контекст, и отобразить их в журналах.

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

  • ELK . Elasticsearch, Logstash и Kibana — три разных инструмента, которые обычно используются вместе. Они используются для поиска, анализа и визуализации данных журнала в режиме реального времени.

Многие из вас, даже если вы раньше не пользовались Java или микросервисами , возможно, слышали о Logstash и Kibana. Например, если вы посмотрите на  hub.docker.com , среди самых популярных изображений, вы найдете те для вышеупомянутых инструментов. В нашем примере мы просто будем использовать эти изображения. Начнем с запуска контейнера с Elasticsearch.

docker run -d -it --name es -p 9200:9200 -p 9300:9300 elasticsearch

Затем мы запускаем контейнер Kibana и связываем его с Elasticsearch.

docker run -d -it --name kibana --link es:elasticsearch -p 5601:5601 kibana

В конце мы запускаем Logstash с объявленным вводом и выводом. В качестве входных данных мы объявляем TCP, который совместим LogstashTcpSocketAppender и используется в качестве приложения для ведения журнала в нашем примере приложения. Как результат, Elasticsearch был объявлен. Каждый микросервис будет проиндексирован по своему имени с  микро- префиксом. Для Logstash доступно много других входных и выходных плагинов, которые перечислены здесь . Еще один метод настройки ввода с использованием RabbitMQ и Spring  AMQPAppenderописано в одном из моих предыдущих постов Как отправлять журналы с помощью Logstash, Elasticsearch и RabbitMQ .

docker run -d -it --name logstash -p 5000:5000 logstash -e 'input { tcp { port => 5000 codec => "json" } } output { elasticsearch { hosts => ["192.168.99.100"] index => "micro-%{serviceName}"} }'

Microservices

Теперь давайте посмотрим на образцы микросервисов. Этот пост является продолжением одного из предыдущих постов в моем блоге о  создании микросервиса с использованием Spring Cloud, Eureka и Zuul . Архитектура и предоставляемые сервисы такие же, как в предыдущем примере. Исходный код доступен на GitHub (ветке logstash). Как упоминалось ранее, мы будем использовать библиотеку Logback для отправки данных журнала в Logstash.  В дополнение к трем зависимостям Logback, мы также добавляем библиотеки для интеграции с Zipkin и Spring Cloud Sleuth Starter. Вот фрагмент pom.xml для микросервисов:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
	<groupId>net.logstash.logback</groupId>
	<artifactId>logstash-logback-encoder</artifactId>
	<version>4.9</version>
</dependency>
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.3</version>
</dependency>
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-core</artifactId>
	<version>1.2.3</version>
</dependency>

В каталоге также есть файл конфигурации Logback  src/main/resources . Вот  logback.xml фрагмент Мы можем указать , какие лесозаготовительные поля отправки Logstash Объявив тег , как  mdc, logLevel, messageи т.д. Мы также добавление службы имени поле для создания индекса Elasticsearch.

<appender name="STASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
	<destination>192.168.99.100:5000</destination>
	<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
		<providers>
			<mdc />
			<context />
			<logLevel />
			<loggerName />
			<pattern>
				<pattern>
          {
          "serviceName": "account-service"
          }
        </pattern>
			</pattern>
			<threadName />
			<message />
			<logstashMarkers />
			<stackTrace />
		</providers>
	</encoder>
</appender>

Конфигурация Spring Cloud Sleuth очень проста. Нам нужно только добавить spring-cloud-starter-sleuthзависимость pom.xml и объявить сэмплер @Bean. В примере я объявил AlwaysSampler, что экспортирует каждый диапазон, но есть и другой вариант  PercentageBasedSampler, который выбирает фиксированную долю диапазонов.

@Bean
public AlwaysSampler defaultSampler() {
  return new AlwaysSampler();
}

Kibana

После запуска док-контейнеров ELK нам нужно запустить наши микросервисы. Существует пять приложений Spring Boot, которые необходимо запустить:

  1. discovery-service,

  2. account-service,

  3. customer-service,

  4. gateway-service,

  5. zipkin-service,

После запуска всех из них мы можем попытаться вызвать некоторые службы — например, http: // localhost: 8765 / api / customer / Customers / {id} , что вызывает вызов служб как клиента, так и учетной записи. Все журналы будут храниться в Elasticsearch с  micro-%{serviceName}  индексом. Их можно искать в Кибане по  micro-* шаблону индекса. Шаблоны индексов создаются в Kibana в разделе « Управление»  > « Шаблоны индексов» . Кибана доступна по адресу http://192.168.99.100:5601 . После первого запуска нам будет предложено ввести шаблон индекса, поэтому давайте наберем micro-*. В разделе  Discover мы можем просмотреть все журналы, соответствующие напечатанному шаблону, с визуализацией временной шкалы.

Kibana — довольно интуитивно понятный и удобный инструмент. Я не буду подробно описывать, как использовать Kibana, потому что вы можете легко узнать это самостоятельно, читая документацию или просто щелкая пользовательский интерфейс. Самое главное, чтобы иметь возможность искать журналы по критериям фильтрации. На рисунке ниже приведен пример поиска журналов по  X-B3-TraceId полю, которое добавляется в заголовок запроса Spring Cloud Sleuth. Sleuth также добавляет X-B3-TraceId для маркировки запросов для одного микросервиса. Мы можем выбрать, какие поля будут отображаться в списке результатов; В этом примере я выбрал  message и serviceName,  как вы можете видеть на левой панели рисунка ниже.

Вот картина с деталями одного запроса. Это видно после раскрытия каждой строки журнала.

Цыпкин

Spring Cloud Sleuth также отправляет статистику Зипкину. Это другой тип данных, чем данные, хранящиеся в Logstash. Это временная статистика для каждого запроса. Zipkin UI действительно прост. Вы можете фильтровать запросы по некоторым критериям, таким как время, имя сервиса и имя конечной точки.

Ниже приведена картинка с теми же запросами, которые были визуализированы с помощью Kibana ( http: // localhost: 8765 / api / customer / Customers / {id} ).

We can always see the details of each request by clicking on it. Then, you see the picture similar to what is visible below. In the beginning, the request has been processed on the API gateway. Then, the gateway discovers customer service on Eureka server and calls that service. Customer service also has to discover the account service and then call it. In this view, you can easily find out which operation is the most time-consuming.

Conclusion

Distributed, independent microservices and centralized log monitoring make for the right solution. With tools like ELK and Zipkin, microservices monitoring seems to not be a very difficult problem to solve. There are also some other tools — for example, Hystrix and Turbine — that provide real-time metrics for the requests processed by microservices.