Introduction:
Twitter's zipkin is a distributed tracking system dedicated to collecting time data for all Twitter distributed services. It provides two services: data collection and data query. The theoretical model of the system comes from the paper of Google Dapper. By collecting tracking data, developers can gain insight into how to execute a particular request in a distributed system.
zipkin-server
Adding dependencies to pom.xml
<!--zipkin rely on --> <!--This dependency is automatically introduced spring-cloud-sleuth-stream And introduce zipkin Dependency packages of --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> <scope>runtime</scope> </dependency> <!--To save to the database, you need the following dependencies --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
application.properties configuration
server.port=9411 spring.application.name=zipkin-server spring.sleuth.enabled=false #rabbitmq configuration spring.rabbitmq.host=172.20.4.132 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=111111 zipkin.storage.type=mysql #spring.datasource.schema[0]=classpath:/zipkin.sql spring.datasource.url=jdbc:mysql://172.20.4.135:3306/zipkin?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false spring.datasource.username=root spring.datasource.password=111111 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.initialize=true spring.datasource.continue-on-error=true
application Start Entry
@SpringBootApplication @EnableZipkinStreamServer public class SleuthServerApplication { public static void main(String[] args) { SpringApplication.run(SleuthServerApplication.class,args); } }
rabbitMQ
I downloaded the docker image directly from Aliyun.
docker pull registry.cn-hangzhou.aliyuncs.com/zp-k8s/rabbitmq:3-management
docker run -d --net host --name rabbitmq registry.cn-hangzhou.aliyuncs.com/zp-k8s/rabbitmq:3-management
Docker exec-it container id/bin/bash
Find rabbit installation directory through find command
Find rabbitmqctl execution
./rabbitmqctl add_user admin 111111
./rabbitmqctl set_user_tags admin administrator
After configuring user passwords and permissions, log in to webUI
So far, all the configurations of the zipkin-server end have been completed.
Service demo
service1
pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency>
application.properties
spring.application.name=orderService server.port=9981 #spring.zipkin.baseUrl=http://localhost:9411 spring.zipkin.enabled=true spring.sleuth.sampler.percentage=1 #rabbitmq configuration spring.rabbitmq.host=172.20.4.132 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=111111
java sample code, in fact, is a common service call
@SpringBootApplication public class SleuthClientApplication1 { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(SleuthClientApplication1.class, args); } } @RestController class OrderController { private static final Log log = LogFactory.getLog(OrderController.class); @Autowired private RestTemplate restTemplate; private String url="http://localhost:9982"; @RequestMapping("/order-info/{id}") public String service1(@PathVariable("id") String id,ModelMap model) throws Exception { log.info("fetch order info "); model.addAttribute("order", id+"Order information..."); Thread.sleep(200L); String coupon = this.restTemplate.getForObject(url + "/coupon/"+id, String.class); model.addAttribute("coupon", coupon); String point = this.restTemplate.getForObject(url + "/point/"+id, String.class); model.addAttribute("point", point); return model.toString(); } @RequestMapping("/order-info-cycle/{id}") public String cycle(@PathVariable("id") String id,ModelMap model) throws Exception { log.info("fetch order info "); model.addAttribute("order", id+"Order information..."); Thread.sleep(200L); String coupon = this.restTemplate.getForObject(url + "/coupon/"+id, String.class); model.addAttribute("coupon", coupon); String point = this.restTemplate.getForObject(url + "/point/"+id, String.class); model.addAttribute("point", point); String cycle = this.restTemplate.getForObject(url + "/do2/"+id, String.class); model.addAttribute("cycle", cycle); return model.toString(); } } @RestController class CycleController { private static final Log log = LogFactory.getLog(CycleController.class); @RequestMapping("/do1/{id}") public String hi(@PathVariable("id") String id) throws Exception { log.info("do1"+id); Thread.sleep(50L); return "the "+id+" cycle in order do1"; } }
server2
The pom.xml is the same
application.properties
spring.application.name=couponService server.port=9982 #spring.zipkin.baseUrl=http://localhost:9411 spring.zipkin.enabled=true spring.sleuth.sampler.percentage=1 spring.rabbitmq.host=172.20.4.132 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=111111
java code
package com.yonyou.sleuth; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @SpringBootApplication public class SleuthClientApplication2 { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(SleuthClientApplication2.class, args); } } @RestController class CouponController { private static final Log log = LogFactory.getLog(CouponController.class); @RequestMapping("/coupon/{id}") public String hi(@PathVariable("id") String id) throws Exception { log.info("coupon"+id); Thread.sleep(100L); return "the "+id+" coupon is 100"; } } @RestController class PointController { private static final Log log = LogFactory.getLog(PointController.class); @RequestMapping("/point/{id}") public String hi(@PathVariable("id") String id) throws Exception { log.info("point"+id); Thread.sleep(100L); return "the "+id+" point is 10000"; } } @RestController class CycleController { private static final Log log = LogFactory.getLog(CycleController.class); @Autowired private RestTemplate restTemplate; private String url="http://localhost:9981"; @RequestMapping("/do2/{id}") public String hi(@PathVariable("id") String id) throws Exception { log.info("do2"+id); Thread.sleep(200L); String cycle = this.restTemplate.getForObject(url + "/do1/"+id, String.class); return "the "+id+" do2 in oter service - "+cycle; } }
So far, start zipkin-server, service 1, service 2
Visit http://localhost:9981/order-info-cycle/1
Return: {order=1 order information.... coupon=the 1 coupon is 100, point=the 1 point is 10000, cycle=the 1 do2 in oter service - the 1 cycle in order do1}
Or http://localhost:9981/order-info/1
Return: {order=1 order information.... coupon=the 1 coupon is 100, point=the 1 point is 10000}
Visit zipkin-server webui: http://172.20.4.132:9411/
The end!