k8s优雅启停总结
2022-09-20 17:39:52 0 举报
AI智能生成
k8s优雅启停总结
作者其他创作
大纲/内容
1、优雅启停问题背景
在 Java应用程序重启时,如果直接 kill -9 使程序退出,再启动,会存在的问题:
旧的请求未处理完,如果服务端进程直接退出,会造成客户端连接中断会收到连接超时(收到 `RST`)
新请求进来,服务还没重启完毕,造成 `connection refused`、
2、单机应用程序优雅启停处理方式
原生Java优雅启停处理方式
原生Java的优雅停机通常通过注册JDK的ShutdownHook(钩子)来实现,关闭钩子本质是一个线程(也称为Hook线程),用来监听JVM的关闭。经过Runtime的addShutdownHook能够向JVM注册一个关闭钩子。当系统接收到退出指令后,首先标记系统处于退出状态,不再接收新的消息,然后将积压的消息处理完,最后调用资源回收接口将资源销毁,最后各线程退出执行。
spring提供健康检测端点实现优雅启停
springBoot架构中的应用优雅停机通过微服务框架健康检测能力来实现,在springBoot中,提供了actuator组件/health端点来实现。客户端须要实现一个自定义的HealthCheckHandler或者在应用程序配置文件打开优雅停机(如下图),它将应用的健康状态保存到内存中,只需在K8s 对应pod 配置文件下利用curl脚本发送shutdown命令,状态一旦发生改变,就会从新向服务器进行注册。
3、springCloud+nacos体系优雅启停方案
springBoot中,提供了actuator组件/health端点来实现通过curl脚本发送shutdown命令让应用程序下线
由于应用程序启动注册nacos后nacos会缓存服务实例、应用程序下线后注册中心并无感知、下线后应主动通过curl脚本主动发起注册中心服务下线。
由于gateway网关有一套自己的服务缓存列表。当服务状态发生变化也需要重新获取最新的服务列表
4、k8s发布时关联spring cloud优雅启停方案
k8s以支持发布服务默认使用的滚动发布方案,这个方案本身已经有一定机制减少发布的影响。滚动发布时发布完一个新版本的pod后才会下线一个旧的pod,并把指向sevice的请求经负载均衡指向新pod,直到所有旧的pod下线,新的pod全部发布完毕。所以只要k8s在pod的启停时做到和微服务联动,就可以做到无感发布。关键在于探知微服务是否准备好了、通知服务将要停止、配置启停过程预留的时间。这几个方面k8s都有相关的机制。
启动后就绪时间这个机制相对简单粗暴,通过一个属性 minReadySeconds 设置pod启动后多长时间才被认为就绪,默认为0s
探针机制k8s提供了是两种探针的机制,分别为就绪探针 readinessProbe、存活探针 livenessProbe。探针机制可以通过http接口、shell指令、tcp确认容器的状态。探针还可以配置延迟探测时间、探测间隔、探测成功或失败条件延后时间等参数。使用http接口探测时,可以配置header参数,如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
terminationGracePeriodSeconds 配置延迟关闭时间该属性默认30s,只配置terminationGracePeriodSeconds这个属性而没有配置prestop时,k8s会先发送SIGTERM信号给主进程,然后然后等待terminationGracePeriodSeconds 属性的时间,会被使用SIGKILL杀死。这个机制相对简单粗暴
prestop 机制 prestop机制,为容器生命周期钩子中的一种,也就是在准备关闭pod时会调用的。这个接口调用是至少一次,有可能调用多次,需要做好幂等处理。这个机制和就绪探针类似,也可以通过http接口、shell指令两种方式进行。 k8s配置pod如下
启动问题基于以上机制解决启动问题使用k8s的就绪探针配合提到的spring cloud+nacos程序本身的启动和注册机制就可以初步的解决。微服务启动未完成或预加载未完成就被注册到nacos以及被k8s导入外部流量的问题。
停机问题使用k8s preStop机制调用微服务3.0即可解决。但是prestop存在一个超时时间,如果设置的超时时间内prestop调用的接口没有完成,则服务存在强制退出的可能,从而产生异常数据或者短暂出现500错误。由于异常宕机难以避免,一般程序本身也必须要有异常处理方案,比如微服务架构下fegin整合的降级熔断处理。
5、验证
试验优雅启停方案,基于k8s环境,使用两个spring cloud+nacos服务,其中一个服务A为weixin-api服务,提供获取用户id接口,A服务使用两个pod。另外一个服务Bmall-api调用A的获取用户接口。
通过jmter压测工具发起多次压力测试。压力测试期间通过Jenkins重新构建A服务、直到pod切换完成查看jmter结果。是否存在500、503响应码。
收藏
0 条评论
下一页