之前我们分析了eureka cilent和eureka server的配置,下面我们来分析一下eureka的启动流程。先来介绍一个类EurekaBootStrap,这个类实现了ServletContextListener接口,在servlet容器启动时初始化EurekaServer。来看一下具体的实现
public void contextInitialized(ServletContextEvent event) {
try {
// 初始化 Eureka-Server 配置环境
initEurekaEnvironment();
// 初始化 Eureka-Server 上下文
initEurekaServerContext();
ServletContext sc = event.getServletContext();
sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
} catch (Throwable e) {
logger.error("Cannot bootstrap eureka server :", e);
throw new RuntimeException("Cannot bootstrap eureka server :", e);
}
}
看下initEurekaEnvironment方法
protected void initEurekaEnvironment() throws Exception {
logger.info("Setting the eureka configuration..");
// 设置配置文件的数据中心
String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);
if (dataCenter == null) {
logger.info("Eureka data center value eureka.datacenter is not set, defaulting to default");
ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT);
} else {
ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter);
}
// 设置配置文件的环境
String environment = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT);
if (environment == null) {
ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
logger.info("Eureka environment value eureka.environment is not set, defaulting to test");
}
}
再看下initEurekaServerContext方法
protected void initEurekaServerContext() throws Exception {
// 【2.2.1】创建 Eureka-Server 配置
EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();
// 【2.2.2】Eureka-Server 请求和响应的数据兼容
// For backward compatibility
JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
// 【2.2.3】创建 Eureka-Server 请求和响应编解码器
logger.info("Initializing the eureka client...");
logger.info(eurekaServerConfig.getJsonCodecName());
ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
// 【2.2.4】创建 Eureka-Client
ApplicationInfoManager applicationInfoManager;
if (eurekaClient == null) {
EurekaInstanceConfig instanceConfig = isCloud(ConfigurationManager.getDeploymentContext())
? new CloudInstanceConfig()
: new MyDataCenterInstanceConfig();
applicationInfoManager = new ApplicationInfoManager(
instanceConfig, new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
} else {
applicationInfoManager = eurekaClient.getApplicationInfoManager();
}
// 【2.2.5】创建 应用实例信息的注册表
PeerAwareInstanceRegistry registry;
if (isAws(applicationInfoManager.getInfo())) { // AWS 相关,跳过
registry = new AwsInstanceRegistry(
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
eurekaClient
);
awsBinder = new AwsBinderDelegate(eurekaServerConfig, eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
awsBinder.start();
} else {
registry = new PeerAwareInstanceRegistryImpl(
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
eurekaClient
);
}
// 【2.2.6】创建 Eureka-Server 集群节点集合
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
registry,
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
applicationInfoManager
);
// 【2.2.7】创建 Eureka-Server 上下文
serverContext = new DefaultEurekaServerContext(
eurekaServerConfig,
serverCodecs,
registry,
peerEurekaNodes,
applicationInfoManager
);
// 【2.2.8】初始化 EurekaServerContextHolder
EurekaServerContextHolder.initialize(serverContext);
// 【2.2.9】初始化 Eureka-Server 上下文
serverContext.initialize();
logger.info("Initialized server context");
// 【2.2.10】从其他 Eureka-Server 拉取注册信息
// Copy registry from neighboring eureka node
int registryCount = registry.syncUp();
registry.openForTraffic(applicationInfoManager, registryCount);
// 【2.2.11】注册监控
// Register all monitoring statistics.
EurekaMonitors.registerAllStats();
}
创建EurekaServer集群结点集合
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
registry,
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
applicationInfoManager
);
创建DefaultEurekaServerContext
serverContext = new DefaultEurekaServerContext(
eurekaServerConfig,
serverCodecs,
registry,
peerEurekaNodes,
applicationInfoManager
);
注册监控
EurekaMonitors.registerAllStats();
EurekaServer启动流程就完成了。
EurekaBootStrap就分析到这里了。