简介
随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知。在这样子的大背景下面,我们需要一套监控系统,能够实时,准确的监控调用链路中的每一个环节,并且通用图形化的界面来展示监控信息,通过这些信息,我们能够快捷的找出那个调用结点出现问题。spring cloud sleuth 就能够解决上述链路调用过程中的数据,zipkin将这些数据通过图形话的方式,来进行展示。
父工程
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<lombok.version>1.18.12</lombok.version>
<mysql.version>5.1.38</mysql.version>
<druid.version>1.1.23</druid.version>
<mybatis-spring-boot.version>2.1.3</mybatis-spring-boot.version>
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!--配置springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--这是mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--这是druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--这是mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>microservicecloud2022</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>@</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
</project>
注册中心
注册中心采用的是Eureka
- 工程结构如下
- pom
<?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">
<parent>
<artifactId>microservicecloud2022</artifactId>
<groupId>com.edu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-eureka-server7001</artifactId>
<description>服务注册中心</description>
<dependencies>
<!--注册中心的坐标-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
- yaml
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #当前服务的实例名
client:
fetch-registry: false # 是否从注册中心取服务
register-with-eureka: false #是否向注册中心注册服务
serviceUrl:
#defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
defaultZone: http://eureka7001.com:7001/eureka/
- 主启动类
package com.edu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaMainApp_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMainApp_7001.class,args) ;
}
}
服务提供者
这里使用的是支付微服务
- 工程的目录结果如下
- pom
<?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">
<parent>
<artifactId>microservicecloud2022</artifactId>
<groupId>com.edu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-payment8001</artifactId>
<description>支付模块</description>
<dependencies>
<!--依赖通用的模块-->
<dependency>
<groupId>com.edu</groupId>
<artifactId>cloud-common-api</artifactId>
<version>${project.version}</version>
</dependency>
<!--这是mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--这是druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--这是mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--springboot的web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot的监控模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--springboot的测试模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--注册中心的客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--sleuth + zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
- yaml
server:
port: 8001
spring:
application:
name: provider-payment
datasource: #数据源的配置信息
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/springcloud2021
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
#druid的其它的一些配置信息GMT%2B8
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
zipkin:
base-url: http://localhost:9411/ #监控消息发送的地址
sleuth:
sampler:
probability: 1 #采样值介于0和1之间 1代表完全采样
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
config-location: classpath:mybatis/mybatis-config.xml
eureka:
client:
service-url: #注册中心的地址
#defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: provider-payment8001
prefer-ip-address: true
info:
app.name: microservicecloud2022
company.name: www.edu.com
build.artifactId: "@project.artifactId@"
build.version: "@project.version@"
- 控制器中发布一个服务
package com.edu.springcloud.controller;
import com.edu.springcloud.entity.CommonResult;
import com.edu.springcloud.entity.Payment;
import com.edu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Slf4j
public class PaymentController {
@GetMapping("/payment/zipkin")
public String paymentZipkin() {
return "hi,I'am paymentzipkin server fallback~~~~~" ;
}
}
服务的消费者
使用的是订单微服务
- 工程目录结构
- pom
<?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">
<parent>
<artifactId>microservicecloud2022</artifactId>
<groupId>com.edu</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-order80</artifactId>
<description>订单模块</description>
<dependencies>
<!--依赖通用的模块-->
<dependency>
<groupId>com.edu</groupId>
<artifactId>cloud-common-api</artifactId>
<version>${project.version}</version>
</dependency>
<!--springboot的web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot的监控模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--springboot的测试模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--注册中心的客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--sleuth + zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--添加热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
- yaml
server:
port: 80
spring:
application:
name: consumer-order
zipkin:
base-url: http://localhost:9411/ #监控消息发送的地址
sleuth:
sampler:
probability: 1 #采样值介于0和1之间 1代表完全采样
eureka:
client:
service-url: #注册中心的地址
#defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: consumer-order80
prefer-ip-address: true
info:
app.name: microservicecloud2022
company.name: www.edu.com
build.artifactId: "@project.artifactId@"
build.version: "@project.version@"
- 控制器
package com.edu.springcloud.controller;
import com.edu.springcloud.entity.CommonResult;
import com.edu.springcloud.entity.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class PaymentConsumerController {
// private static final String BASE_URL_PREFIX="http://localhost:8001" ;
private static final String BASE_URL_PREFIX="http://PROVIDER-PAYMENT" ;
@Autowired
private RestTemplate restTemplate ;
@GetMapping("/consumer/payment/zipkin")
public String paymentZipkin(){
return restTemplate.getForObject(BASE_URL_PREFIX +"/payment/zipkin",String.class);
}
}
- 编写主配置类
package com.edu.springcloud;
import com.edu.rule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(value = "PROVIDER-PAYMENT",configuration = MySelfRule.class)
public class ConsumerOrder80_APP {
public static void main(String[] args) {
SpringApplication.run(ConsumerOrder80_APP.class,args) ;
}
}
zipkin环境的搭建
下载地址:https://zipkin.io/pages/extensions_choices
测试过程
- 先启动Eureka注册中心
- 启动zipkin
- 启动服务提供者
- 启动服务消费者
- 访问zipkin的图形界面 http://localhost:9411/zipkin/