The Simplest Spring Cloud Tutorial in History | Part 9: Service Link Tracking (Spring Cloud Sleuth)(Finchley Version)

This article focuses on the service tracking component zipkin, which is integrated with Spring Cloud Sleuth.

1. Introduction

Add sleuth to the classpath of a Spring Boot application (see below for Maven and Gradle examples), and you will see the correlation data being collected in logs, as long as you are logging requests. ------ Taken from the official website

The main function of Spring Cloud Sleuth is to provide tracking solutions in distributed systems, and it is compatible with zipkin. You only need to introduce the corresponding dependencies in the pom file.

2. Service tracking analysis

In the microservice architecture, services are divided by business. An interface exposed to the outside through REST call may require the coordination of many services to complete the interface function. If any service on the link has a problem or a network timeout, an interface will be formed that will lead to the formation of the interface. The call failed. With the continuous expansion of the business, the calls between services will become more and more complex.

As there are more and more services, the analysis of the call chain will become more and more complex. The calling relationship between them may be as follows:

3. Terminology

  • Span: The basic unit of work. For example, sending an RPC in a newly created span is equivalent to sending a response request to the RPC. The span is uniquely identified by a 64-bit ID, the trace is represented by another 64-bit ID, and the span has other data information , such as summaries, timestamp events, key-value annotations (tags), span IDs, and progress IDs (usually IP addresses) The span is constantly starting and stopping, while recording time information, when you create a span, you must stop it at some point in the future.
  • Trace: A tree-like structure composed of a series of spans, for example, if you are running a distributed big data project, you may need to create a trace.
  • Annotation: used to record the existence of an event in time, some core annotations are used to define the start and end of a request
    • cs - Client Sent - The client initiates a request, this annotation describes the start of the span
    • sr - Server Received - the server gets the request and is ready to start processing it, if you subtract the cs timestamp from its sr you get the network latency
    • ss - Server Sent - The annotation indicates the completion of the request processing (when the request is returned to the client), if the ss is subtracted from the sr timestamp, the processing time required by the server can be obtained
    • cr - Client Received - Indicates the end of the span, the client successfully received the reply from the server, if the cs timestamp is subtracted from the cr, all the time required for the client to get the reply from the server can be obtained Graphicalize the process of using Zipkin annotations for Span and Trace in one system:

Graphicalize the process of using Zipkin annotations for Span and Trace in one system:

Fourth, the construction project

After the basic knowledge is explained, let's go to the actual combat. The case in this article is mainly composed of three projects: a server-zipkin, whose main function uses the functions of ZipkinServer, collects and calls data, and displays it; a service-hi, which exposes the hi interface to the outside world; A service-miya exposes the miya interface to the outside world; these two services can call each other; and only after calling, server-zipkin will collect data, which is why it is called service tracking.

4.1 Build server-zipkin

When spring Cloud is the F version, there is no need to build the Zipkin Server by yourself, you only need to download the jar, the download address:

https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/

It can also be downloaded here:

Link: https://pan.baidu.com/s/1w614Z8gJXHtqLUB6dKWOpQ Password: 26pf

After downloading the jar package, you need to run the jar as follows:

java -jar zipkin-server-2.10.1-exec.jar

Visit the browser localhost:9494

4.2 Create service-hi

Introduce the starter dependency spring-cloud-starter-zipkin in its pom, the code is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.forezp</groupId>
	<artifactId>service-zipkin</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>service-hi</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>com.forezp</groupId>
		<artifactId>sc-f-chapter9</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>



	<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>



	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
copy

Specify the address of the zipkin server in its configuration file application.yml, and the header is specified by configuring "spring.zipkin.base-url":

server.port=8988
spring.zipkin.base-url=http://localhost:9411
spring.application.name=service-hi
copy

By introducing the spring-cloud-starter-zipkin dependency and setting spring.zipkin.base-url, it is enough.

Externally exposed interface:

package com.forezp;

import brave.sampler.Sampler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.logging.Level;
import java.util.logging.Logger;

@SpringBootApplication
@RestController
public class ServiceHiApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceHiApplication.class, args);
	}

	private static final Logger LOG = Logger.getLogger(ServiceHiApplication.class.getName());


	@Autowired
	private RestTemplate restTemplate;

	@Bean
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}

	@RequestMapping("/hi")
	public String callHome(){
		LOG.log(Level.INFO, "calling trace service-hi  ");
		return restTemplate.getForObject("http://localhost:8989/miya", String.class);
	}
	@RequestMapping("/info")
	public String info(){
		LOG.log(Level.INFO, "calling trace service-hi ");

		return "i'm service-hi";

	}

	@Bean
	public Sampler defaultSampler() {
		return Sampler.ALWAYS_SAMPLE;
	}


}
copy

4.3 Create service-miya

The creation process hurts service-hi, introduces the same dependencies, and configures spring.zipkin.base-url.

Externally exposed interface:

package com.forezp;

import brave.sampler.Sampler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.logging.Level;
import java.util.logging.Logger;

@SpringBootApplication
@RestController
public class ServiceMiyaApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceMiyaApplication.class, args);
	}

	private static final Logger LOG = Logger.getLogger(ServiceMiyaApplication.class.getName());


	@RequestMapping("/hi")
	public String home(){
		LOG.log(Level.INFO, "hi is being called");
		return "hi i'm miya!";
	}

	@RequestMapping("/miya")
	public String info(){
		LOG.log(Level.INFO, "info is being called");
		return restTemplate.getForObject("http://localhost:8988/info",String.class);
	}

	@Autowired
	private RestTemplate restTemplate;

	@Bean
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}


	@Bean
	public Sampler defaultSampler() {
		return Sampler.ALWAYS_SAMPLE;
	}
}
copy

4.4 Start the project and demonstrate the tracking

Start the above projects in turn, open the browser to visit: http://localhost:9411/, the following interface will appear:

Visit: http://localhost:8989/miya, the browser appears:

i'm service-hi

Then open the interface of http://localhost:9411/, click Dependencies, you can find the dependencies of the service:

Click find traces, you can see the data of specific services calling each other:

Download the source code of this article:

https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-chapter9

Posted by vaibhavs on Sun, 08 May 2022 06:02:05 +0300