Netflix Eureka - 服务端实例构造(注册相关)

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

服务端实例构造(注册相关)

// 第四步,注册相关

// 可以发现集群中节点的服务实例注册表
PeerAwareInstanceRegistry registry;
if (isAws(applicationInfoManager.getInfo())) { // 判断 实例信息 是不是 aws类型实例
    // 如果是 aws类型实例
    registry = new AwsInstanceRegistry(eurekaServerConfig,
            eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);
    awsBinder = new AwsBinderDelegate(eurekaServerConfig,
            eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
    awsBinder.start();
} else {
    // 如果不是 aws类型实例
    // 获取 PeerAwareInstanceRegistry 注册表
    // 服务配置信息、客户端配置信息、服务编码组件、客户端组件
    registry = new PeerAwareInstanceRegistryImpl(eurekaServerConfig,
            eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);
}

// 根据 注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(registry, eurekaServerConfig,
        eurekaClient.getEurekaClientConfig(), serverCodecs, applicationInfoManager);

// 获取 eureka服务上下文
serverContext = new DefaultEurekaServerContext(eurekaServerConfig, serverCodecs, registry
        , peerEurekaNodes, applicationInfoManager);

// 构建 EurekaServerContextHolder 持有 EurekaServerContext serverContext
EurekaServerContextHolder.initialize(serverContext);

// EurekaServerContext serverContext eureka服务上下文初始化
serverContext.initialize();
logger.info("Initialized server context");

// 从相邻的一个eureka server节点拷贝注册表的信息,如果拷贝失败,就找下一个
// Copy registry from neighboring eureka node
int registryCount = registry.syncUp();
registry.openForTraffic(applicationInfoManager, registryCount);

// 注册所有跟踪监控统计数据
// Register all monitoring statistics.
EurekaMonitors.registerAllStats();

构造 PeerAwareInstanceRegistry

Peer:多个同样的东西组成的一个集群。

Peers:peer就是集群中的一个实例

PeerAware:可以识别eureka server集群的

InstanceRegistry:服务实例注册表。存放所有的注册到这个eureka server上来的服务实例。

PeerAwareInstanceRegistry:可以感知eureka server集群的服务实例注册表,eureka client(作为服务实例)过来注册的注册表,而且这个注册表是可以感知到eureka server集群的。

Aware:假如有一个eureka server集群的话,这里包含了其他的eureka server中的服务实例注册表的信息的。

包含:服务配置信息、客户端配置信息、服务编码组件、客户端组件
// 服务配置信息、客户端配置信息、服务编码组件、客户端组件
registry = new PeerAwareInstanceRegistryImpl(eurekaServerConfig,
        eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);

构造PeerEurekaNodes

PeerEurekaNodes:eureka-server集群。

包含:注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
// 根据 注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(registry, eurekaServerConfig,
        eurekaClient.getEurekaClientConfig(), serverCodecs, applicationInfoManager);

PeerEurekaNode:表示指向该信息的对等节点应该从这个节点共享。

处理所有更新操作的复制同步,例如注册、更新、取消、过期和状态更改到它所代表的eureka节点。
/**
 * The <code>PeerEurekaNode</code> represents a peer node to which information
 * should be shared from this node.
 *
 * <p>
 * This class handles replicating all update operations like
 * <em>Register,Renew,Cancel,Expiration and Status Changes</em> to the eureka
 * node it represents.
 * <p>
 *
 * @author Karthik Ranganathan, Greg Kim
 *
 */
public class PeerEurekaNode {

}

构造EurekaServerContext

EurekaServerContext:当前eureka server的服务器上下文,包含服务器需要的所有的数据。

EurekaServerContextHolder.initialize(serverContext);
将EurekaServerContext放在holder中,要使用EurekaServerContext,直接从这个holder中获取。

EurekaServerContext.initialize()

@PostConstruct
@Override
public void initialize() throws Exception {
    logger.info("Initializing ...");
    // 启动 eureka-server 集群
    peerEurekaNodes.start();
    // 基于eureka server集群的信息,来初始化注册表
    registry.init(peerEurekaNodes);
    logger.info("Initialized");
}

peerEurekaNodes.start();

启动eureka server集群,更新eureka server集群的信息,让当前的eureka server感知到所有的其他的eureka server。

定时调度任务,更新eureka server集群的信息。

/**
 * 启动eureka server集群
 */
public void start() {
    taskExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r, "Eureka-PeerNodesUpdater");
            thread.setDaemon(true);
            return thread;
        }
    });
    try {
        // 更新 eureka-server 集群信息,让当前的eureka server感知到所有的其他的eureka server
        updatePeerEurekaNodes(resolvePeerUrls());
        
        // 定时更新eureka server集群的信息的任务
        Runnable peersUpdateTask = new Runnable() {
            @Override
            public void run() {
                try {
                    updatePeerEurekaNodes(resolvePeerUrls());
                } catch (Throwable e) {
                    logger.error("Cannot update the replica Nodes", e);
                }

            }
        };
        // 定时更新eureka server集群的信息。
        taskExecutor.scheduleWithFixedDelay(peersUpdateTask,
                serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
                serverConfig.getPeerEurekaNodesUpdateIntervalMs(), TimeUnit.MILLISECONDS);
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
    for (PeerEurekaNode node : peerEurekaNodes) {
        logger.info("Replica node URL:  " + node.getServiceUrl());
    }
}

registry.init(peerEurekaNodes);

  • 基于eureka server集群的信息,初始化注册表
  • 将eureka server集群中所有的eureka server的注册表信息都抓取过来,合并到本地的注册表里去,
  • 交换eureka server集群之间的注册表信息,保持同步
@Override
public void init(PeerEurekaNodes peerEurekaNodes) throws Exception {
    this.numberOfReplicationsLastMin.start();
    this.peerEurekaNodes = peerEurekaNodes;
    initializedResponseCache();
    scheduleRenewalThresholdUpdateTask();
    initRemoteRegionRegistry();

    try {
        Monitors.registerObject(this);
    } catch (Throwable e) {
        logger.warn("Cannot register the JMX monitor for the InstanceRegistry :", e);
    }
}

registry.syncUp();

从相邻的一个eureka server节点拷贝注册表的信息,如果拷贝失败,就找下一个。

/**
 * Populates the registry information from a peer eureka node. This
 * operation fails over to other nodes until the list is exhausted if the
 * communication fails.
 */
@Override
public int syncUp() {
    // Copy entire entry from neighboring DS node
    int count = 0;

    for (int i = 0; ((i < serverConfig.getRegistrySyncRetries()) && (count == 0)); i++) {
        if (i > 0) {
            try {
                Thread.sleep(serverConfig.getRegistrySyncRetryWaitMs());
            } catch (InterruptedException e) {
                logger.warn("Interrupted during registry transfer..");
                break;
            }
        }
        Applications apps = eurekaClient.getApplications();
        for (Application app : apps.getRegisteredApplications()) {
            for (InstanceInfo instance : app.getInstances()) {
                try {
                    if (isRegisterable(instance)) {
                        register(instance, instance.getLeaseInfo().getDurationInSecs(), true);
                        count++;
                    }
                } catch (Throwable t) {
                    logger.error("During DS init copy", t);
                }
            }
        }
    }
    return count;
}

EurekaMonitors.registerAllStats();

注册所有跟踪监控统计数据

// Register all monitoring statistics.
EurekaMonitors.registerAllStats();

猜你喜欢

转载自juejin.im/post/7114523821448626212
今日推荐