Одной из проблем в архитектуре микросервисов является возможность устранения проблем. Простое действие пользователя может вызвать цепочку нисходящих вызовов микросервиса. Было бы утомительно отслеживать журналы, относящиеся к определенному действию пользователя через микросервисы. В дополнение к этому, мы могли бы хотеть отследить, почему определенный вызов микросервиса занимает так много времени. Мы можем использовать Spring Cloud Sleuth для решения подобных проблем. Spring Cloud Sleuth предоставляет возможности распределенной трассировки, и мы также можем экспортировать эту информацию трассировки в Zipkin для визуализации трассировок вызовов.
Микроуслуги с использованием Spring Boot и Spring Cloud
- Часть 1. MicroServices: Spring Boot и Spring Cloud Обзор
- Часть 2. MicroServices: управление конфигурацией с помощью Spring Cloud Config и Vault
- Часть 3. MicroServices: реестр и обнаружение Spring Cloud Service
- Часть 4: MicroServices: автоматический выключатель Spring Cloud с использованием Netflix Hystrix
- Часть 5. MicroServices: Spring Cloud Zuul Proxy в качестве шлюза API
- Часть 6. MicroServices: распределенная трассировка с помощью Spring Cloud Sleuth и Zipkin
В этом посте мы собираемся узнать:
- Отслеживание распределенных сервисных звонков
- Использование Spring Cloud Sleuth для распределенной трассировки
- Распределенная трассировка с Zipkin Server
Отслеживание распределенных сервисных звонков
В мире микросервисов пользовательское действие в пользовательском интерфейсе может вызывать одну конечную точку API микросервиса, которая, в свою очередь, вызывает другую конечную точку микросервиса.
Например, когда пользователь видит каталог, shoppingcart-ui вызывает API REST службы каталогов http: // localhost: 8181 / api / products, который, в свою очередь, вызывает API REST службы инвентаризации http: // localhost: 8282 / api / инвентарь, чтобы проверить наличие инвентаря.
Предположим, произошла исключительная ситуация или возвращенные данные неверны, и вы хотите выяснить, что не так, просмотрев журналы. Но на данный момент нет способа сопоставить журналы этого конкретного пользователя по нескольким сервисам.
Распределенная трассировка бедного человека
Одним из решений этого является то, что в начале цепочки вызовов мы можем создать CORRELATION_ID и добавить его во все операторы журнала. Наряду с этим отправьте CORRELATION_ID в качестве заголовка для всех нисходящих служб, чтобы эти нисходящие службы также использовали CORRELATION_ID в журналах. Таким образом, мы можем идентифицировать все операторы журнала, связанные с определенным действием в службах.
Мы можем реализовать это решение, используя функцию MDC каркасов Logging. Обычно у нас есть перехватчик WebRequest, где вы можете проверить, есть ли заголовок CORRELATION_ID. Если в заголовке нет CORRELATION_ID, то создайте новый и установите его в MDC. Каркасы журналов включают в себя информацию, установленную в MDC, со всеми операторами журналов.
Но вместо того, чтобы делать всю эту работу, мы можем использовать Spring Cloud Sleuth, который сделает все это и многое другое для нас.
Использование Spring Cloud Sleuth для распределенной трассировки
Во-первых, ознакомьтесь с некоторой терминологией Span, Trace, Annotations здесь http://cloud.spring.io/spring-cloud-static/Finchley.M7/single/spring-cloud.html#_terminology .
Давайте добавим стартер Sleuth к сервису инвентаризации и сервису каталогов .
1
2
3
4
|
< dependency > < groupId >org.springframework.cloud</ groupId > < artifactId >spring-cloud-starter-sleuth</ artifactId > </ dependency > |
Как только вы добавите Sleuth Starter и запустите службы, вы можете наблюдать в журналах что-то вроде этого.
1
2
|
2018 - 03 - 20 10 : 19 : 15.512 INFO [inventory-service,,,] 53685 --- [trap-executor- 0 ] c.n.d.s.r.aws.ConfigClusterResolver ... 2018 - 03 - 20 10 : 24 : 15.507 INFO [inventory-service,,,] 53685 --- [trap-executor- 0 ] c.n.d.s.r.aws.ConfigClusterResolver ... |
Теперь нажмите любую конечную точку REST службы инвентаризации, скажем, http: // localhost: 8282 / api / inventory. Тогда вы можете наблюдать TraceID , SpanID в журналах.
1
|
2018 - 03 - 20 10 : 15 : 38.466 INFO [inventory-service,683f8e4370413032,d8abe400c68a9a6b, false ] 53685 --- [oryController- 3 ] ... |
Sleuth включает шаблон [appname, traceId, spanId, exportable] в журналы MDC.
Теперь вызовите конечную точку службы каталога http: // localhost: 8181 / api / products, которая внутренне вызывает конечную точку службы инвентаризации http: // localhost: 8282 / api / inventory.
В журналах службы каталогов вы можете найти записи журнала, например:
1
|
2018 - 03 - 20 10 : 54 : 29.625 INFO [catalog-service,0335da07260d3d6f,0335da07260d3d6f, false ] 53617 --- [io- 8181 -exec- 10 ] ... |
И, проверьте журналы в инвентаризации службы, вы можете найти записи журнала что-то вроде:
1
|
2018 - 03 - 20 10 : 54 : 29.662 INFO [inventory-service,0335da07260d3d6f,1af68249ac3a6902, false ] 53685 --- [oryController- 6 ] ... |
Обратите внимание, что TraceID 0335da07260d3d6f одинаков как для службы каталогов, так и для службы инвентаризации для одного и того же вызова API REST. Таким образом, мы можем легко сопоставить журналы между службами.
Значение false в [инвентарь-сервис, 0335da07260d3d6f, 1af68249ac3a6902, false] указывает, что эта трассировка не экспортируется ни на один сервер трассировки, например Zipkin. Давайте посмотрим, как мы можем экспортировать информацию трассировки в Zipkin.
Распределенная трассировка с Zipkin Server
Мы узнали, как использовать Sleuth для добавления информации о трассировке в журналы. В дополнение к этому, мы также можем экспортировать эту информацию в Zipkin, чтобы мы могли визуализировать это через пользовательский интерфейс.
Создать Zipkin Server как приложение SpringBoot
Мы можем запустить Zipkin-сервер как приложение с весенней загрузкой или запустить в Docker-контейнере.
На данный момент Zipkin не поддерживает Spring Boot 2. Таким образом, мы можем создать zipkin-сервер приложения SpringBoot, используя версию 1.5.10.RELEASE, и добавить зависимости zipkin-server, zipkin-autoconfigure-ui.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 < modelVersion >4.0.0</ modelVersion > < groupId >com.sivalabs</ groupId > < artifactId >zipkin-server</ artifactId > < version >0.0.1-SNAPSHOT</ version > < packaging >jar</ packaging > < name >zipkin-server</ name > < parent > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-parent</ artifactId > < version >1.5.10.RELEASE</ version > </ parent > < properties > < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > < project.reporting.outputEncoding >UTF-8</ project.reporting.outputEncoding > < java.version >1.8</ java.version > < spring-cloud.version >Edgware.RELEASE</ spring-cloud.version > </ properties > < dependencies > < dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-web</ artifactId > </ dependency > < dependency > < groupId >org.springframework.cloud</ groupId > < artifactId >spring-cloud-starter-zipkin</ artifactId > </ dependency > < dependency > < groupId >io.zipkin.java</ groupId > < artifactId >zipkin-server</ artifactId > </ dependency > < dependency > < groupId >io.zipkin.java</ groupId > < artifactId >zipkin-autoconfigure-ui</ artifactId > < scope >runtime</ scope > </ dependency > </ dependencies > < dependencyManagement > < dependencies > < dependency > < groupId >org.springframework.cloud</ groupId > < artifactId >spring-cloud-dependencies</ artifactId > < version >${spring-cloud.version}</ version > < type >pom</ type > < scope >import</ scope > </ dependency > </ dependencies > </ dependencyManagement > < build > < plugins > < plugin > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-maven-plugin</ artifactId > </ plugin > </ plugins > </ build > < repositories > < repository > < id >spring-milestones</ id > < name >Spring Milestones</ name > < snapshots > < enabled >false</ enabled > </ snapshots > </ repository > </ repositories > </ project > |
Добавьте аннотацию @EnableZipkinServer к основному классу точки входа.
01
02
03
04
05
06
07
08
09
10
11
12
|
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import zipkin.server.EnableZipkinServer; @SpringBootApplication @EnableZipkinServer public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication. class , args); } } |
Установите порт и имя приложения в application.properties.
1
2
|
spring.application.name=zipkin-server server.port= 9411 |
Теперь вы можете запустить Zipkin Server, запустив ZipkinServerApplication .
Zipkin Server как Docker-контейнер
Вместо создания сервера Zipkin в качестве приложения SpringBoot, вы можете использовать образ Docker для OpenZipkin .
Мы можем создать сервер Zipkin, поддерживаемый хранилищем данных в памяти, используя следующий файл docker-compose-mem.yml .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
version: '2' services: # The zipkin process services the UI, and also exposes a POST endpoint that # instrumentation can send trace data to. Scribe is enabled by default. zipkin: image: openzipkin/zipkin container_name: zipkin # Environment settings are defined here https://github.com/openzipkin/zipkin/tree/1.19.0/zipkin-server#environment-variables environment: - STORAGE_TYPE=mem # Uncomment to disable scribe # - SCRIBE_ENABLED=false # Uncomment to enable self-tracing # - SELF_TRACING_ENABLED=true # Uncomment to enable debug logging # - JAVA_OPTS=-Dlogging.level.zipkin=DEBUG ports: # Port used for the Zipkin UI and HTTP Api - 9411:9411 |
Вы также можете использовать образ докера, поддерживаемый хранилищем данных MySQL, используя https://github.com/openzipkin/docker-zipkin/blob/master/docker-compose.yml .
После запуска сервера Zipkin вы можете перейти по адресу http: // localhost: 9411 /, чтобы просмотреть панель мониторинга пользовательского интерфейса Zipkin Server.
Экспорт информации трассировки на Zipkin Server
Мы заметили, что информация трассировки печатается в журналах, но не экспортируется. Мы можем экспортировать их на сервер Zipkin, чтобы можно было визуализировать следы на панели инструментов пользовательского интерфейса Zipkin Server.
Добавьте стартер Zipkin Client как к сервису инвентаризации, так и сервису каталогов.
1
2
3
4
|
< dependency > < groupId >org.springframework.cloud</ groupId > < artifactId >spring-cloud-starter-zipkin</ artifactId > </ dependency > |
Сконфигурируйте URL сервера Zipkin в bootstrap.properties службы инвентаризации и службы каталогов.
1
2
|
spring.zipkin.base-url=http: //localhost:9411/ spring.sleuth.sampler.probability= 1 |
ПРИМЕЧАНИЕ . По умолчанию spring.sleuth.sampler.probability = 0.1, что означает, что только 10% информации о трассировке будет экспортировано в Zipkin. Сделайте это до желаемого процента.
Теперь перезапустите и службу инвентаризации, и службу каталогов и вызовите конечную точку http: // localhost: 8181 / api / products. Вы можете заметить, что в журналах напечатано значение true, означающее, что оно экспортируется.
1
|
2018 - 03 - 20 11 : 41 : 02.241 INFO [catalog-service,7d0d44fe314d7758,7d0d44fe314d7758, true ] 53617 --- [nio- 8181 -exec- 5 ] c.s.c.services.ProductService |
Теперь перейдите к Zipkin UI Dashboard, вы можете увидеть имена сервисов, заполненные в первом выпадающем списке. Выберите сервис, который хотите проверить, или выберите все, а затем нажмите кнопку «Найти следы».
Нажмите на любой след, который вы можете увидеть цепочку вызовов и данные о задержке для каждого диапазона.
Вы также можете нажать на ссылку Зависимости в верхней панели навигации, чтобы увидеть зависимости сервиса.
Вы можете найти исходный код этой статьи по адресу https://github.com/sivaprasadreddy/spring-boot-microservices-series
Опубликовано на Java Code Geeks с разрешения Сивы Редди, партнера нашей программы JCG . См. Оригинальную статью здесь: MicroServices. Часть 6. Распределенная трассировка с помощью Spring Cloud Sleuth и Zipkin.
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |