您的位置:  首页 > 技术杂谈 > 正文

K8S优雅升级系列(下) | 项目实战配置

2022-09-08 14:00 https://my.oschina.net/u/4580203/blog/5574267 汉得数字平台 次阅读 条评论

图片

前面我们已经讲解了如何让应用和容器优雅下线以及如何优雅滚动发布,相信大家对“优雅”已经有了一定的认识,这里提供某大型ToC项目的配置实例:

问题现象:在生产环境进行发版、服务滚动更新的这段时间内,如果刚好有用户访问系统会出现报错。针对流量比较大且始终有顾客在使用的商城系统,短暂的出现访问出错也是不可接受的。

问题原因:新的POD拉起,旧的POD销毁,在这个过程中资源会有一定的延迟更新,导致流量可能进入还没准备好的新POD或者进入已经销毁的旧POD,从而出现访问出错。

 

配置优雅下线

旧的POD销毁这段时间,只要我们控制流量不进入销毁中的POD,就能达到优雅下线的目的:

高版本Spring Boot(Hzero1.7及1.7之后),已经提供了优雅下线的参数,配合K8S的钩子和优雅下线宽限期,可以达到真正的优雅下线,三个关键参数分别为50秒+40秒+30秒。

设置要求:TerminationGracePeriodSeconds>Prestop中Sleep的时间>Spring.lifecycle.timeout-per-shutdown-phas时间

步骤一:置50秒TerminationGracePeriodSeconds

图片

 

步骤二:休眠40秒Prestop

利用K8S的钩子,在程序销毁前先睡眠40秒(建议值,具体时间视请求的处理时间而定);在这40秒的时间内Eureka发现检测失败会把这个Pod剔除,不再转发流量到Pod上,同时也有40秒的时间能处理剩余的流量正常返回,从而避免出错的情况。

项目上通过步骤二单一配置,报错率大概降低了98%,针对流量不大的ToB系统基本可以满足了,针对大流量的系统或者ToC的场景,建议把步骤一到步骤三做完(或者在休眠前调用自定义脚本,主动剔除Eureka的注册POD,也能达到目的)

图片

 

步骤三:设置30秒timeout-per-shutdown-phas

停止设置为优雅停止,时间设置为30秒,可以在Yml文件中配置也可以设置在VM参数中

JAVA_OPTS=-Dserver.shutdown=graceful-Dspring.lifecycle.timeout-per-shutdown-phase=30s

 

配置优雅滚动发布

新的POD拉起这段时间,只要我们控制流量不进入未完全准备好的POD,就能达到优雅上线的目的,两个配置步骤解决:

步骤一:设置探针

K8S提供了两种检查探针,分别为存活检查就绪检查,从名字上也能清晰地知道两种探针的作用。

存活检查:让K8S知道应用是否还正常提供服务,如果应用已经挂了,K8S会自动移除该POD并启动一个新的POD替换它;

就绪检查:让K8S知道应用是否已经准备好接收流量,只有就绪检查通过才会把流量转发到POD,否则会停止向POD发送流量,直至检查通过;

探针配置如下:

协议

HTTP

路径

Hzero的服务默认都集成了Actuator健康监控,直接配置即可。

Hzero1.7版本及以上,两种探针分别配置:

/actuator/health/liveness

/actuator/health/readiness

 

Hzero1.7版本以下的,两种探针都配置:/actuator/health

端口

Yml配置文件的管理端口,Management.server.port

延迟探测时间

120秒

如果服务启动时间长可适当延长

执行探测频率

10秒

超时时间

10秒

不健康阈值

3

 

步骤二:配置服务注册

之所以需要配置服务注册参数,是为了避免这种情况

当探针延迟120秒POD状态还没变为Running时,Eureka注册中心上的节点已经是UP的状态,如果是以POD IP的形式注册到Eureka上,此时内部Fegin调用的流量有可能会分发到非探测通过的POD上,导致程序出错。

我们的解决整体思路是配置改为Hostname注册值Eureka,Hostname和SVC名称一致,这样就会去请求SVC再负载到POD上,当POD未就绪的时候,就不会参与到SVC的负载上。

  • 配置PreferIpAddress

修改Bootstrap.yml,PreferIpAddress: ${EUREKA_INSTANCE_PREFER_IP_ADDRESS:true}修改为PreferIpAddress: ${EUREKA_INSTANCE_PREFER_IP_ADDRESS:false};

或者在环境启动参数EUREKA_INSTANCE_PREFER_IP_ADDRESS设置为False,效果是一样的。

  • 配置Hostname

根据服务名称命名,且需要跟后续的SVC名称保持一致,修改Bootstrap.yml,加入以下配置:

eureka:  instance:    hostname: hzero-gateway

或者服务启动指定参数Eureka.instance.hostname=hzero-gateway,效果是一样的。

  • 创建SVC

Name: Hzero-gateway,与Bootstrap.yml文件的Hostname需要保持一致,否则会报500​​​​​​​

apiVersion: v1kind: Servicemetadata:  labels:    choerodon.io/release: hzero-gateway  name: hzero-gateway  namespace: xxxspec:  ports:    - port: 8080      targetPort: 8080      protocol: TCP      name: service-0    - port: 8081      targetPort: 8081      protocol: TCP      name: service-1  selector:    choerodon.io/release: hzero-gateway  type: ClusterIP

 

通过上述的两大配置五大步骤,能够达到系统24小时可用,代码发布不影响顾客前端操作体验的效果。

所谓优雅就是平滑切换不报错,核心思路是在新的POD拉起、旧的POD销毁这个过程中,也就是POD还没准备好的时间窗口,不要把流量分发过去。理解了流量会经过哪些组件、组件的缓存策略,要达到优雅这个目的,我们的配置方式可以是多种多样,但万变不离其宗,大家也可以自己尝试新的配置方式。

 

联系我们

产品试用请登录开放平台。请在 PC 端打开:

https://open.hand-china.com/market-home/trial-center/

产品详情请登录开放平台:

https://open.hand-china.com/document-center/

如有疑问登录开放平台提单反馈

https://open.hand-china.com/

图片

图片

▲ 更多精彩内容,扫码关注 “四海汉得” 公众号

 

展开阅读全文
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接