文章目錄
-
-
- 版本說明
- 簡介
- 術語
- Zipkin
- 示例
-
- 啟動zipkin
- 依賴
- 配置檔案
- 驗證
- 使用rabbitmq進行鍊路資料傳輸(可選)
- 日志收集(可選)
-
- Elasticsearch+Kibana+Logstash
-
在分布式系統中,鍊路将總是十分重要。
版本說明
元件 | 版本 | 說明 |
---|---|---|
zipkin | 2.12.9 | |
rabbitmq | 3.7.15 | |
erl | 10.4 | rabbitmq依賴 |
elasticsearch | 6.5.3 | 使用7.x會與zipkin沖突 |
kibana | 6.5.3 | 使用7.x會與zipkin沖突 |
logstash | 6.5.3 | 使用7.x會與zipkin沖突 |
簡介
Spring Cloud Sleuth 為服務之間調用提供鍊路追蹤。了解到一個服務請求經過了哪些服務,每個服務處理花費了多長。進而讓我們理清各微服務間的調用關系。
功能:
- 耗時分析: 獲得每個采樣(鍊路追蹤可以不展示全部)請求的耗時;
- 可視化錯誤: 對于程式未捕捉的異常,可以通過內建 Zipkin 服務界面上看到;
- 鍊路優化: 對于調用比較頻繁的服務,可以針對這些服務實施一些優化措施。
術語
- Span:基本工作單元,發送一個遠端排程任務就會産生一個Span,Span是用一個64位ID唯一辨別的,Trace是用另一個64位ID唯一辨別的。Span還包含了其他的資訊,例如摘要、時間戳事件、Span的ID以及程序ID。
- Trace:由一系列Span組成的,呈樹狀結構。請求一個微服務系統的API接口,這個API接口需要調用多個微服務單元,調用每個微服務單元都會産生一個新的Span,所有由這個請求産生的Span組成了這個Trace。
- Annotation:用于記錄一個事件,定義一個請求的開始和結束,如下:
- cs (Client Sent):用戶端發送一個請求,描述Span的開始。
- sr (Server Received):服務端獲得請求并準備開始處理它,如果将其sr減去cs時間戳,便可得到網絡傳輸的時間。
- ss (Server Sent):服務端發送響應,該注解表明請求處理的完成(當請求傳回用戶端),用ss的時間戳減去sr時間戳,便可以得到伺服器請求的時間。
- cr (Client Received):用戶端接收響應,此時Span結束,如果cr的時間戳減去cs時間戳,便可以得到整個請求所消耗的時間。
Zipkin
Zipkin是一種分布式鍊路追蹤系統。 收集鍊路中的資料,并且可以以界面的形式展現。
Zipkin UI還提供了一個依賴關系圖,顯示了每個應用程式通過的跟蹤請求數。
zipkin已經不再支援開發者自己開發zipkin server,而是以一個jar包啟動。
下載下傳jar包
curl -sSL https://zipkin.io/quickstart.sh | bash -s
或者https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
或者pull docker鏡像
docker pull zipkin
示例
啟動zipkin
java -jar zipkin.jar
預設端口為9411
依賴
所有的服務相對于zipkin server 都是client,是以所有的服務都需要以下依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
配置檔案
增加以下内容
spring:
#鍊路追蹤
sleuth:
web:
client:
enabled: true
# 采樣比例,預設是0.1,最大為1,表示采集資料的比例
sampler:
probability: 1.0
#zipkin的位址
zipkin:
base-url: http://localhost:9411/
驗證
代碼不需要任何改動。
確定啟動了consul,zipkin
在浏覽器中輸入
http://localhost:9411
調用服務,可以在浏覽器中搜尋服務,獲得鍊路追蹤後的詳細資訊;還可以觀察每一個服務的依賴關系。
使用rabbitmq進行鍊路資料傳輸(可選)
1 . 下載下傳,安裝,啟動rabbitmq;在浏覽器中輸入
http://localhost:15672
檢查是否成功
2 . 啟動zipkin
zipkin啟動需要讀取一些環境變量來配置自己。
屬性 | 環境變量 | 描述 |
---|---|---|
zipkin.collector.rabbitmq.addressed | RABBIT_ADDRESSES | 用逗号分隔的 RabbitMQ 位址清單,例如localhost:5672,localhost:5673 |
zipkin.collector.rabbitmq.password | RABBIT_PASSWORD | 連接配接到 RabbitMQ 時使用的密碼,預設為 guest |
zipkin.collector.rabbitmq.username | RABBIT_USER | 連接配接到 RabbitMQ 時使用的使用者名,預設為guest |
zipkin.collector.rabbitmq.virtual-host | RABBIT_VIRTUAL_HOST | 使用的 RabbitMQ virtual host,預設為 / |
zipkin.collector.rabbitmq.use-ssl | RABBIT_USE_SSL | 設定為true則用 SSL 的方式與 RabbitMQ 建立連結 |
zipkin.collector.rabbitmq.concurrency | RABBIT_CONCURRENCY | 并發消費者數量,預設為1 |
zipkin.collector.rabbitmq.connection-timeout | RABBIT_CONNECTION_TIMEOUT | 建立連接配接時的逾時時間,預設為 60000毫秒,即 1 分鐘 |
zipkin.collector.rabbitmq.queue | RABBIT_QUEUE | 從中擷取 span 資訊的隊列,預設為 zipkin |
最好使用環境變量,在java指令中直接設定屬性值會失效
set RABBIT_ADDRESSES=localhost
set path=%path%;RABBIT_ADDRESSES
java -jar zipkin.jar
在浏覽器中輸入
http://localhost:9411/zipkin/
檢查是否成功
3 . 引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
4 . 修改配置檔案
spring:
# 使用rabbitmq後去掉
# zipkin:
# base-url: http://localhost:9411/
zipkin:
sender:
type: rabbit
rabbitmq:
host: localhost
username: guest
password: guest
port: 5672
注釋 base-url,添加rabbitmq的配置
日志收集(可選)
Elasticsearch+Kibana+Logstash
Logstash(收集伺服器上的日志檔案) -->然後儲存到 ElasticSearch(搜尋引擎) -->Kibana提供友好的web界面(從ElasticSearch讀取資料進行展示)
1 .下載下傳Elasticsearch和Kibana,Logstash,解壓
2 .啟動
elasticsearch.bat
,
kibana.bat
3 .配置Logstash并啟動
在logstash安裝目錄/bin下建立檔案logstash.conf,内容如下
input {
beats {
port => 5044
}
}
filter {
# pattern matching logback pattern
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
#index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
index => "zipkin-%{+YYYY.MM.dd}"
#user => "elastic"
#password => "changeme"
}
}
啟動logstash:
logstash -f logstash.conf
4 .添加依賴
<!--日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.11</version>
</dependency>
5 .配置服務logback-spring.xml,以json格式将日志輸出到檔案,在項目目錄/bulid下
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- Example for logging into the build folder of your project -->
<property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>
<!-- You can override this to have a custom pattern -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- Appender to log to console -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- Minimum logging level to be presented in the console logs-->
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- Appender to log to file -->
<appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- Appender to log to file in a JSON format -->
<appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}.json</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"severity": "%level",
"service": "${springAppName:-}",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"parent": "%X{X-B3-ParentSpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"rest": "%message"
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<!-- uncomment this to have also JSON logs -->
<appender-ref ref="logstash"/>
<appender-ref ref="flatfile"/>s
</root>
</configuration>
6 .啟動consul,rabbitmq,Elasticsearch,Kibana,各個服務
7 .啟動zipkin
set RABBIT_ADDRESSES=localhost
set STORAGE_TYPE=elasticsearch
set ES_HOSTS=http://localhost:9200
set ES_INDEX=zipkin
set path=%path%;RABBIT_ADDRESSES;STORAGE_TYPE;ES_HOSTS;ES_INDEX
java -jar zipkin.jar
8 .測試通路
http://localhost:9411/zipkin/
9 .将資料通過kibana展示
- kibana預設端口是
,在浏覽器中輸入5601
http://localhost:5601
- 單擊“Management”按鈕,然後單擊“Add New”,添加一個index。ElasticSearch中寫傳入連結路資料的index配置為“zipkin”,那麼在界面填寫為“zipkin*”,單擊“Create”按鈕。
- 點選Discover按鈕檢視資料