• k8s环境下spring cloud优雅停机


    目的

     Spring cloud 微服务、k8s容器化部署的架构下,单个服务升级过程中,不停止对外提供服务,使得用户对整个升级过程无感知,从而实现服务的优雅升级。

    负载均衡器

      1. spring cloud ribbon(k8s同namespace):k8s同一命名空间之间的服务调用,采用ribbon、eureka做服务注册和负载均衡。

         问题:

            a、ribbon和eureka(CP)注重服务的可用性,所以存在服务实例的缓存,本地缓存:(1)ribbon本地缓存 (2)eureka client本地缓存 。远程缓存:(1)eureka server 三级缓存

            b、service 提供者停止,pod 向容器发送SIGTERM信号,service 提供者会向eureka server下线服务,这个时候service消费者会存在原有service的实例信息

      2. k8s  service (k8s不同namespce):  k8s不同命名空间之间的服务调用,采用k8s service、kube-proxy做服务注册和负载均衡。

         问题:

           a、k8s service 支持服务的负载均衡,只有容器探针检测成功后,才会停止旧的容器Service。采用两种探针实现RollingUpdate。但是前提要存在多个实例

    基于spring cloud 负载均衡的优雅停机

      针对spring cloud负载均衡存在的问题,要做到优雅停机,需要进行如下配置:

     a、缩短缓存时间

       1. 修改Client配置(ribbon和eureka client)

     1 ribbon:
     2   # ribbon刷新eureka的时间5s, 默认30s
     3   ServerListRefreshInterval: 5000
     4 #注册中心
     5 eureka:
     6   client:
     7     serviceUrl:
     8       defaultZone: http://eureka-server:8761/eureka
     9     # eureka客户端需要多长时间发定时刷新本地缓存时间,默认30s
    10     registry-fetch-interval-seconds: 5
    11   instance:
    12     prefer-ip-address: true
    13     instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    14     # eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然活着,默认30秒
    15     lease-renewal-interval-in-seconds: 5
    16     # eureka服务器在接受到实力的最后一次发出的心跳后,需要等待多久才可以将此实例删除 默认90秒
    17     lease-expiration-duration-in-seconds: 15

        缩短ribbon本地缓存时间,eureka client拉取注册表、心跳间隔时间 

       2. 修Server配置(eureka server)

     1 eureka:
     2   server:
     3     # 禁用readOnlyCacheMap
     4     useReadOnlyResponseCache: false
     5     # 主动失效检测间隔, 默认60s
     6     evictionIntervalTimerInMs: 5000
     7   instance:
     8     # eureka服务器的标识,如果是集群就可以写成 eurekaSer1,eurekaSer2,eurekaSer3..
     9     hostname: eureka-server
    10     health-check-url-path: /actuator/health
    11   client:
    12     # 开启客户端存活状态监测
    13     healthcheck:
    14       enabled: true
    15     registerWithEureka: false
    16     fetchRegistry: false

      缩短失效检测的实现,同时禁用readOnlye缓存。 eureka server 存在三级缓存 ,均是纯内存操作,详细见下图

    (1)registry(ConcurrentMap):注册表
    (2)readWriteCacheMap(GuavaCache):读写缓存
    (3)readOnlyCacheMap(ConcurrentMap):只读缓存

    
    
    b、Service先下线,再停机
    1、增加Service 下线端点
     1 @ConfigurationProperties(prefix = "endpoints.offline")
     2 public class OfflineEndpoint extends AbstractEndpoint<String> {
     3 
     4     public OfflineEndpoint() {
     5         super("offline", false);
     6     }
     7 
     8 
     9     @Override
    10     public String invoke() {
    11         String remoteIp = IPUtils.getIp();
    12         String localIp = IPUtils.getLocalIp();
    13         log.info("remoteIp:{} trigger service offline", remoteIp);
    14         if(localIp.substring(0, localIp.lastIndexOf(".")).equals(remoteIp.substring(0, remoteIp.lastIndexOf(".")))) {
    15             log.info("service start execute offline");
    16             DiscoveryManager.getInstance().shutdownComponent();
    17             try {
    18                 Thread.sleep(10000);
    19             } catch (InterruptedException e) {
    20                 log.error("sleep exception",e);
    21                 throw new RuntimeException(e);
    22             }
    23             log.info("service end execute offline");
    24             return "SUCCESS";
    25         } else {
    26             log.warn("remoteIp:{} localIp:{} not trigger service ll_offline", remoteIp, localIp);
    27             return "NOT_ALLOW";
    28         }
    29 
    30     }
    31 }
    View Code

        2、利用pod preStop hook

    1  lifecycle:
    2           preStop:
    3             httpGet:
    4               port: 9494 
    5               scheme: HTTP
    6               path: offline

     c、Spring Cloud升级流程总结

       针对容器化RollingUpdate,Service 旧版本A,新版本A1发布流程如下:

       1、新版本容器Service A1,而在Service A1启动后就会注册到Eureka Server,

       2、Service A1,只有容器探针检测成功后,才会停止旧的容器Service A。所以此时 Service A1 和 Service A都注册在 Eureka Server上,接受流量

       3、Service A1,容器探测成功,下线Service A

       4、Service A 触发 preStop的offline操作,将Service A 从Eureka Server中下线,直至缓存更新完成

       5、Service A停止,Service A1 上限,完成单次服务滚动更新

    基于k8s service 负载均衡的优雅停机

      实例注册:容器启动成功并不会注册到service,只有需要容器readinessPro成功后,才会注册到service。

      实例注销:容器执行preStop的同时就会将实例信息从service注销

      k8s Deployment本身就支持Rolling update,所以这里优雅停机:可以先扩容到2个实例,然后再缩容到1个实例,实现单服务的滚动更新

         



             

  • 相关阅读:
    From MSI to WiX, Part 2
    From MSI to WiX, Part 1
    WIX Custom Action (immediate, deffered, rollback)
    SVN: revert all command
    HowTo: SVN undo add without reverting local changes
    “Assign Random Colors” is not working in 3ds Max 2015
    CruiseControl.NET : svnrevisionlabeller
    JSON parser error with double quotes
    How to: Extract files from a compiled setup.exe created by Inno setup
    虚拟账号ftp服务器
  • 原文地址:https://www.cnblogs.com/mxmbk/p/12705014.html
Copyright © 2020-2023  润新知