十八.SpringCloud极简入门-Zipkin整合RabbitMQ使用ElasticSearch存储的高性能链路追踪方案
Posted 墨家巨子@俏如来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十八.SpringCloud极简入门-Zipkin整合RabbitMQ使用ElasticSearch存储的高性能链路追踪方案相关的知识,希望对你有一定的参考价值。
前言
之前讲过一个版本的Zipkin链路追踪,《Sleuth整合ZipKin链路追踪》,讲了Zipkin的工作流程,以及简单集成Zipkin,这篇文章将会对之前的方案进行升级,使用RabbitMQ异步收集数据,使用ElasticSearch进行数据存储。另外本文会使用Docker来搭建相关组件。 注意:请一定先看上一篇 Sleuth整合ZipKin链路追踪。学习该文章需要有一定的知识储备:Docker,ElasticSearch,RabbitMQ,SpringCloud等。
方案设计
Zipkin可以分为ZipKinServer端和Zipkin client 端,client端也就是咱们参与链路追踪的微服务。微服务需要整合Zipkin实时向Zipkin服务端发送链路数据,支持的方式有WEB(http),Rabbit,Kafka三种。ZipKinServer通过collector收集器收集链路数据,然后通过store把数据存储到内存或数据库或ElasticSearch。最后Zipkin通过UI把链路数据展示出来,大致原理图如下:
今天我们采用的方式是:
- 客户端使用rabbitmq的方式进行数据的异步推送,这样的方式性能更好,容错性更高,即使zIpkinserver挂了客户端也可以正常工作
- ZipkinServer的存储方式采用ElasticSearch,因为这种链路数据是非常庞大的,内存和数据库都不太适合存储。
组件环境安装
Docker安装
在准备好的linux机器上安装好Docker
# yum源指定
[root@localhost ~]# sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker
[root@localhost ~]# sudo yum -y install docker-ce
#启动dokcer
[root@localhost ~]# sudo systemctl start docker
使用阿里云镜像加速
[root@localhost ~]# vi /etc/docker/daemon.json
#加入如下内容
"registry-mirrors": ["https://5pfmrxk8.mirror.aliyuncs.com"]
重启Docker
[root@localhost ~]# systemctl restart docker
ElasticSerach安装
ElasticSerach是用来存储链数据的全文搜索组件,专门应对大数据量的全文检索和存储。
#下载镜像
[root@localhost ~]# docker pull elasticsearch:6.8.6
# 启动容器
[root@localhost ~]# docker run --name elasticsearch -d -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:6.8.6
访问测试:我的linux机器的ip是:192.168.119.129:9200
Kibana安装
Kibana是针对ElasticSearch的查询和分析统计的可视化工具
# 下载镜像
[root@localhost ~]# docker pull kibana:6.8.6
# 启动容器,通过ELASTICSEARCH_HOSTS指定es的地址
[root@localhost ~]# docker run --name kibana -e "ELASTICSEARCH_HOSTS=http://192.168.119.129:9200" -p 5601:5601 -d kibana:6.8.6
访问测试:我的linux机器的ip是:192.168.119.129:5601
安装RabbitMQ
RabbitMQ是一个高性能的消息队列,微服务把链路数据发送到MQ,zipkinserver从MQ中收集数据往ElasticSearch总存储
#下载镜像
[root@localhost ~]# docker pull rabbitmq:latest
#启动容器
[root@localhost ~]# docker run -d -v /opt/rabbitmq/data:/var/lib/rabbitmq -p 5672:5672 -p 15672:15672 --name rabbitmq --restart=always --hostname myRabbit rabbitmq
#安装可视化插件
[root@localhost ~]# docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_management
访问测试:我的linux机器的ip是:192.168.119.129:15672 , 登录账号是:guest/guest
安装ZipkinServer
ZipkinServer负责收集微服务发送过来的链路数据
#下载镜像
[root@localhost ~]# docker pull openzipkin/zipkin:2.14.1
#启动容器,指定存储方式为elasticsearch,并指定ElasticSearch主机,以及RabbitMQ的地址
[root@localhost ~]# docker run -d ---env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.119.129:9200 --env RABBIT_ADDRESSES=192.168.119.129:5672 -p 9411:9411 openzipkin/zipkin:2.14.1
这里指定存储方式为elasticsearch,并指定ElasticSearch主机,以及RabbitMQ的地址,它需要从RabbitMQ中拿到链路数据存储到ElasticSearch中。访问测试:我的linux机器的ip是:192.168.119.129:9411 ,
安装Zipkin-dependencies
当zipkin使用elasticsearch进行数据存储后,会丢失依赖关系,需要额外安装Zipkin-dependencies
#下载镜像
[root@localhost ~]# docker pull openzipkin/zipkin-dependencies:2.6.2
# 启动容器 ,存储方式为STORAGE_TYPE=elasticsearch ,并指定ES的主机
[root@localhost ~]# docker run --name zipkin-dependencies --env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.119.129:9200 --env ES_INDEX=zipkin --rm=true -e JAVA_OPTS="-Xmx1024m -Xms1024m" openzipkin/zipkin-dependencies:2.6.2
出现这样的效果就可以了
到这里所有的组件准备完毕,使用 docker ps 查看容器
微服务准备
这里我基于Eureka做服务发现,搭建了Producer和Consumer两个微服务,服务之间使用OpfenFeign进行通信。项目结构如
springcloud-elk
|--- eureka-server #注册中心
|--- service-consumer #消费者
|--- service-producer #提供者
搭建父工程
<!--SpringBoot-->
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Eureka搭建
第一步导入POM
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
第二步:编写启动内
@SpringBootApplication
@EnableEurekaServer
public class EurekaStarter
public static void main(String[] args)
SpringApplication.run(EurekaStarter.class ,args);
第三步:yml配置
server:
port: 1000
eureka:
instance:
hostname: localhost #主机
client: #客户端配置
registerWithEureka: false #EurekaServer自己不要注册到EurekaServer自己 ,只有EurekaClient才注册
fetchRegistry: false #EurekaServer不要拉取服务的通信地址列表 ,只有EurekaClient才拉取地址列表
serviceUrl: #注册中心的注册地址
defaultZone: http://localhost:1000/eureka/ #http://$eureka.instance.hostname:$server.port/eureka/
server:
enable-self-preservation: false #关闭自我保护警告
服务提供者
第一步导入POM , 需要导入:spring-cloud-starter-zipkin整合zipkin ; 导入spring-rabbit整合RabbitMQ
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
第二步:启动类
@SpringBootApplication
public class ProducerStarter
public static void main(String[] args)
SpringApplication.run(ProducerStarter.class , args);
第三步:yml配置
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1000/eureka/ #注册地址
instance:
prefer-ip-address: true #使用ip地址进行注册
instance-id: service-producer:3000 #实例ID
spring:
application:
name: service-producer
rabbitmq: #rabbitMQ配置
host: 192.168.119.129 #使用的是docker安装的RabbitMQ
port: 5672
username: guest
password: guest
zipkin:
base-url: http://192.168.119.129:9411 #Zipkin服务端地址 ,可以使用ip地址也可以使用服务发现方式。
discovery-client-enabled: false #如果使用服务发现的方式查找zipkin则打开为true
sender:
type: rabbit #使用MQ的方式发送链路数据,还可以是web,kafka
sleuth:
sampler:
probability: 1.0 #链路数据收集率,越大收集的越全
server:
port: 3000
第四步:编写一个controller,提供给消费者调用
@RestController
public class ProducerController
@RequestMapping("/hi")
public String hi()
return "hello";
服务消费者
第一步导入依赖:比提供者多一个OpenFeign的依赖,因为要做服务调用
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
<!--sleuth-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
第二步:启动类 , 这里开启Feign
@SpringBootApplication
@EnableFeignClients
public class ConsumerStarter
public static void main(String[] args)
SpringApplication.run(ConsumerStarter.class ,args);
第三步:编写feign客户端接口 , 该接口是用来调用提供者服务的
@FeignClient("service-producer")
public interface HIFeignClient
@RequestMapping("/hi")
String hi();
第四步:编写controller,使用feign访问提供者
@RestController
public class ConsumerController
@Autowired
private HIFeignClient feignClient;
@RequestMapping("/hi")
public String hi()
return feignClient.hi();
第五步:yml配置
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1000/eureka/
instance:
prefer-ip-address: true #使用ip地址进行注册
instance-id: service-consumer:4000 #实例ID
spring:
application:
name: service-consumer
rabbitmq:
host: 192.168.119.129
port: 5672
username: guest
password: guest
zipkin:
base-url: http://192.168.119.129:9411 #Zipkin服务端地址 ,可以使用ip地址也可以使用服务发现方式。
discovery-client-enabled: false #如果使用服务发现的方式查找zipkin则打开为true
sender:
type: rabbit #使用MQ的方式发送链路数据,还可以是web,kafka
sleuth:
sampler:
probability: 1.0
server:
port: 4000
到了,到这里所有的 微服务也准备完毕。
测试
依次启动:Eureka ,提供者服务(3000),消费者服务(4000) , 使用浏览器访问 http://localhost:4000/hi ,可以多访问几次,数据会收集多一点,
控制台效果
然后微服务会把链路调用数据发送到RabbitMQ中,而ZipkinServer会从RabbitMQ中数据并存储到ElasticSearch中。下面是ES中的效果:http://192.168.119.129:5601
在Discover中看到收集的数据
然后Zipkin会通过UI展示链路信息 http://192.168.119.129:9411/zipkin
查看依赖
文章结束希望对你有所帮助,喜欢的话请给个好评
以上是关于十八.SpringCloud极简入门-Zipkin整合RabbitMQ使用ElasticSearch存储的高性能链路追踪方案的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud - Spring Cloud 之 Sleuth分布式链路跟踪;Zipkin埋点数据;Elastic Search 数据持久化(十八)
springcloud 项目一步一步搭建 SpringCloud Sleuth zipkin 链路追踪
微服务实践之全链路追踪(sleuth,zipkin)详解-SpringCloud(2021.0.x)-4