验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

Spring Cloud Alibaba如何实现服务的无损下线功能

阅读:384 来源:乙速云 作者:代码code

Spring Cloud Alibaba如何实现服务的无损下线功能

      解决方案

      1 找到通过负载均衡组件获取可用服务信息的地方

      Spring Cloud Alibaba如何实现服务的无损下线功能

      通过一顿Debug之后,从上图中可知,我们获取到可用的服务实例信息,会从缓存中获取,那么如果当服务下线后,我们清空这个服务的缓存的信息,那么下次在获取这个服务的信息就是最新的了,那么问题就解决了。

      2 解决思路

      Spring Cloud Alibaba如何实现服务的无损下线功能

      • 服务提供方或消费方,同时监听 Spring Cloud Config中的某个配置文件,比如lossless文件

      • 服务下线时, 第一步: 从nacos上将自身这个实例下线。 第二步: 通过api更新lossless 文件中的内容,记录服务下线的服务名加上时间戳

      • 消费者或网关,监听到lossless配置文件的变更,获取到服务名,然后将这个服务名对应的缓存清空

      部分实现代码

      1 引入jar

      
      	
          
              com.alibaba.cloud
              spring-cloud-starter-alibaba-nacos-discovery
          
          
          
              com.alibaba.cloud
              spring-cloud-starter-alibaba-nacos-config
          
          
          
              com.alibaba.nacos
              nacos-spring-context
              1.1.1
          
          
              org.projectlombok
              lombok
          
          
          
              org.springframework.cloud
              spring-cloud-starter-loadbalancer
          
          
          
              org.springframework.cloud
              spring-cloud-starter-bootstrap
          
          
              org.springframework.boot
              spring-boot-starter-web
          
      

      2 编写服务下线方法

      @Component
      @Slf4j
      public class LosslessOfflineApi {
      
          @Resource
          private NacosConfigManager nacosConfigManager;
          @Resource
          private NacosServiceManager nacosServiceManager;
          @Resource
          private NacosDiscoveryProperties nacosDiscoveryProperties;
      
          /**
           * 服务下线
           *
           * @throws NacosException NacosException
           */
          public void offlineService() throws NacosException {
              log.info("触发服务下线 serviceName:[{}]", nacosDiscoveryProperties.getService());
              nacosServiceManager.nacosServiceShutDown();
              nacosConfigManager.getConfigService()
                      .publishConfig(NacosConstant.DATA_ID, NacosConstant.GROUP,
                              nacosDiscoveryProperties.getService() + NacosConstant.SPLIT + System.currentTimeMillis());
          }
      }

      此处需要注意的是: 使用nacosConfigManager.getConfigService().publishConfig 发布配置,此处更新配置中的 服务名+时间戳,如果只是更新服务名,则可能不会触发监听事件。

      3 监听配置变更,清除服务缓存

      使@NacosConfigListener注解生效

      1、引入配置

      
          com.alibaba.nacos
          nacos-spring-context
          1.1.1
      

      2、开启注解

      @Configuration
      @EnableNacos(globalProperties =
      	@NacosProperties(serverAddr = "${spring.cloud.nacos.config.server-addr}")
      )
      public class NacosConfiguration {
      }
      监听配置、清除缓存
      @Component
      @RequiredArgsConstructor
      @Slf4j
      public class ListenerConfigChange {
          @Resource
          private DefaultLoadBalancerCacheManager defaultLoadBalancerCacheManager;
          @Resource
          private NacosServiceManager nacosServiceManager;
          @Resource
          private NacosDiscoveryProperties nacosDiscoveryProperties;
          @Resource
          private NacosServiceDiscovery nacosServiceDiscovery;
          @Resource
          private NacosConfigManager nacosConfigManager;
      
          @NacosConfigListener(groupId = GROUP, dataId = DATA_ID)
          public void configChange(String config) {
              log.warn("==>接收到 无损服务下线 配置变更:[{}]", config);
              String serviceName = config.split(SPLIT)[0];
              log.info("需要无损下线的服务名:[{}]", serviceName);
      
              Cache cache = defaultLoadBalancerCacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
              if (null != cache) {
                  cache.evict(serviceName);
                  log.info("失效serviceName:[{}]的缓存", serviceName);
              }
          }
      }

      实现

      1 服务准备

      服务端口提供api备注
      nacos-lossless-gateway9001/consumer/**路由到consumer服务
      nacos-feign-consumer9002/fetchProviderServerInfo通过feign接口,获取provider服务的ip和port
      nacos-provider-90039003/shutdown从nacos server上下线服务,发布配置变更
      nacos-provider-90049004/shutdown从nacos server上下线服务,发布配置变更

      解释:
      1、通过gateway访问 http://localhost:9001/consumer/fetchProviderServerInfo将会返回provideripport信息。
      2、http://localhost:9003/shutdown 将会将自己从nacos server下线,并且操作 nacos config,变更配置文件的内容。
      3、gatewayconsumer监听到配置变更,更新服务的缓存,从而下次访问,不会访问到这个下线的服务。

      2 演示

      Spring Cloud Alibaba如何实现服务的无损下线功能

    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>