Spring cloud系列20 实现服务优雅上下线

在使用Spring Cloud微服务的过程中,必然会碰到微服务因为版本升级而重启。如果只是使用kill命令结束服务进程,则依赖此服务的客户端服务不会立即知道目标服务已经下线,仍然会调用目标服务借口,会因为访问失败会抛出异常,为了避免这个情况,我们希望实现服务升级对用户是无感知的

如何解决问题
首先我们搜索网络,发现这篇文章实用技巧:Spring Cloud中,如何优雅下线微服务?,但是这篇文章的方法都符合我们的业务要求。

后来经过研究发现以下方法,使用EurekaAutoServiceRegistration对象可以达到我们的目的。我们使用的注册中心框架是Eureka

  • 执行eurekaAutoServiceRegistration.stop() 方法时,本服务会向Eureka注册中心进行反注册,注册中心收到请求后,会将此服务从注册列表中删除。
  • 执行eurekaAutoServiceRegistration.start() 方法时,本服务向Eureka注册中心注册服务

代码如下:

@RestController
@RequestMapping(value = "/test-service")
@EnableSwagger2
@Deprecated
public class Test {
    @Autowired
    private EurekaAutoServiceRegistration eurekaAutoServiceRegistration;

    @RequestMapping("/online")
    public String online() {
        this.eurekaAutoServiceRegistration.start();
        return "user online method";
    }

    @RequestMapping("/offline")
    public String offline() {
        this.eurekaAutoServiceRegistration.stop();
        return "user offline method";
    }
}

服务启动后,调用以下命令使目标服务下线
http://127.0.0.1:10803/demo//eureka-service/online
登录注册中心看,目标服务已经下线
在这里插入图片描述
此时,还不能停止目标服务,因为Eureka实现AP关系,此时依赖目标服务的服务还不知道此服务已经下线,目标服务仍然需要正常运行。等待Ns后,其他服务知道目标服务已经下线,不在访问目标服务,则停止目标服务,然后升级服务

服务调用者多久知道目标服务已经下线
实际应用时,这里有个问题,服务调用者多久知道目标服务已经下线?
我们整理服务整个流程:

  1. 准备下线服务调用eurekaAutoServiceRegistration.stop()方法
  2. Eureka注册中心收到注销请求后,会先将信息更新到读写缓存中。Eureka注册中心有两个缓存:读写缓存和只读缓存。关于Eureka注册中对缓存的描述详细见这篇文章Spring cloud系列十六 Eureka各个组件详解和相关配置详细说明
  3. 注册中心有个定时任务会定时(默认值是30s)将读写缓存中的数据同步到只读缓存中
  4. 服务调用者务会定时(默认值也是30s)从注册中心拉取次服务列表(为了提高性能,此时只是从只读缓存中获取),并更新本地信息

综上,服务调用者最多花费60s(30s+30s)就可以知道服务已经下线

你可能感兴趣的:(spring,boot,spring,spring-cloud)