下面分析下Eureka Server的集群同步,先看关键代码

    1. registry.register(info, "true".equals(isReplication));

    其中关键字段 isReplication表示是否来自于集群同步
    假如现在有3个Eureka server集群,3个user集群服务,3个product集群服务。
    当user服务启动时向其中某个Eureka Server注册时,注册完毕后会将同步注册信息给其他的Eureka Server,为了防止产生死循环(也即第二个服务收到注册信息后又重复发给第一个服务器),即引入了isReplication字段。
    当User服务向Eureka Server注册时,isReplication为null,而服务器同步时isReplication为true。

    public void register(final InstanceInfo info, final boolean isReplication) {
            int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
            if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
                leaseDuration = info.getLeaseInfo().getDurationInSecs();
            }
            super.register(info, leaseDuration, isReplication);
            replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
        }
    

    集群同步

    private void replicateToPeers(Action action, String appName, String id,
                                      InstanceInfo info /* optional */,
                                      InstanceStatus newStatus /* optional */, boolean isReplication) {
            Stopwatch tracer = action.getTimer().start();
            try {
                if (isReplication) {
                    numberOfReplicationsLastMin.increment();
                }
                // If it is a replication already, do not replicate again as this will create a poison replication
                // isReplication 如果为true则直接返回,不用同步
                if (peerEurekaNodes == Collections.EMPTY_LIST || isReplication) {
                    return;
                }
    
                for (final PeerEurekaNode node : peerEurekaNodes.getPeerEurekaNodes()) {
                    // If the url represents this host, do not replicate to yourself.
                    if (peerEurekaNodes.isThisMyUrl(node.getServiceUrl())) {
                        // 如果没有集群也跳过同步,这种情况是没有Eureka Server集群
                        continue;
                    }
                    // 同步注册信息给其他服务器
                    replicateInstanceActionsToPeers(action, appName, id, info, newStatus, node);
                }
            } finally {
                tracer.stop();
            }
        }
    

    两种情况是不用同步

    • isReplication为true,即来自集群间同步请求
    • 只有一个单一的Eureka Server服务器