当前位置: 首页 > 后端技术 > Java

SpringCloudAlibaba实现服务无损离线功能

时间:2023-04-01 16:20:13 Java

1。背景最近使用SpringCloudAlibaba开发微服务。在开发过程中,我们发现当我们的服务上线或者下线的时候,我们的SpringCloudGateway需要一段时间去感知,那么有没有办法让服务立刻感知到呢?答案是肯定的。这个实现方法是我自己记录的,目前没有在生产环境中使用。这里的记录是为了以后遇到这种情况。可以找到解决方案2.解决方案2.1通过负载均衡组件查找可用的服务信息经过调试,我们从上图可以看出,我们获取的是可用的服务实例信息,是从缓存中获取的,所以如果我们清除服务下线后这个服务的缓存信息,那么下次在这个服务获取的信息是最新的,问题就解决了。2.2解决方案服务提供者或消费者同时监听SpringCloudConfig中的某个配置文件。比如无损文件服务下线时,第一步是从nacos中让实例本身下线。第二步:通过api更新无损文件中的内容,记录下线服务的服务名称并添加时间戳。消费者或网关监听无损配置文件的变化,获取服务名,然后清除服务名对应的缓存。3.部分实现代码3.1导入jarcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-starter-alibaba-nacos-configcom.alibaba.nacosnacos-spring-context1.1.1org.projectlomboklombokorg.springframework.cloudspring-cloud-starter-loadbalancerorg.springframework.云spring-cloud-starter-bootstraporg.springframework.bootspring-boot-starter-web3.2编写服务下线方法@Component@Slf4jpublicclassLosslessOfflineApi{@ResourceprivateNacosConfigManagernacosConfigManager;@ResourceprivateNacosServiceManagernacosServiceManager;@ResourceprivateNacosDiscoveryPropertiesnacosDiscoveryProperties;/***服务下线**@throwsNacosExceptionNacosException*/publicvoidofflineService()throwsNacosException{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.导入配置com.alibaba.nacosnacos-spring-context1.1.12.开启注解@Configuration@EnableNacos(globalProperties=@NacosProperties(serverAddr="${spring.cloud.nacos.config.server-addr}"))publicclassNacosConfiguration{}3.注解生效参考文档@RequiredArgsConstructor@Slf4jpublic类ListenerConfigChange{@ResourceprivateDefaultLoadBalancerCacheManagerdefaultLoadBalancerCacheManager;@ResourceprivateNacosServiceManagernacosServiceManager;@ResourceprivateNacosDiscoveryPropertiesnacosDiscoveryProperties;@ResourceprivateNacosServiceDiscoverynacosServiceDiscovery;@ResourceprivateNacosConfig管理器nacosConfigManager;@NacosConfigListener(groupId=GROUP,dataId=DATA_ID)publicvoidconfigChange(Stringconfig){log.warn("==>收到无损服务离线配置变更:[{}]",config);StringserviceName=config.split(SPLIT)[0];log.info("需要无损离线的服务名称:[{}]",serviceName);缓存cache=defaultLoadBalancerCacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);if(null!=cache){cache.evict(serviceName);log.info("使服务名称无效:[{}]的缓存",serviceName);}}}4.实现4.1服务准备服务端口提供api备注nacos-lossless-gateway9001/consumer/**通过feign接口路由到消费者服务nacos-feign-consumer9002/fetchProviderServerInfo获取提供者服务的ip和端口.nacos-provider-90039003/shutdown从nacos服务器注销下线,发布配置变更nacos-provider-90049004/shutdown从nacos服务器上线服务,发布配置变更说明:1.访问http://localhost:9001/通过网关获取consumer/fetchProviderServerInfo,会返回provider的ip和port信息2、http://localhost:9003/shutdown会自己退出nacos服务器,运行nacosconfig修改配置文件的内容。3、网关和消费者监听配置变化,更新服务的缓存,这样下次访问时就不会再访问这个离线服务了。4.2Demo5、完整代码https://gitee.com/huan1993/spring-cloud-alibaba-parent/tree/master/nacos-lossless-offline6、参考链接1、https://github.com/nacos-group/nacos-spring-project2,https://github.com/alibaba/spring-cloud-alibaba/issues/458