您现在的位置是:网站首页> 编程开发> devops 编程开发
解决k8s里平滑下线nacos的问题
2023-06-30【devops】 838人已围观
简介今天上线,突然间齐刷刷报出来一堆错误,本以为有平滑下线就不用去操作下线nacos的动作。后来排查发现,居然平滑下线没起作用。问了一下chatgpt:k8s里优雅退出怎么做?在Kubernetes(简称K8s)中,优雅退出是指在停止或重启一个容器时,容器能够平稳地完成正在处理的工作,并允许正在进行的请求正常完成,不中断用户的服务。以下是在Kubernetes中实现优雅退出的几种方法: 1.&n
解决k8s里平滑下线nacos的问题
最后更新:2023-06-30 16:25:54
推荐指数:
今天上线,突然间齐刷刷报出来一堆错误,本以为有平滑下线就不用去操作下线nacos的动作。后来排查发现,居然平滑下线没起作用。
问了一下chatgpt:k8s里优雅退出怎么做?
在Kubernetes(简称K8s)中,优雅退出是指在停止或重启一个容器时,容器能够平稳地完成正在处理的工作,并允许正在进行的请求正常完成,不中断用户的服务。以下是在Kubernetes中实现优雅退出的几种方法: 1. 使用Kubernetes的TerminationGracePeriodSeconds参数:在Pod的配置文件中,可以设置TerminationGracePeriodSeconds参数来控制容器终止前的等待时间。Kubernetes会等待该时间段后再强制关闭容器。可以提供一个合适的时间让容器完成正在处理的任务。 ```yaml apiVersion: v1 kind: Pod metadata: name: my-pod spec: terminationGracePeriodSeconds: 30 containers: - name: my-container image: my-image ``` 2. 在容器内部处理信号:在容器内部编写代码来处理接收到的信号,例如SIGTERM。在接收到信号后,容器可以执行清理工作(例如保存数据、释放资源等)然后正常退出。 以Python为例,可以使用`signal`库来捕获信号并实现优雅退出的逻辑: ```python import signal import sys def graceful_exit(signum, frame): # 执行清理工作 # ... sys.exit(0) signal.signal(signal.SIGTERM, graceful_exit) # 业务逻辑 # ... ``` 3. 使用Kubernetes的PreStop钩子:PreStop钩子是一种在Pod终止之前执行的容器命令或脚本。可以在PreStop钩子中编写容器终止前的清理逻辑,例如发送停止信号给应用程序,等待正在处理的任务完成后再退出。 ```yaml apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image lifecycle: preStop: exec: command: ["./cleanscript.sh"] ``` 以上是一些常见的方法,可以根据具体场景选择适合的方式来实现优雅退出。在Kubernetes中,优雅退出对于确保高可用性和稳定性非常重要。
看了以上内容,发现还是有思路的,至少证明我的k8s里的prestop配置是没错的。
我的k8s配置如下图:
那问题就应该是出现在了我的pre-stop.sh脚本里了。
我的脚本里是写了一个curl脚本停止调用我的nacos,我尝试进入容器,手动调用pre-stop.sh试一试?
果然,我只调用了pre-stop.sh一个shell居然就直接把我的微服务从nacos里下线了,这根本不是我要的效果啊。现在微服务直接下线,如果有上游服务调用我,那肯定会报错的。所以问题出现在了下线nacos的问题。
后分析源码,果然 出现在了
serviceRegistry.deregister(registration); 这里是直接把服务从nacos里删除,我要的目录只需要标记下线就好。所以换个方法吧。 serviceRegistry.setStatus(registration,"DOWN"); 使用以上方法。完美解决问题,具体源码如下:
public void offline(){ new Thread(() -> { log.info("Ready to stop service"); //serviceRegistry.deregister(registration); serviceRegistry.setStatus(registration,"DOWN"); int waitTime = offlineProperties.getWaitTime(); log.info("instance has been de-registered: {}" , registration.getServiceId()); log.info("Waiting {} milliseconds...", waitTime); try { Thread.sleep(waitTime); } catch (InterruptedException e) { log.info("interrupted!", e); } log.info("Closing application..."); final int exitCode = SpringApplication.exit(context); log.info("Closing application code: {} ",exitCode); System.exit(exitCode); }).start(); }
完美解决问题!
很赞哦! (0)
上一篇:企业自动化持续发布方案
文章评论
验证码: