Kubernetes下,Spring Cloud服务平滑升级

Kubernetes下,Spring Cloud服务平滑升级

运行环境

  • Kubernetes
  • Spring Cloud <= 2020
  • Nacos

运行现象

当微服务在 Kubernetes编排下,进行服务滚动升级或者动态缩容时,应用已经关闭,然而此时会有请求无法得到响应,导致在滚动升级以及缩容期间,出现部分请求出错

原因分析

由于Nacos的健康检查机制以及Ribbon的缓存策略,导致服务虽然已经关闭,但是已经关闭的服务的列表信息依然还注册在Nacos注册中心上或者缓存在Ribbon的本地服务列表信息中,导致请求发送至已经关闭了的服务,导致请求出错

  • Nacos健康检查

    Nacos默认每 5s检测实例的上次心跳间隔时间是否大于15秒,若大于则将实例健康状态为false。 如果时间间隔超过30秒,则会剔除实例。

  • Ribbon缓存策略

    Ribbon自身会对服务列表进行缓存,即 Ribbon会每 30s向注册中心获取服务的列表信息,更新本地缓存

解决方案

修改服务配置

  • 修改服务心跳间隔

    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
            metadata:
    		  # 心跳间隔 单位毫秒
    		  preserved.heart.beat.interval: 1000 
    		  # 心跳暂停 单位毫秒
    		  preserved.heart.beat.timeout: 3000 
    		  # 删除超时 单位毫秒
    		  preserved.ip.delete.timeout: 3000 
    
  • 在 Spring Cloud Gateway中,增加 ServerListRefreshInterval配置,修改 Ribbon缓存刷新时间:

    ribbon:
      ServerListRefreshInterval: 3000
    

上述 Nacos心跳间隔以及 Ribbon缓存刷新时间的设置,需要考虑对 Nacos压力以及服务的性能酌情设置。
经过对服务配置的修改,已经极大的缩短了服务不可用的时间范围,但此时仍然还会存在一定时间的旧服务列表信息,此时可以通过使用 Spring Cloud Gateway的重试机制来进行解决。。当服务请求发送至已经关闭的服务时,通过响应的状态,网关向其它服务发起重试,保证服务滚动升级或者缩容期间的正常响应

  • Spring Cloud Gateway配置重试机制
    spring:
      cloud:
        gateway:
          routes:
          - id: dubbo-provider
            uri: lb://dubbo-provider
            predicates:
            - Path=/provider/**
      	    filters:
    	      name: Retry
    	      args:
    	        retries: 3 # 重试次数,默认3次
    	        series:
    	        - SERVER_ERROR # 重试错误类型
    	        methods: # 重试请求类型
    	        - GET
    	        - POST
    	        exceptions:
    	        - java.lang.Exception # 重试异常类型
    

(该文章只是提供一个思路,不做配置以及源码的具体分析)

你可能感兴趣的:(spring,cloud,kubernetes,java,微服务)