[Spring Cloud系列]Consul实验篇

[Spring Cloud系列]Consul实验篇_health-check-critical-timeout-CSDN博客
猿Why为什么会想着写这样一篇文章?请先阅览先序篇。
先序篇,对Consul服务的服务特性、Spring Cloud Consul模块服务注册与服务发现原理进行了了解。但是感觉还是不够,在与同事“抬扛”的时候,底气不足。所以,猿Why打算针对Consul的一些服务特性做几个验证性试验。

温故知新
spring.application.name=consul-agent
server.port=8080
#consul服务注册中心
spring.cloud.consul.host=localhost
#consul服务端口号
spring.cloud.consul.port=8500
#注册应用服务到consul服务
spring.cloud.consul.discovery.register=true
#提供给Consul服务的本应用服务的健康检查地址(支持自定义)
spring.cloud.consul.discovery.health-check-path=/actuator/health/consul
#Pull类型(HTTP)健康检查时间间隔
spring.cloud.consul.discovery.health-check-interval=1s
#应用服务注册ID
spring.cloud.consul.discovery.instance-id=${spring.application.name}
#注册使用IP地址
spring.cloud.consul.discovery.prefer-ip-address=true
#应用服务IP地址
spring.cloud.consul.discovery.ip-address=127.0.0.1
#TTL(心跳开关),当值为false时候,HTTP方式健康检查生效
spring.cloud.consul.discovery.heartbeat.enabled=true
#心跳频率(例如5s一次)
spring.cloud.consul.discovery.heartbeat.ttl-value=5
#健康检查显示详细信息
management.endpoint.health.show-details=ALWAYS
#服务发现日志打开
logging.level.org.springframework.cloud.consul.discovery.ConsulDiscoveryClient=DEBUG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
问题一:Consul服务重启,应用服务是否需要重新注册?
实验步骤:

启动Consul服务
E:\consul_1.9.0_windows_amd64> consul.exe agent -dev -data-dir /consul/data -log-file /consul/logs/consul.log
1
启动应用服务,注册到Consul


Consul服务关闭

Ctrl + C(关闭Consul服务)

应用服务,服务发现异常(如期望)

Consul服务重新启动

E:\consul_1.9.0_windows_amd64> consul.exe agent -dev -data-dir /consul/data -log-file /consul/logs/consul.log
1

实验结果:

Consul服务关闭,应用服务会继续进行服务发现,更新本地服务列表(只不过是失败)
Agent对应用服务进行健康检查,状态发生改变的时候,会更新应用服务在Consul服务注册中心的状态
Consul服务重启(启动参数不变,持久化数据可以加载),可以继续提供服务(健康检查和服务注册与发现)
服务Consul服务重启,应用服务不需要重新注册。但是有前提:如果Consul服务是在Docker容器中或者是集群模式部署,服务关闭前与重启时候,所有Consul agent信息应当完全一致(比如IP),否则,应用服务无法更新服务列表。

问题二:TTL方式健康检查,应用服务长时间处于不健康状态,Consul服务是否会强迫应用服务下线?
实验分为两种情况:

①应用服务与Consul服务之前的网络连接断了,无法再更新服务状态
实验步骤:

Consul服务启动、应用服务启动注册
#TTL(心跳开关),当值为false时候,HTTP方式健康检查生效
spring.cloud.consul.discovery.heartbeat.enabled=true
#心跳频率(例如5s一次)
spring.cloud.consul.discovery.heartbeat.ttl-value=5
#critical状态下线时间限定(Consul服务用)
spring.cloud.consul.discovery.health-check-critical-timeout=5m
1
2
3
4
5
6
$ nohup.exe java -jar consul-client-0.0.1-SNAPSHOT.jar  >filename.log 2>&1 &
1
期望:5s左右进行一次心跳,停服务姿势不正确(kill -9),等5min后,Consul服务端下线应用

关闭 应用服务进程(或者 kill -9)

查看Consul agent日志输出

实验结果:

TTL方式做为健康检查,心跳间隔为:ttl-value×2÷3(源码算法)
当超过心跳时间间隔,没有心跳发送到Consul服务,会开始记录时间
当心跳丢失时间超过health-check-critical-timeout设置值,则在Consul服务端会将应用服务下线
反复调整参数health-check-critical-timeout,发现该参数最短时间为1min
②应用服务长时间更新状态,均为不健康状态
实验步骤:

Consul服务启动、应用服务启动注册
#TTL(心跳开关),当值为false时候,HTTP方式健康检查生效
spring.cloud.consul.discovery.heartbeat.enabled=true
#心跳频率(例如5s一次)
spring.cloud.consul.discovery.heartbeat.ttl-value=5
#critical状态下线时间限定(Consul服务用)
spring.cloud.consul.discovery.health-check-critical-timeout=5m
1
2
3
4
5
6
应用服务启动一段时间后,健康检查始终更新服务为不健康状态
从第20次心跳之后开始持续刷新状态为critical
$ nohup.exe java -jar consul-client-0.0.1-SNAPSHOT.jar --check.threshold=20 >filename.log 2>&1 &
1
查看Consul agent日志输出

