侧边栏壁纸
博主头像
云录博主等级

行动起来,活在当下

  • 累计撰写 24 篇文章
  • 累计创建 11 个标签
  • 累计收到 18 条评论

目 录CONTENT

文章目录

【云原生 | Kubernetes 系列】SpringCloud - Nacos 结合 K8s 服务优雅上下线

Dylan
2023-12-21 / 0 评论 / 0 点赞 / 133 阅读 / 2705 字 / 正在检测是否收录...
广告 广告

【云原生 | Kubernetes 系列】—SpringCloud - Nacos 结合 K8s 服务优雅上下线

版权 本文为云篆录原创文章,转载无需和我联系,但请注明来自云篆录 http://www.yunzhuan.site

🍇 问题描述

在生产环境中使用springbootforalibaba框架,在服务升级的过程中,pod会被直接停止,在高并发的情况下
部分请求被分发到终止的容器,服务出现500的情况,所以考虑使用优雅停止服务,和平滑上线,将错误率减少到最低。

🍋 解决思路

  • 在pod关闭之前,新的请求不能够进来。因为nacos健康检查默认是5s,假如现在服务已经完全关闭了,而nacos还没有感知到, 依旧将新的请求调度到完全关闭的节点,那么请求就会500。因此,我们可以利用k8s的生命周期特性(preStop 钩子函数)在服务 关闭之前我们将服务的权重修改为0,这样新的请求就不会打到即将关闭的服务了。
  • 在nacos服务权重为0后,因为nacos默认更新时间为30S,每个服务里面都会缓存一份naocs服务缓存表,这个时候我们还是不能关闭 服务,让程序继续跑,是为了处理旧的请求,以及有足够的时间返回请求,因此我们在preStop钩子函数里面sleep 45S(注意这个时间要大于30S) 留足够的时间处理。

🥭解决方案

  • 获取podip,因为nacos提供的接口需要服务的podip,因此我们需要在容器里面获取podip
env:
   - name: POD_IP
     valueFrom:
       fieldRef:
         apiVersion: v1
         fieldPath: status.podIP
  • 修改k8s Deploy,增加preStop钩子函数,所需要的参数
  1. nacos地址 http://127.0.0.1:8848
  2. serviceName,服务名称 applicationName
  3. clusterName 集群名称
  4. groupName 组名称
  5. ip pod的ip
  6. port 服务端口
  7. namespaceId nacos命名空间
lifecycle:
  preStop:
    exec:
      command:
        - bash
        - "-c"
        - 'curl -X "POST"  "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=applicationName&clusterName=DEFAULT&groupName=DEFAULT_GROUP&ip=$POD_IP&port=8080&ephemeral=true&weight=0&enabled=false&namespaceId=nacosNamespace" -H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8";sleep 45'
  • 修改terminationGracePeriodSeconds,K8s 关闭机制里还有一个重要参数 terminationGracePeriodSeconds(默认 30s)K8s 在执行关闭过程中,因为上面有一些命令需要执行,难免会出现一些意外,导致程序一直卡死在那边,所以 K8s 有一个补偿机制,就是如果关闭流程消耗的时间大于这个参数时间时,马上 K8s 强制关闭,所以这个时间必须大于 sleep 的时间
spec:
  terminationGracePeriodSeconds: 60

🥭验证效果

当我们停止一个服务的时候,看是否下线服务

  • 停止前 imgyouya1.png
  • 停止中 此时服务已经下线 imgyouya2.png
  • 完全关闭,并重新生成新的服务 imgyouya3.png
版权 本文为云篆录原创文章,转载无需和我联系,但请注明来自云篆录 http://www.yunzhuan.site
0

评论区