微服务(七)链路追踪sleuth、zipkin和健康检查springcloud admin和统一配置springcloud config
一、链路追踪
1、链路追踪的必要性
如果能跟踪每个请求,中间请求经过哪些微服务,请求耗时,网络延迟,业务逻辑耗时等。我们就能更好地分析系统瓶颈、解决系统问题。因此链路跟踪很重要。
我们自己思考解决方案:在调用前后加时间戳。捕获异常。
链路追踪目的:解决错综复杂的服务调用中链路的查看。排查慢服务。
市面上链路追踪产品,大部分基于google的Dapper论文。
有两个框架,一个sleuth,一个zippin,zippin是基于sleuth的。
2、链路追踪要考虑的几个问题
- 探针的性能消耗。尽量不影响 服务本尊。
- 易用。开发可以很快接入,别浪费太多精力。
- 数据分析。要实时分析。维度足够。
3、Sleuth简介
Sleuth是Spring cloud的分布式跟踪解决方案。
-
span(跨度),基本工作单元。一次链路调用,创建一个span,
span用一个64位id唯一标识。包括:id,描述,时间戳事件,spanId,span父id。
span被启动和停止时,记录了时间信息,初始化span叫:root span,它的span id和trace id相等。
-
trace(跟踪),一组共享“root span”的span组成的树状结构 称为 trace,trace也有一个64位ID,trace中所有span共享一个trace id。类似于一颗 span 树。
-
annotation(标签),annotation用来记录事件的存在,其中,核心annotation用来定义请求的开始和结束。
- CS(Client Send客户端发起请求)。客户端发起请求描述了span开始。
- SR(Server Received服务端接到请求)。服务端获得请求并准备处理它。SR-CS=网络延迟。
- SS(Server Send服务器端处理完成,并将结果发送给客户端)。表示服务器完成请求处理,响应客户端时。SS-SR=服务器处理请求的时间。
- CR(Client Received 客户端接受服务端信息)。span结束的标识。客户端接收到服务器的响应。CR-CS=客户端发出请求到服务器响应的总时间。
其实数据结构是一颗树,从root span 开始。
4、使用sleuth与zipkin
需要引入sleuth的依赖。在consumer与provider中添加。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
注意:这个需要配到每一个需要监控的服务上的。
运行下可以从控制命令台上看到:
但是这样看太累了。
用zippin。
一样先加依赖:
<!-- zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
还需要加properties中:
spring.zipkin.base-url=http://localhost:9411
#采样深度
spring.sleuth.sampler.rate=1
但是只是这样会报错。
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:9411/api/v2/spans": connect timed out; nested exception is java.net.SocketTimeoutException: connect timed out
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:746) ~[spring-web-5.2.12.RELEASE.jar:5.2.12.RELEASE]
这里需要在zippin官网下一个jar包,然后启动。
访问:lockhost:9411/zipkin/
再启动一个provier和一个consumer。调用一下。
二、springcloud admin
这个组件是分服务端与客户端,相互配合使用。
新建一个项目admintest,不用勾选组件,配置pom文件。
<!-- Admin 服务 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.2.1</version>
</dependency>
<!-- Admin 界面 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>2.2.1</version>
在主配置类上加一个注解。
@EnableAdminServer
直接启动看下是否成功。
所有微服务作为admin的客户端,都要加依赖:
<!-- Admin 服务 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
需要在client端的properties加:
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
spring.boot.admin.client.url=http://localhost:8080
将配置好的consumer上线。
有个有趣的邮件通知功能(服务下线通知你)。
添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在properties中加入:
spring.mail.host=smtp.qq.com
// 这里的username填写的是你发接人的qq
spring.mail.username=1111110000
// 用qq邮箱查找smtp的qq密码,会给你一个token
spring.mail.password=xxxxxxxx
spring.mail.properties.mail.smpt.auth=true
spring.mail.properties.mail.smpt.starttls.enable=true
spring.mail.properties.mail.smpt.starttls.required=true
#收件邮箱
spring.boot.admin.notify.mail.to=7575574@qq.com
# 发件邮箱
spring.boot.admin.notify.mail.from=1111110000@qq.com
三、配置中心Springcloud config + github
主要是这样的结构。
去拉取远端的服务配置。除了一样的配置,还有个性化配置,个性化配置放在本地。以服务名去区分配置文件。一般将配置放到github。通过单服务的重写加载(让服务器通知同一个服务下的另外服务器)。可以把所有微服务一次性完成所有微服务配置重载。
创建一个项目congifcenter
在主配置上加
@EnableConfigServer
然后访问下
Client
需要加上configclient依赖
#直接URL方式查找配置中心
spring.cloud.config.uri=http://localhost:9999/
#通过注册中心查找
#spring.cloud.config.discovery.enabled=true
#spring.cloud.config.discovery.service-id=a-config
//哪个配置
spring.cloud.config.profile=dev
#分支
spring.cloud.config.label=test
并修改 application.properties为bootstrap.properties
因为远程写了myconfig=“test xxxxoo“
本地没有,那么可以用,
@Value("${config.info}")
String info;
拉取过来。
注意上传的配置名字需要统一,前面为服务名,后面为分支名。
拉的test分支。
Properties也可以这样
#通过注册中心查找
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-center
//哪个配置
spring.cloud.config.profile=dev
#分支
spring.cloud.config.label=test
配置刷新
手动配置热更新
- 开启actuator中的refresh端点(加actuator依赖)
- Controller中添加
@RefreshScope
注解(加注解) - 向客户端 url
http://localhost:91/actuator/refresh
发送Post请求
这里的第三步需要用postman发送post请求。所有对服务更改的都不能用get请求。
如果想多个consumer一起改,可以用Bus。将所有服务接入bus,是他们的总线,也就是所有服务的一个闸。这里需要配置一下rabbitmq。
配置好了需要调用的API不是refresh而是bus-reflush。
方式1:单个服务器的话,重启就行。
方式2:单个服务器的话,服务器端口为91,http://localhost:91/actuator/refresh`发送Post请求。(更新了配置)
方式3:单个服务集群的话,需要bus,bus底层是rabbitmq。需要把下面配置文件放到client项目里。
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
还需要加依赖。
org.springframework.cloud
spring-cloud-starter-bus-amqp
这个时候,需要用postman发送bus-reflush的api,而不是reflush。这个时候,91与92都会变成。
方式4:整体服务器更新配置。把所有配置信息放到config项目中,访问端口9999的actuator/bus-reflush.