应用服务被下线后,尝试更新在Conusl服务的状态

应用服务已经被下线,再次接收到更新应用服务状态的请求,请求被拒绝执行

查看Conusl与应用服务日志,不难发现,应用服务主动刷新服务状态为critical,也持续了5min之后,Consul服务下线了应用服务。并且应用服务无法再更新自身状态到

实验结果:

应用服务持续更新自身状态为critical,时间超过health-check-critical-timeout,Consul会下线该服务
当应用服务在Conusl服务注册中心下线之后,便不能再更新服务状态(服务都不在了,不能更新自然是理所当然)
问题二的答案:
TTL方式健康检查,当服务处于critical状态时间超过了health-check-critical-timeout设置的值,则应用服务会被迫下线,并且不可再进行状态的维护

问题三:HTTP方式健康检查,应用服务长时间处于不健康状态,Consul服务是否会强迫应用服务下线?
实验分为两种情况:

①应用服务与Consul服务之前的网络连接断了,无法再更新服务状态
实验步骤:

Consul服务启动、应用服务启动注册
#关闭心跳,则使用HTTP方式进行健康检查
spring.cloud.consul.discovery.heartbeat.enabled=false
1
2


关闭 应用服务进程(或者 kill -9)


查看Consul agent日志输出


实验结果:
与TTL健康检查方式相同,当应用服务处于critical*状态持续时间health-check-critical-timeout,服务会被迫下线

②应用服务长时间更新状态,均为不健康状态
实验步骤:

Consul服务启动、应用服务启动注册
#关闭心跳,则使用HTTP方式进行健康检查
spring.cloud.consul.discovery.heartbeat.enabled=false
1
2
应用服务启动一段时间后,健康检查始终返回500

查看Consul agent日志输出

实验结果:
与TTL健康检查方式相同,当应用服务处于critical状态持续时间health-check-critical-timeout,服务会被迫下线

总结问题二和问题三实验结果
当应用服务处于critical状态持续时间health-check-critical-timeout,服务会被迫下线,也就是说health-check-critical-timeout属性是对Consul服务端有用的,对与应用服务来说没有什么用。至于是Push(TTL)还是Pull(HTTP)类型的健康检查在这方面是没有区别的。
Pull和Push的区别在于,将服务状态更新的操作交给谁来做,猿Why在看过美剧《硅谷》之后,对『去中心化』这个概念印象深刻。Push方式接近这个概念。把服务治理很大一部分压力交给应用服务自身。
Consul支持的HTTP健康检查是根据HTTP请求 Response 的status code(passing: 200 < warning: 429 < critical: 503)判断的,健康检查的内容没有什么卵用。
Consul Check 源码地址

func (c *CheckHTTP) check() {
    // 省略前边一大堆代码

   if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
      // PASSING (2xx)
      c.StatusHandler.updateCheck(c.CheckID, api.HealthPassing, result)
   } else if resp.StatusCode == 429 {
      // WARNING
      // 429 Too Many Requests (RFC 6585)
      // The user has sent too many requests in a given amount of time.
      c.StatusHandler.updateCheck(c.CheckID, api.HealthWarning, result)
   } else {
      // CRITICAL
      c.StatusHandler.updateCheck(c.CheckID, api.HealthCritical, result)
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
问题四:应用服务如何优雅下线?
关闭应用服务,源码阅读,Tomcat接收到信号量,销毁容器,容器销毁之前调用API进行服务下线
Tomcat容器优雅关闭应用:org.springframework.scheduling.concurrent.ExecutorConfigurationSupport#shutdown
容器关闭:调用org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry#deregister
容器销毁之前,触发应用服务下线


问题五:应用服务重新注册会出现什么情况?
以HTTP健康检查方式为例,进行实验,分为两种情况:

①:Consul注册中心,服务处于健康状态,应用服务重新注册
实验步骤:

健康检查,健康检查时间间隔设置长一些,启动应用注册到Consul
#Pull类型(HTTP)健康检查时间间隔
spring.cloud.consul.discovery.health-check-interval=30s
1
2
迅速杀掉应用服务
迅速重新启动应用
分析日志

实验结果:

Consul服务注册中心,应用服务处于健康状态,应用服务重新注册是允许的
重新注册的前提条件:注册的应用服务信息保持不变
②:Consul注册中心,服务处于不健康状态,应用服务重新注册
实验步骤:

健康检查,非健康状态时间限制设置长一些,健康检查时间间隔短一点,启动应用注册到Consul
暴力杀掉应用服务
纠正截图中的暴力杀掉应用命令为kill -9(此处虽然-15也能验证实验)
重新启动应用
分析日志

实验结果:

Consul服务注册中心,应用服务处于不健康状态,应用服务重新注册是允许的
重新注册的前提条件:注册的应用服务信息保持不变
问题五实验结果:
Conusl服务中已经存在一个应用服务的实例,同样的实例信息再次注册,依然可以成功注册
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/u010730731/article/details/111396158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值