Zipkin初体验
背景
Zipkin 是一个开放源代码分布式的跟踪系统,每个服务向zipkin报告计时数据,zipkin会根据调用关系通过Zipkin UI生成依赖关系图。
初体验
部署服务端
找台linux服务器,执行:
curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar
数据默认会存储在内存中,重启进程后数据就没有了。
纯JAVA客户端
pom依赖
<dependency>
<groupId>io.zipkin.brave</groupId>
<artifactId>brave</artifactId>
<version>5.12.6</version>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-sender-okhttp3</artifactId>
<version>2.15.2</version>
</dependency>
代码示例:
import java.util.concurrent.TimeUnit;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.context.log4j2.ThreadContextScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
import zipkin2.codec.SpanBytesEncoder;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;
public class TraceDemo {
public static void main(String[] args) {
Sender sender = OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans");
AsyncReporter asyncReporter = AsyncReporter.builder(sender)
.closeTimeout(1000, TimeUnit.MILLISECONDS)
.build(SpanBytesEncoder.JSON_V2);
Tracing tracing = Tracing.newBuilder()
.localServiceName("tracer-demo")
.spanReporter(asyncReporter)
// .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
.currentTraceContext(
ThreadLocalCurrentTraceContext.newBuilder().addScopeDecorator(ThreadContextScopeDecorator.create())
.build())// // puts trace IDs into logs
.build();
Tracer tracer = tracing.tracer();
Span span = tracer.newTrace().name("encode").start();
try {
doSomethingExpensive();
} finally {
span.finish();
}
Span twoPhase = tracer.newTrace().name("twoPhase").start();
try {
Span prepare = tracer.newChild(twoPhase.context()).name("prepare").start();
try {
prepare();
} finally {
prepare.finish();
}
Span commit = tracer.newChild(twoPhase.context()).name("commit").start();
try {
commit();
} finally {
commit.finish();
}
} finally {
twoPhase.finish();
}
sleep(1000);
}
private static void doSomethingExpensive() {
sleep(500);
}
private static void commit() {
sleep(500);
}
private static void prepare() {
sleep(500);
}
private static void sleep(long milliseconds) {
try {
TimeUnit.MILLISECONDS.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
数据包格式
通过抓包,可以看到Zipkin的数据包格式为:
[
[{
"traceId": "b15ea22da84801f3",
"parentId": "b15ea22da84801f3",
"id": "d4516b3c8d4777ef",
"name": "prepare",
"timestamp": 1603356689511178,
"duration": 504408,
"localEndpoint": {
"serviceName": "tracer-demo"
}
}, {
"traceId": "b15ea22da84801f3",
"parentId": "b15ea22da84801f3",
"id": "b18a3f2c02007c56",
"name": "commit",
"timestamp": 1603356690015732,
"duration": 504033,
"localEndpoint": {
"serviceName": "tracer-demo"
}
}, {
"traceId": "b15ea22da84801f3",
"id": "b15ea22da84801f3",
"name": "twophase",
"timestamp": 1603356689511055,
"duration": 1008958,
"localEndpoint": {
"serviceName": "tracer-demo"
}
}],
[{
"traceId": "cf045137964b3975",
"id": "cf045137964b3975",
"name": "encode",
"timestamp": 1603356688967842,
"duration": 502240,
"localEndpoint": {
"serviceName": "tracer-demo"
}
}]
]
查询页面
打开 http://127.0.0.1:9411/zipkin/
,点 RUN QUERY,可见: