sequence
In this paper, we study the spring cloud EurekaServerInitializerConfiguration
EurekaServerInitializerConfiguration
Spring – the cloud – netflix – eureka – server – 2.0.0. RC1 – sources. The 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); }}Copy the code
The contextDestroyed method is called when the contextInitialized method is started and the contextDestroyed method is called when the contextDestroyed method is stopped
EurekaServerBootstrap.contextInitialized
Spring – the cloud – netflix – eureka – server – 2.0.0. RC1 – sources. The 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); }}Copy the code
InitEurekaEnvironment initializes the environment configuration, focusing 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();
}
Copy the code
Call the EurekaServerContextHolder here. The initialize (enclosing serverContext), registry. SyncUp (), then the registry. OpenForTraffic
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() {
returnholder; }}Copy the code
The main reference is to the 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;
}
Copy the code
Obtain the instance information of another Eureka Server from the client, and then register the instance with isReplication=true
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();
}
Copy the code
OpenForTraffic basically identifies itself (eureka Server) as UP and can start receiving requests.
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();
}
}
Copy the code
Here context and environment variables are destroyed. Note that there is this.serverContext! = null, that is, if serverContext has been destroyed, it will not be called again.
summary
EurekaServerInitializerConfiguration mainly implements the Lifecycle methods, initialize the servlet context, When start to call EurekaServerBootstrap contextInitialized, at the time of the stop calling EurekaServerBootstrap. ContextDestroyed, All with the help of the eurekaServerBootstrap class. The eurekaServerBootstrap part calls the EurekaServerContext.
EurekaServerBootstrap. ContextInitialized. There are two important action registry syncUp () and registry. OpenForTraffic
- Registry.syncup () gets instance information from other Eureka servers, registers it with this server, and then copies it to other servers
- Registry.openfortraffic () identifies its server as UP, indicating that it can start receiving requests
doc
- Understanding Eureka Peer to Peer Communication