一、版本介绍

Nacos: 1.3.1
SpringCloud: 2021.0.2
SpringCloud gateway: 3.1.2

二、背景

  1. 微服务下线后,网关存在短时间内转发失效服务,导致前端访问异常
  2. 微服务上线后,网关没有及时刷新本地缓存的服务,导致前端可能找不到服务实例
  3. nacos的主动推送实例变化比网关自己拉取要及时的多

三、网关增加订阅微服务实例变化的代码

import static org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;

import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.listener.Subscriber;
import com.alibaba.nacos.common.utils.JacksonUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 订阅nacos通知
 * 接收nacos推送的微服务上下线实例信息
 * @author
 *
 */
@Component
@Slf4j
public class NacosInstancesChangeEventListener extends Subscriber<InstancesChangeEvent> {
	@Resource
	private CacheManager defaultLoadBalancerCacheManager;
    @PostConstruct
    public void registerToNotifyCenter(){
        NotifyCenter.registerSubscriber(this);
    }
	@Override
	public void onEvent(InstancesChangeEvent event) {
		log.info("SpringCloud Gateway 接收微服务实例刷新事件:{}, 开始刷新本地存储的微服务实例信息的缓存", JacksonUtils.toJson(event));
		Cache cache = defaultLoadBalancerCacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
		if (cache != null) {
			cache.evict(event.getServiceName());
		}
		log.info("SpringCloud Gateway 实例刷新完成");
	}

	@Override
	public Class<? extends com.alibaba.nacos.common.notify.Event> subscribeType() {
		return InstancesChangeEvent.class;
	}
}

一级增加配置使订阅事件生效

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 默认false,开启后可以通过ip:port/服务名称/接口地址进行服务转发
          interval: 10000 # 设置定时拉取服务信息的时间间隔为10

此处配置注意点:

1、如果cloud.gateway.discovery.locator.enabled 设置为false,那么订阅程序将收不到nacas推送的消息
2、如果不需要定时拉取,可以把interval的设置去掉

Logo

一起探索未来云端世界的核心,云原生技术专区带您领略创新、高效和可扩展的云计算解决方案,引领您在数字化时代的成功之路。

更多推荐