Hzero 服务注册监听组件的分析

有三种事件的类型:

  1. InstanceAddedEvent
  2. InstanceRemovedEvent
  3. ServiceChangedEvent
    一个事件发布器:AbstractEventListener
    它实现了ApplicationEventPublisherAware接口会注入进一个事件发布器,同时启动一个定时任务,每十秒执行一次,主要是通过连接注册中心去监听服务的上下线和改变,然后发布相应的事件,去触发监听该事件的的事件监听器。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.hzero.register.event.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.hzero.register.event.config.RegisterEventListenerProperties;
import org.hzero.register.event.event.InstanceAddedEvent;
import org.hzero.register.event.event.InstanceRemovedEvent;
import org.hzero.register.event.util.MD5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

public abstract class AbstractEventListener implements ApplicationEventPublisherAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEventListener.class);
    private DiscoveryClient discoveryClient;
    private RegisterEventListenerProperties properties;
    private ApplicationEventPublisher publisher;
    private ScheduledExecutorService scheduler;

    public AbstractEventListener() {
    }

    public void setDiscoveryClient(DiscoveryClient discoveryClient) {
        this.discoveryClient = discoveryClient;
    }

    public void setProperties(RegisterEventListenerProperties properties) {
        this.properties = properties;
    }

    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
        this.start();
    }

    private void start() {
        this.scheduler = new ScheduledThreadPoolExecutor(1, (r) -> {
            return new Thread(r, "register-event-scheduler");
        });
        this.scheduler.scheduleAtFixedRate(new AbstractEventListener.PollTask(), 0L, this.properties.getPollInterval(), TimeUnit.SECONDS);//定时任务
    }

    static class CustomPropertyPreFilter implements PropertyFilter {
        private String[] excludes;

        public CustomPropertyPreFilter(String... excludes) {
            this.excludes = excludes;
        }

        public boolean apply(Object object, String name, Object value) {
            String[] var4 = this.excludes;
            int var5 = var4.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String exclude = var4[var6];
                if (exclude == null) {
                    return true;
                }

                if (exclude.equals(name)) {
                    return false;
                }
            }

            return true;
        }
    }

    class PollTask implements Runnable {
        private AbstractEventListener.CustomPropertyPreFilter filter = new AbstractEventListener.CustomPropertyPreFilter(new String[]{"leaseInfo", "lastDirtyTimestamp", "lastUpdatedTimestamp"});
        private String cacheMD5 = "";
        private Set<String> serviceCache = new HashSet();
        private Map<String, Set<String>> instanceMapCache = new HashMap();
        private int serviceDownCount = 0;
        private Map<String, AtomicInteger> instanceDownCountMap = new HashMap();

        PollTask() {
        }

        public void run() {
            Set<String> services = this.serviceCache;
            Map<String, Set<String>> instanceMap = this.instanceMapCache;
            String MD5 = this.cacheMD5;

            try {
                long start = System.currentTimeMillis();
                services = new HashSet(AbstractEventListener.this.discoveryClient.getServices());
                if (((Set)services).isEmpty()) {
                    ++this.serviceDownCount;
                    if (this.serviceDownCount > AbstractEventListener.this.properties.getMaxServiceDownTimes()) {
                        this.publishServiceChangedEvent(this.serviceCache, (Set)services, instanceMap, new HashMap(0));//发布事件
                        return;
                    }

                    return;
                }

                this.serviceDownCount = 0;
                Map<String, ServiceInstance> serviceInstanceMap = new HashMap(16);
                instanceMap = (Map)((Set)services).stream().collect(Collectors.toMap((service) -> {
                    return service;
                }, (service) -> {
                    List<ServiceInstance> serviceInstances = AbstractEventListener.this.discoveryClient.getInstances(service);
                    AtomicInteger count = (AtomicInteger)this.instanceDownCountMap.computeIfAbsent(service, (k) -> {
                        return new AtomicInteger(0);
                    });
                    if (serviceInstances.isEmpty()) {
                        if (count.incrementAndGet() > AbstractEventListener.this.properties.getMaxInstanceDownTimes()) {
                            return Collections.emptySet();
                        } else {
                            Set<String> instances = (Set)this.instanceMapCache.get(service);
                            return instances == null ? Collections.emptySet() : instances;
                        }
                    } else {
                        count.set(0);
                        return (Set)serviceInstances.stream().map((serviceInstance) -> {
                            String json = JSON.toJSONString(serviceInstance, this.filter, new SerializerFeature[0]);
                            serviceInstanceMap.put(json, serviceInstance);
                            return json;
                        }).collect(Collectors.toSet());
                    }
                }));
                MD5 = MD5Util.encrypt(instanceMap.toString());
                if (this.cacheMD5.equals(MD5)) {
                    return;
                }

                this.publishServiceChangedEvent(this.serviceCache, (Set)services, instanceMap, serviceInstanceMap);
                long end2 = System.currentTimeMillis();
                AbstractEventListener.LOGGER.debug("getList and publish event cost : " + (end2 - start) + "ms");
            } catch (Throwable var12) {
                AbstractEventListener.LOGGER.error("pollTask throw exception :", var12);
            } finally {
                this.serviceCache = (Set)services;
                this.instanceMapCache = instanceMap;
                this.cacheMD5 = MD5;
            }

        }

        private void publishServiceChangedEvent(Set<String> oldServices, Set<String> newServices, Map<String, Set<String>> instanceMap, Map<String, ServiceInstance> serviceInstanceMap) {
            this.compareAndExecute(oldServices, newServices, this::publishInstanceRemovedEvent, this::publishInstanceAddedEvent);
            Iterator var5 = oldServices.iterator();

            while(var5.hasNext()) {
                String service = (String)var5.next();
                Set<String> oldInstanceSet = (Set)this.instanceMapCache.get(service);
                Set<String> newInstanceSet = (Set)instanceMap.get(service);
                if (!oldInstanceSet.equals(newInstanceSet)) {
                    this.compareAndExecute(oldInstanceSet, newInstanceSet, (removedInstanceSet) -> {
                        Iterator var4 = removedInstanceSet.iterator();

                        while(var4.hasNext()) {
                            String serviceInstanceJson = (String)var4.next();

                            try {
                                AbstractEventListener.this.publisher.publishEvent(new InstanceRemovedEvent(this, service, (ServiceInstance)serviceInstanceMap.get(serviceInstanceJson)));
                            } catch (Throwable var7) {
                                AbstractEventListener.LOGGER.error("publishEvent error", var7);
                            }
                        }

                    }, (addedInstanceSet) -> {
                        Iterator var4 = addedInstanceSet.iterator();

                        while(var4.hasNext()) {
                            String serviceInstanceJson = (String)var4.next();

                            try {
                                AbstractEventListener.this.publisher.publishEvent(new InstanceAddedEvent(this, service, (ServiceInstance)serviceInstanceMap.get(serviceInstanceJson)));
                            } catch (Throwable var7) {
                                AbstractEventListener.LOGGER.error("publishEvent error", var7);
                            }
                        }

                    });
                }
            }

        }

        private void compareAndExecute(Set<String> set1, Set<String> set2, FunctionX f1, FunctionX f2) {
            if (set1 == null) {
                set1 = new HashSet();
            }

            if (set2 == null) {
                set2 = new HashSet();
            }

            Set<String> oldTmp = new HashSet((Collection)set1);
            Set<String> newTmp = new HashSet((Collection)set2);
            oldTmp.removeAll((Collection)set2);
            newTmp.removeAll((Collection)set1);
            if (!oldTmp.isEmpty()) {
                f1.apply(oldTmp);
            }

            if (!newTmp.isEmpty()) {
                f2.apply(newTmp);
            }

        }

        private void publishInstanceAddedEvent(Set<String> addedServices) {
            Iterator var2 = addedServices.iterator();

            while(var2.hasNext()) {
                String service = (String)var2.next();
                List<ServiceInstance> serviceInstances = AbstractEventListener.this.discoveryClient.getInstances(service);
                Iterator var5 = serviceInstances.iterator();

                while(var5.hasNext()) {
                    ServiceInstance serviceInstance = (ServiceInstance)var5.next();

                    try {
                        AbstractEventListener.this.publisher.publishEvent(new InstanceAddedEvent(this, service, serviceInstance));
                    } catch (Throwable var8) {
                        AbstractEventListener.LOGGER.error("publishEvent error", var8);
                    }
                }
            }

        }

        private void publishInstanceRemovedEvent(Set<String> removedServices) {
            Iterator var2 = removedServices.iterator();

            while(var2.hasNext()) {
                String service = (String)var2.next();
                List<ServiceInstance> serviceInstances = AbstractEventListener.this.discoveryClient.getInstances(service);
                Iterator var5 = serviceInstances.iterator();

                while(var5.hasNext()) {
                    ServiceInstance serviceInstance = (ServiceInstance)var5.next();

                    try {
                        AbstractEventListener.this.publisher.publishEvent(new InstanceRemovedEvent(this, service, serviceInstance));
                    } catch (Throwable var8) {
                        AbstractEventListener.LOGGER.error("publishEvent error", var8);
                    }
                }
            }

        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值