Talk about eurekaservinitializerconfiguration of spring cloud.

  springcloud

Order

This article mainly studies eurekaservinitializerconfiguration of spring cloud.

EurekaServerInitializerConfiguration

spring-cloud-netflix-eureka-server-2.0.0.RC1-sources.jar! /org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java

@Configuration
public class EurekaServerInitializerConfiguration
        implements ServletContextAware, SmartLifecycle, Ordered {
    //......
    @Override
    public void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //TODO: is this class even needed now?
                    eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
                    log.info("Started Eureka Server");

                    publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
                    EurekaServerInitializerConfiguration.this.running = true;
                    publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
                }
                catch (Exception ex) {
                    // Help!
                    log.error("Could not initialize Eureka servlet context", ex);
                }
            }
        }).start();
    }

    @Override
    public void stop() {
        this.running = false;
        eurekaServerBootstrap.contextDestroyed(this.servletContext);
    }
}

Here, the contextInitialized method is called when start, and then the contextDestroyed method is called when stopping.

EurekaServerBootstrap.contextInitialized

spring-cloud-netflix-eureka-server-2.0.0.RC1-sources.jar! /org/springframework/cloud/netflix/eureka/server/EurekaServerBootstrap.java

    public void contextInitialized(ServletContext context) {
        try {
            initEurekaEnvironment();
            initEurekaServerContext();

            context.setAttribute(EurekaServerContext.class.getName(), this.serverContext);
        }
        catch (Throwable e) {
            log.error("Cannot bootstrap eureka server :", e);
            throw new RuntimeException("Cannot bootstrap eureka server :", e);
        }
    }

Here, initEurekaEnvironment initializes the environment configuration, with the emphasis on initEurekaServerContext

EurekaServerBootstrap.initEurekaServerContext

    protected void initEurekaServerContext() throws Exception {
        // For backward compatibility
        JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
                XStream.PRIORITY_VERY_HIGH);
        XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
                XStream.PRIORITY_VERY_HIGH);

        if (isAws(this.applicationInfoManager.getInfo())) {
            this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig,
                    this.eurekaClientConfig, this.registry, this.applicationInfoManager);
            this.awsBinder.start();
        }

        EurekaServerContextHolder.initialize(this.serverContext);

        log.info("Initialized server context");

        // Copy registry from neighboring eureka node
        int registryCount = this.registry.syncUp();
        this.registry.openForTraffic(this.applicationInfoManager, registryCount);

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

Eurekaservercontexthall.initialize (this.servercontext), registry.syncUp (), and then registry.openForTraffic are called here.

EurekaServerContextHolder.initialize(this.serverContext)

eureka-core-1.8.8-sources.jar! /com/netflix/eureka/EurekaServerContextHolder.java

/**
 * A static holder for the server context for use in non-DI cases.
 *
 * @author David Liu
 */
public class EurekaServerContextHolder {

    private final EurekaServerContext serverContext;

    private EurekaServerContextHolder(EurekaServerContext serverContext) {
        this.serverContext = serverContext;
    }

    public EurekaServerContext getServerContext() {
        return this.serverContext;
    }

    private static EurekaServerContextHolder holder;

    public static synchronized void initialize(EurekaServerContext serverContext) {
        holder = new EurekaServerContextHolder(serverContext);
    }

    public static EurekaServerContextHolder getInstance() {
        return holder;
    }
}

Mainly refers to EurekaServerContext for non-IOC containers

syncUp

eureka-core-1.8.8-sources.jar! /com/netflix/eureka/registry/PeerAwareInstanceRegistryImpl.java

    /**
     * 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;
    }

Here, the client obtains the instance information of another eureka server, and isReplication=true performs the registration of the instance.

openForTraffic

    Override
    public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
        // Renewals happen every 30 seconds and for a minute it should be a factor of 2.
        this.expectedNumberOfRenewsPerMin = count * 2;
        this.numberOfRenewsPerMinThreshold =
                (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());
        logger.info("Got {} instances from neighboring DS node", count);
        logger.info("Renew threshold is: {}", numberOfRenewsPerMinThreshold);
        this.startupTime = System.currentTimeMillis();
        if (count > 0) {
            this.peerInstancesTransferEmptyOnStartup = false;
        }
        DataCenterInfo.Name selfName = applicationInfoManager.getInfo().getDataCenterInfo().getName();
        boolean isAws = Name.Amazon == selfName;
        if (isAws && serverConfig.shouldPrimeAwsReplicaConnections()) {
            logger.info("Priming AWS connections for all replicas..");
            primeAwsReplicas(applicationInfoManager);
        }
        logger.info("Changing status to UP");
        applicationInfoManager.setInstanceStatus(InstanceStatus.UP);
        super.postInit();
    }

OpenForTraffic focuses on its own (eureka server) is identified as an UP state, and then the request can begin to be received.

eurekaServerBootstrap.contextDestroyed

    public void contextDestroyed(ServletContext context) {
        try {
            log.info("Shutting down Eureka Server..");
            context.removeAttribute(EurekaServerContext.class.getName());

            destroyEurekaServerContext();
            destroyEurekaEnvironment();

        }
        catch (Throwable e) {
            log.error("Error shutting down eureka", e);
        }
        log.info("Eureka Service is now shutdown...");
    }

    /**
     * Server context shutdown hook. Override for custom logic
     */
    protected void destroyEurekaServerContext() throws Exception {
        EurekaMonitors.shutdown();
        if (this.awsBinder != null) {
            this.awsBinder.shutdown();
        }
        if (this.serverContext != null) {
            this.serverContext.shutdown();
        }
    }

Destroy the context and environment variables here, notice that there is a this.serverContext! = null judgment, that is, if the serverContext has been destroyed, it will not be called again.

Summary

Eurekaservererinitializerconfiguration mainly implements the Lifecycle method, initializes servlet related context, and calls eurekaserverbotestrap.contextinitialized when start. In stop, eurekaServerBootstrap. ContextDestroyed is called by means of Eurekaserverbootstrap class. While EurekaServerContext was partially called in eurekaservercontext.

Eurekaserverbootstrap.contextinitializedhere are two important actions: registry.syncUp () and registry.openForTraffic

  • Sync up () obtains instance information from other eureka server, registers with this server, and then copies to other servers
  • Registry.openForTraffic () identifies its server as UP, indicating that it can begin receiving requests.

doc