An overview of the

In this paper, we used Zipkin to build a tracking center of microservice call chain, and simulated the experimental scene of microservice call. Using Zipkin’s library Brave, we can collect information about which components a client request goes through from sending to being responded to, which microservices, the total duration of the request, and how long each component takes.

This article shows you how to track calls to the Mysql database using Zipkin, again with the Help of the OpenZipkin library Brave.

Note: This article was published on My public account CodeSheep. You can subscribe by holding down or scanning the heart below ↓ ↓ ↓


Extend the ZipkinTool component

ZipkinTool is a tool component that communicates with Zipkin in the article “Building microservice Call Chain Tracking Center”, and uses it to track the microservice call chain. Now we want to track the Mysql database call chain, we can extend its function.

  • Add dependency to POM.xml:
< the dependency > < groupId > IO. Zipkin. Brave < / groupId > < artifactId > brave - mysql < / artifactId > < version > 4.0.6 < / version > </dependency>Copy the code
  • Add MySQLStatementInterceptorManagementBean ZipkinConfiguration in class
    @Bean
    public MySQLStatementInterceptorManagementBean mySQLStatementInterceptorManagementBean() {
        return new MySQLStatementInterceptorManagementBean(brave().clientTracer());
    }
Copy the code

Add microservices for Mysql database access

Following the previous article: Building a Trace Center for Microservice Call Chain, we will transform the ServiceC microservice in the following to add interaction with Mysql database.

  • Add JDBC and Mysql dependencies to POM.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>  <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>Copy the code
  • Add Mysql connection configuration to application.properties
Spring.datasource. Driver-class-name = com.mysql.jdbc.driver spring.datasource. Url = JDBC :mysql:// Your mysql service is located at IP:3307/test? useSSL=false\
  &statementInterceptors=com.github.kristofa.brave.mysql.MySQLStatementInterceptor\
  &zipkinServiceName=mysqlService
spring.datasource.username=root
spring.datasource.password=XXXXXX
Copy the code
  • Add JdbcTemplate to the Controller to access the database
    @GetMapping("/ mysqltest") public String mysqltest () {String name = jdbcTemplate. QueryForObject ("SELECT name FROM user WHERE id = 1", String.class ); return "Welcome " + name; }Copy the code

Start the Mysql database service

1. Start the Mysql container

docker run -d -p 3307:3306 \
-v ~/mysql/data:/var/lib/mysql \
-v ~/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=XXXXXX \
--name mysql mysql
Copy the code

2. Start another Mysql container and add it to perform some Settings

  • Start with the mysql command line
docker run -it --rm \
--link mysql:mysql mysql \
mysql -hmysql -u root -p
Copy the code

  • Next, create the database Zipkin: to hold the data that zipkin collects
CREATE DATABASE `zipkin`

CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit ', 'trace_id' BIGINT NOT NULL, `id` BIGINT NOT NULL, `name` VARCHAR(255) NOT NULL, `parent_id` BIGINT, `debug` BIT(1), `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and toImplement TTL, '`duration` BIGINT COMMENT 'Span.duration(): Micros used for minDuration and maxDuration query ') ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate";ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`.`trace_id`.`id`) COMMENT 'for joining with zipkin_annotations’;
ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forGetTracesByIds';ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames’;
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range";CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit ', 'trace_id' BIGINT NOT NULL COMMENT 'coincides withZipkin_spans trace_id ',`span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id’,
  `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type= =- 1',`a_value` BLOB COMMENT 'BinaryAnnotation. Value (), which must be smaller than 64KB ', 'a_type' INT NOT NULL COMMENT 'BinaryAnnotation.type() or - 1 ifThe Annotation, '`a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotations. Timestamp or zipkin_SPANS. Timestamp ', 'endpoint_ipv4' INT COMMENT 'Null when Binary/Annotation.endpoint is null',`endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation. The endpoint is Null, or no IPv6 address,' ` endpoint_port ` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',`endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation. The endpoint is Null ") ENGINE = InnoDB ROW_FORMAT = COMPRESSED CHARACTER SET = utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate";ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`.`trace_id`.`span_id`) COMMENT 'for joining with zipkin_spans’;
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'forGetTraces/ByIds';ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames’;
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'forGetTraces';ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces’;
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'forDependencies job ";CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL.`parent` VARCHAR(255) NOT NULL.`child` VARCHAR(255) NOT NULL.`call_count` BIGINT.`error_count` BIGINT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`.`parent`.`child`);
Copy the code

Three data tables are created here.

The Sql file can be obtained from the following link: https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql/src/main/resources/mysql.sql

After executing the Sql script, you can see that the three zipkin-related tables have been built:

  • Create database test: used as the test database
CREATE DATABASE `test`
CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `name` varchar(100) DEFAULT NULL ,
  PRIMARY KEY (`id`))ENGINE=InnoDB DEFAULT CHARSET = utf8;

insert into user values (1, "hansonwang99")Copy the code

I inserted a piece of data here for the experiment.


Start the Zipkin service

docker run -d -p 9411:9411 \
--link mysql:mysql \
-e STORAGE_TYPE=mysql \
-e MYSQL_HOST=mysql \
-e MYSQL_TCP_PORT=3306 \
-e MYSQL_DB=zipkin \
-e MYSQL_USER=root \
-e MYSQL_PASS=XXXXXX \
 --name zipkin openzipkin/zipkin
Copy the code

Start microservices for Mysql database access (that is, ServiceC)

Type localhost:8883/mysqltest in your browser. If you see the following output, you can confirm that the database call operation succeeded!


Zipkin tracks actual experiments with database calls

  • Browser input: * * * * http://localhost:9411/zipkin/

Open the Zipkin Web UI and click the service name drop-down list to see that the Mysql database has been successfully identified to invoke the service

  • After you select mysqlService, click Find Traces

You can see the call chain trace information for the first query to Mysql

Click on any one to view:

  • ** Localhost :8883/mysqltest

The purpose is to trigger the Mysql call again, and then again Find Traces. You can see the trace data similar to what you see in the image below:

Click on the first Query to view, which is actually trying to connect to the Mysql database

Click on the second Query and see that this is the actual query business

The graphical interface clearly shows the detailed steps and time consuming of each phase, so it can be used to analyze which SQL statements execute slowly.


Afterword.

The source code used in this experiment has been open source, please help yourself.

  • The author’s more original articles are here, welcome to watch

  • My Personal Blog

The author has more SpringBt practice articles here:

  • Spring Boot application monitoring actual combat
  • The SpringBoot application is deployed in an external Tomcat container
  • ElasticSearch in SpringBt practice
  • A preliminary study on Kotlin+SpringBoot joint programming
  • Spring Boot Logging framework practices
  • SpringBoot elegant coding: Lombok plus

If you are interested, take some time to read some of the author’s articles on containerization and microservitization:

  • Use K8S technology stack to create personal private cloud serial articles
  • Nginx server configuration from a detailed configuration list
  • Docker container visual monitoring center was built
  • Use ELK to build Docker containerized application log center
  • RPC framework practice: Apache Thrift
  • RPC framework practice: Google gRPC
  • Establishment of microservice call chain tracking center
  • Docker containers communicate across hosts
  • Preliminary study on Docker Swarm cluster
  • Several guidelines for writing dockerFiles efficiently