All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.df.restypass.lb.server.AbstractDiscoveryServerContext Maven / Gradle / Ivy

The newest version!
package com.github.df.restypass.lb.server;

import com.github.df.restypass.util.CommonTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * SpringCloud服务发现抽象容器
 * Created by darrenfu on 17-8-17.
 */
public abstract class AbstractDiscoveryServerContext implements ServerContext {

    private static final Logger log = LoggerFactory.getLogger(AbstractDiscoveryServerContext.class);

    /**
     * server缓存
     */
    private volatile ConcurrentHashMap> instancesMap = new ConcurrentHashMap<>();

    /**
     * 更新的数据存储map
     */
    private volatile ConcurrentHashMap> updatedInstancesMap = new ConcurrentHashMap<>();

    /**
     * 数据是否更新的标志
     */
    private AtomicBoolean updated = new AtomicBoolean(false);


    /**
     * update task是否启动
     */
    private AtomicBoolean taskStarted = new AtomicBoolean(false);

    public AbstractDiscoveryServerContext() {
        startUpdateTask();
    }


    @Override
    public List getAllServiceName() {
        return instancesMap.keySet().stream().collect(Collectors.toList());
    }

    @Override
    public List getAllServerList() {
        checkStatus();
        List instances = new LinkedList<>();
        for (Map.Entry> entry : instancesMap.entrySet()) {
            if (entry.getValue() != null && entry.getValue().size() > 0) {
                instances.addAll(entry.getValue());
            }
        }
        return instances;
    }

    @Override
    public List getServerList(String serviceName) {
        checkStatus();
        return instancesMap.getOrDefault(serviceName, Collections.EMPTY_LIST);
    }

    @Override
    public void refreshServerList() {
        updateServer();
    }

    @Override
    public void refreshServerList(String serviceName) {
        updateServer();
    }

    @Override
    public List setServerList(List instanceList) {
        throw new UnsupportedOperationException("基于SpringCloud自动服务发现,不支持手动设置服务实例");
    }

    @Override
    public List addServerList(List instanceList) {
        throw new UnsupportedOperationException("基于SpringCloud自动服务发现,不支持手动设置服务实例");
    }


    /**
     * 检查server是否更新
     */
    protected void checkStatus() {
        if (updated.compareAndSet(true, false)) {
            this.instancesMap = updatedInstancesMap;
        }
    }


    /**
     * 定时任务
     */
    private void startUpdateTask() {
        if (taskStarted.compareAndSet(false, true)) {
            Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(() -> {
                try {
                    if (isDiscoveryEnabled()) {
                        updated.set(false);
                        updateServer();
                        updated.set(true);
                    }
                } catch (Exception ex) {
                    log.warn("更新server发生错误:" + ex.getMessage(), ex);
                }

            }, 3 * 1000, 20 * 1000, TimeUnit.MILLISECONDS);
        }
    }


    /**
     * 更新server
     */
    protected void updateServer() {
        List services = getServiceNames();
        this.updatedInstancesMap = new ConcurrentHashMap<>();
        List serviceList = new ArrayList<>();
        serviceList.addAll(services);
        serviceList.addAll(UrlServerContext.getInstance().getAllServiceName());
        serviceList = serviceList.stream().distinct().collect(Collectors.toList());
        for (String service : serviceList) {
            try {
                List instances = Collections.EMPTY_LIST;
                // 先尝试获取URL配置的服务
                List urlInstanceList = UrlServerContext.getInstance().getServerList(service);
                if (CommonTools.isNotEmpty(urlInstanceList)) {
                    instances = UrlServerContext.getInstance().getServerList(service);
                } else {
                    instances = getServiceInstances(service);
                }
                updatedInstancesMap.put(service, instances);

            } catch (Exception ex) {
                log.warn("更新server:{}发生错误:{}", service, ex.getMessage(), ex);
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("刷新server instances:{}", updatedInstancesMap);
        }
    }


    protected abstract boolean isDiscoveryEnabled();

    protected abstract List getServiceNames();

    protected abstract List getServiceInstances(String serviceName);


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy