温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2023-03-13 15:59:44 来源:亿速云 阅读:121 作者:iii 栏目:开发技术

今天小编给大家分享一下Spring Cloud Alibaba如何实现服务的无损下线功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    解决方案

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

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

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

    2 解决思路

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

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

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

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

    部分实现代码

    1 引入jar

    <dependencies>
    	<!-- 服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- nacos 配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- 引入这个是为了使 @NacosConfigListener 注解生效 -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-spring-context</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- 负载均衡组件 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- 使bootstrap.yaml中的配置生效 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    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、引入配置

    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-spring-context</artifactId>
        <version>1.1.1</version>
    </dependency>

    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如何实现服务的无损下线功能

    以上就是“Spring Cloud Alibaba如何实现服务的无损下线功能”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI