1 、 开启Eureka Server
@EnableEurekaServer
注解开启eureka server
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer {
}
@Import EurekaServerMarkerConfiguration
注入一个配置类EurekaServerMarkerConfiguration, 只做了new Marker的标记,没有启动逻辑的处理。
@Configuration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}
2、 真正的Eureka Server配置类 EurekaServerAutoConfiguration
该类通过Spring boot的自动装配机制进行初始化<link> spring boot 自动装配机制实现原理 SpringFactoryLoader <link>
EurekaServerAutoConfiguration
在spring.factories文件中进行配置,由spring boot的自动装配机制进行加载。
@Configuration
@Import(EurekaServerInitializerConfiguration.class)
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
@PropertySource("classpath:/eureka/server.properties")
public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter {
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
表示在spring容器
有Marker实例的时候,才会加载当前这个Bean(EurekaServerAutoConfiguration )。Marker实例是由上面的@EnableEurekaServer
注解引入并实例化的,这也是@EnableEurekaServer注解的意义所在。
@EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class })
加载properties配置EurekaDashboardProperties定义eureka dashboard的属性(访问路径,是否开启)。InstanceRegistryProperties 服务注册一些属性。
@PropertySource("classpath:/eureka/server.properties")
加载server.properties配置文件
具体方法
// 创建并加载EurekaServerConfig的实现类EurekaServerConfigBean,主要维护Eureka-server的配置信息
@Configuration
protected static class EurekaServerConfigBeanConfiguration {
@Bean
@ConditionalOnMissingBean
public EurekaServerConfig eurekaServerConfig(EurekaClientConfig clientConfig) {
EurekaServerConfigBean server = new EurekaServerConfigBean();
if (clientConfig.shouldRegisterWithEureka()) {
// Set a sensible default if we are supposed to replicate
server.setRegistrySyncRetries(5);
}
return server;
}
}
// 初始化EurekaController,提供Eureka控制台接口
@Bean
@ConditionalOnProperty(prefix = "eureka.dashboard", name = "enabled", matchIfMissing = true)
public EurekaController eurekaController() {
return new EurekaController(this.applicationInfoManager);
}
// PeerAwareInstanceRegistry接收客户端注册等请求
@Bean
public PeerAwareInstanceRegistry peerAwareInstanceRegistry(
ServerCodecs serverCodecs) {
this.eurekaClient.getApplications(); // force initialization
return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig,
serverCodecs, this.eurekaClient,
this.instanceRegistryProperties.getExpectedNumberOfRenewsPerMin(),
this.instanceRegistryProperties.getDefaultOpenForTrafficCount());
}
// 配置服务节点信息,这里的作用主要是为了配置Eureka的peer节点
@Bean
@ConditionalOnMissingBean
public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry,
ServerCodecs serverCodecs) {
return new RefreshablePeerEurekaNodes(registry, this.eurekaServerConfig,
this.eurekaClientConfig, serverCodecs, this.applicationInfoManager);
}
//EurekaServer的上下文
@Bean
public EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs,
PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) {
return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs,
registry, peerEurekaNodes, this.applicationInfoManager);
}
//EurekaServerBootstrap 初始化
@Bean
public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,
EurekaServerContext serverContext) {
return new EurekaServerBootstrap(this.applicationInfoManager,
this.eurekaClientConfig, this.eurekaServerConfig, registry,
serverContext);
}
// Register the Jersey filter
// eureka server 的rest接口通过此实现,* 具体如何实现的 *
@Bean
public FilterRegistrationBean jerseyFilterRegistration(
javax.ws.rs.core.Application eurekaJerseyApp) {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new ServletContainer(eurekaJerseyApp));
bean.setOrder(Ordered.LOWEST_PRECEDENCE);
bean.setUrlPatterns(
Collections.singletonList(EurekaConstants.DEFAULT_PREFIX + "/*"));
return bean;
}
Eureka server有哪些配置,配置文件可配置哪些:
spring-configuration-metadata.json
属性配置类和配置属性的对应关系,从此文件可以查看配置属性的全貌,比如:
{
"sourceType": "org.springframework.cloud.netflix.eureka.server.EurekaDashboardProperties",
"defaultValue": true,
"name": "eureka.dashboard.enabled",
"description": "Flag to enable the Eureka dashboard. Default true.",
"type": "java.lang.Boolean"
}
spring-autoconfigure-metadata.properties
这个文件有什么用?在SpringBoot的自动装配机制中,在配置类EurekaServerAutoConfiguration加载过程中会读取此文件,此文件中记录了与自动装配相关的配置类。
3、 EurekaServerInitializerConfiguration 在 @EurekaServerAutoConfiguration 被Import。Eureka Server启动。
@Configuration
public class EurekaServerInitializerConfiguration
implements ServletContextAware, SmartLifecycle, Ordered {
EurekaServerInitializerConfiguration实现了SmartLifecle接口的start方法,此方法在Spring容器初始化过程中会调用。* Spring容器初始化过程中如何调用的? *
实现 ServletContextAware接口获取ServletContext。 * Spring容器初始化过程中如何调用的? *
@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();
}
contextInitialized
方法中进行了一系列初始化工作,Eureka Server启动后还发布了两个事件,基于事件驱动的方式可以进行扩展。
EurekaServerBootstrap
public void contextInitialized(ServletContext context)
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中设置serverContext
EurekaServerContextHolder.initialize(this.serverContext);
log.info("Initialized server context");
// Copy registry from neighboring eureka node
// 从其他EurekaServer节点同步服务注册信息
int registryCount = this.registry.syncUp();
//方法主要是设置了期望每分钟接收到的心跳次数,并将服务实例的状态设置为UP,
//通过方法postInit来开启一个定时任务,
//用于每隔一段时间(默认60秒)将没有续约的服务实例(默认90秒没有续约)清理掉。
this.registry.openForTraffic(this.applicationInfoManager, registryCount);
// Register all monitoring statistics.
// 注册EurekaServer的监控指标
EurekaMonitors.registerAllStats();
}
待办拓展:
Spring Boot 自动装配,自定义实现starter
Spring Boot ConfigurationProperties实现
Eureka 的配置
EurekaServerBootstrap、PeerAwareInstanceRegistry、PeerEurekaNodes 的实现细节。
Eureka Client实现
网友评论