gateway+nacos秒级上下线

gateway+nacos秒级上下线

spring cloud gateway和nacos是我们常用的组件,如果不做处理,服务启动或停止后在gateway上并不会立即上线或者下线。带来的问题就是,部署服务的时候,要把新的服务启动,等待gateway更新,再把老的服务下线,再次等待gateway更新,最后停止老服务。很麻烦,体验很差。

究其原因,大概率是gateway里对服务做了缓存,但是服务上下线后没有触发缓存的更新,直到gateway自己检查服务在线状态才更新了缓存。既然它没有更新,那就让它更新就行

1.版本说明

spring-boot版本: 2.3.12.RELEASE
spring-cloud版本: Hoxton.SR12
nacos版本: 2.2.9.RELEASE

解决过程中查了不少资料,能成功的不多,可能是版本不一样造成的。

2.在gateway创建服务监听者

在gateway里创建监听者,当服务上、下线时更新

ServiceListenerComponent.java

@Component
public class ServiceListenerComponent {

    @Resource
    private NacosDiscoveryProperties discoveryProperties;
    @Resource
    private NacosServiceDiscovery serviceDiscovery;
    @Resource
    private ServiceEventListener eventListener;
    private volatile NamingService naming;
    protected static volatile List<String> services = new ArrayList<>();
    protected volatile long time = 30000;
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    public void init(){
        try {
            naming = discoveryProperties.namingServiceInstance();
            services = serviceDiscovery.getServices();
            services.forEach(this::addServiceListener);
            new Thread(()->{
                for (;;){
                    try {
                        Thread.sleep(time);
                        List<String> newServices = serviceDiscovery.getServices();
                        for (String service : newServices){
                            if (!services.contains(service)){
                                services.add(service);
                                addServiceListener(service);
                            }
                        }
                    }catch (Exception e){
                        logger.error("发生错误!", e);
                    }
                }
            }).start();

        }catch (Exception e){
            logger.error("发生错误!", e);
        }

    }

    /**
     * 新的服务添加监听
     * @param serviceName
     */
    public void addServiceListener(String serviceName){
        try {
            naming.subscribe(serviceName, eventListener);
        }catch (Exception e){
            logger.error("发生错误!", e);
        }
    }

}

ServiceEventListener.java

@Component
public class ServiceEventListener implements EventListener {
    @Resource
    private NamedContextFactory factory;

    /**
     * 监听服务的变更并销毁原有的服务列表
     * @param event
     */
    @Override
    public void onEvent(Event event) {
        if (event instanceof NamingEvent){
            //销毁服务上下文
            factory.destroy();
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值