分布式跟踪系统Zipkin详解(4)

方法分别为

@RequestMapping("bar") public String bar() throws InterruptedException, IOException { //service3 method Random random = new Random(); int sleep= random.nextInt(100); TimeUnit.MILLISECONDS.sleep(sleep); return " [service3 sleep " + sleep+" ms]"; } @RequestMapping("tar") public String tar() throws InterruptedException, IOException { //service4 method Random random = new Random(); int sleep= random.nextInt(1000); TimeUnit.MILLISECONDS.sleep(sleep); return " [service4 sleep " + sleep+" ms]"; }

将工程修改后编译成jar形式

执行

nohup java -jar server4.jar & nohup java -jar server3.jar & nohup java -jar server2.jar & nohup java -jar server1.jar &

访问:8080/start后查看zipkin的web UI

chain

点击条目可以查看具体的延迟信息

times

服务之间的依赖为

dependency

brave 源码

以上完成了基本的操作,下面将从源码角度来看下brave的实现

首先从SpanCollector来入手

@Bean public SpanCollector spanCollector() { HttpSpanCollector.Config config = HttpSpanCollector.Config.builder().connectTimeout(properties.getConnectTimeout()).readTimeout(properties.getReadTimeout()) .compressionEnabled(properties.isCompressionEnabled()).flushInterval(properties.getFlushInterval()).build(); return HttpSpanCollector.create(properties.getUrl(), config, new EmptySpanCollectorMetricsHandler()); }

从名称上看HttpSpanCollector是基于http的span收集器,因此超时配置是必须的,默认给出的超时时间较长,flushInterval表示span的传递
间隔,实际为定时任务执行的间隔时间.在HttpSpanCollector中覆写了父类方法sendSpans

@Override protected void sendSpans(byte[] json) throws IOException { // intentionally not closing the connection, so as to use keep-alives HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setConnectTimeout(config.connectTimeout()); connection.setReadTimeout(config.readTimeout()); connection.setRequestMethod("POST"); connection.addRequestProperty("Content-Type", "application/json"); if (config.compressionEnabled()) { connection.addRequestProperty("Content-Encoding", "gzip"); ByteArrayOutputStream gzipped = new ByteArrayOutputStream(); try (GZIPOutputStream compressor = new GZIPOutputStream(gzipped)) { compressor.write(json); } json = gzipped.toByteArray(); } connection.setDoOutput(true); connection.setFixedLengthStreamingMode(json.length); connection.getOutputStream().write(json); try (InputStream in = connection.getInputStream()) { while (in.read() != -1) ; // skip } catch (IOException e) { try (InputStream err = connection.getErrorStream()) { if (err != null) { // possible, if the connection was dropped while (err.read() != -1) ; // skip } } throw e; } } }

可以看出最终span信息是通过HttpURLConnection实现的,同样道理就可以推理brave对brave-spring-resttemplate-interceptors模块的实现,
只是换了一种http封装。

Brave

@Bean public Brave brave(SpanCollector spanCollector){ Brave.Builder builder = new Brave.Builder(properties.getServiceName()); //指定state builder.spanCollector(spanCollector); builder.traceSampler(Sampler.ALWAYS_SAMPLE); Brave brave = builder.build(); return brave; }

Brave类包装了各种工具类

public Brave build() { return new Brave(this); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f78ef258305c19bcf8576bcaef6b84ab.html