Ribbon监听Nacos注册中心服务变化并刷新服务地址列表

com.netflix.loadbalancer.DynamicServerListLoadBalancer
中 updateListOfServers()方法 用于从注册中心刷新服务列表 
@VisibleForTesting
    public void updateListOfServers() {
        List<T> servers = new ArrayList<T>();
        if (serverListImpl != null) {
            servers = serverListImpl.getUpdatedListOfServers();
            LOGGER.debug("List of Servers for {} obtained from Discovery client: {}",
                    getIdentifier(), servers);

            if (filter != null) {
                servers = filter.getFilteredListOfServers(servers);
                LOGGER.debug("Filtered List of Servers for {} obtained from Discovery client: {}",
                        getIdentifier(), servers);
            }
        }
        updateAllServerList(servers);
    }

封装在 ServerListUpdater.UpdateAction对象中
 protected final ServerListUpdater.UpdateAction updateAction = new ServerListUpdater.UpdateAction() {
        @Override
        public void doUpdate() {
            updateListOfServers();
        }
    };
UpdateAction 可以从 PollingServerListUpdater 中拿到,所以需要自定义 ServerListUpdater 类继承  PollingServerListUpdater ,注入并替换默认的PollingServerListUpdater
 @Bean
    @ConditionalOnMissingBean
    public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {
        return new PollingServerListUpdater(config);
    }

    @Bean
    @ConditionalOnMissingBean
    public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerList<Server> serverList, ServerListFilter<Server> serverListFilter, IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
        return (ILoadBalancer)(this.propertiesFactory.isSet(ILoadBalancer.class, this.name) ? (ILoadBalancer)this.propertiesFactory.get(ILoadBalancer.class, config, this.name) : new ZoneAwareLoadBalancer(config, rule, ping, serverList, serverListFilter, serverListUpdater));
    }

 

 具体操作如下:

@Component("ribbonServerListUpdater")
public class MyPollingServerListUpdater extends PollingServerListUpdater {

    private UpdateAction updateAction;

    @Override
    public synchronized void start(UpdateAction updateAction) {

        this.updateAction = updateAction;

        super.start(updateAction);

    }


    public UpdateAction getUpdateAction(){

        return updateAction;

    }
}

定义Nacos监听器并调用 updateAction.doUpdate() 方法

@Component
public class ServerStatusListner {

    @Autowired
    private MyPollingServerListUpdater myListUpdater;

    @Value("${spring.cloud.nacos.discovery.namespace}")
    private String namespace;
    @Value("${spring.cloud.nacos.discovery.server-addr}")
    private String serverAddr;

    @PostConstruct
    public void init() throws Exception {

        //初始化监听服务上下线

        Properties properties = System.getProperties();
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);

        NamingService naming = NamingFactory.createNamingService(properties);

        List<String> serviceNames = new ArrayList<>();
        // 要监听的服务名称
        serviceNames.add("SVC1");
        serviceNames.add("SVC2");
        serviceNames.stream().forEach(serviceName->{

            try {

                naming.subscribe(serviceName, (event -> {
                    //通知ribbon更新服务列表
                    ServerListUpdater.UpdateAction updateAction = myListUpdater.getUpdateAction();

                    if (updateAction != null){
                        updateAction.doUpdate();
                    }

                    NamingEvent namingEvent = (NamingEvent) event;

                    List<Instance> instances = namingEvent.getInstances();

                    String name = namingEvent.getServiceName();

                    if(instances != null && !instances.isEmpty()){

                        instances.stream().forEach(instance -> {

                            System.out.println("服务"+name+":"+instance);
                        });
                    }else {
                        System.out.println("服务"+name+"列表为空");
                    }
                }));

            } catch (NacosException e) {
                e.printStackTrace();
            }
        });
    }
}

 



 

posted @ 2021-02-05 15:23  悦悦耶  阅读(1397)  评论(0编辑  收藏  举报