文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Cloud Alibaba实现服务的无损下线功能(案例讲解)

2023-03-13 14:23

关注

1、背景

最近用到了Spring Cloud Alibaba开发微服务,在开发的过程中发现,当我们的服务上线下线的时候,我们的Spring Cloud Gateway需要一段时间才能感知到,那么有没有办法能够让服务立即感知到呢?答案是可以的

此种实现方式是我自己记录下,目前未在生产环境中使用,此处记录是为了以后遇到此种场景,可以找到一种解决方案

2、解决方案

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

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

2.2 解决思路

3、部分实现代码

3.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>

3.2 编写服务下线方法

@Component
@Slf4j
public class LosslessOfflineApi {

    @Resource
    private NacosConfigManager nacosConfigManager;
    @Resource
    private NacosServiceManager nacosServiceManager;
    @Resource
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    
    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.3 监听配置变更,清除服务缓存

3.3.1 使@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 {
}

3、注解生效参考文档

https://github.com/nacos-group/nacos-spring-project
https://github.com/alibaba/spring-cloud-alibaba/issues/458

3.3.2 监听配置、清除缓存

@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);
        }
    }
}

4、实现

4.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监听到配置变更,更新服务的缓存,从而下次访问,不会访问到这个下线的服务。

4.2 演示

5、完整代码

https://gitee.com/huan1993/spring-cloud-alibaba-parent/tree/master/nacos-lossless-offline

6、参考链接

1、https://github.com/nacos-group/nacos-spring-project
2、https://github.com/alibaba/spring-cloud-alibaba/issues/458

到此这篇关于Spring Cloud Alibaba实现服务的无损下线功能的文章就介绍到这了,更多相关Spring Cloud Alibaba无损下线内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