Eureka服务端

发布时间:2024年01月03日

一般我们Server端会像下图一样,引入Eureka,下面就通过这个来分析Eureka服务端源码流程

1、自动配置

@EnableEurekaServer开关
eureka是一个c/s架构的服务治理框架,springcloud将其集成用作服务治理。springcloud使用eureka比较简单,只需要引入依赖以后添加一个@EnableEurekaServer注解即可,如

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

public static void main(String[] args) {
    SpringApplication.run(EurekaApplication.class, args);
}

}

@EnableEurekaServer又有什么魔力呢?为什么它能够开关EurekaServer?为此,我们打开@EnableEurekaServer注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer {

}

可以看到,@EnableEurekaServer的@Import注解导入了一个EurekaServerMarkerConfiguration类。所以,开启@EnableEurekaServer注解也就是导入该类。

那么,EurekaServerMarkerConfiguration这个配置类又做了啥?

@Configuration
public class EurekaServerMarkerConfiguration {

@Bean
public Marker eurekaServerMarkerBean() {
    return new Marker();
}

class Marker {

}

}

可以看到,这里只是把一个空的Marker类变成了spring中的Bean。而Marker本身什么功能都没有实现。顾名思义,我们可以这样猜测一下:@EnableEurekaServer注解就是将Marker配置为Bean,而Marker作为Bean的存在,将会触发自动配置,从而达到了一个开关的效果。

EurekaServerAutoConfiguration自动配置类
我们再打开EurekaServerAutoConfiguration这个自动配置类

@Configuration
@Import(EurekaServerInitializerConfiguration.class)
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
@PropertySource(“classpath:/eureka/server.properties”)
public class EurekaServerAutoConfiguration implements WebMvcConfigurer {
// …
}

首先值得注意的是@ConditionalOnBean这个注解,它将判断EurekaServerMarkerConfiguration.Marker这个Bean是否存在。如果存在才会解析这个自动配置类,从而呼应了@EnableEurekaServer这个注解的功能。
@EnableConfigurationProperties注解和@PropertySource注解都加载了一些键值对的属性。
@Import导入了一个初始化类EurekaServerInitializerConfiguration(后面再看它)

EurekaServerAutoConfiguration作为自动配置类,我们看看它主要配置了哪些东西(有所忽略)
看板
服务治理少不了需要一个DashBoard来可视化监控,EurekaController基于springmvc提供DashBoard相关的功能。

@Bean
@ConditionalOnProperty(prefix = “eureka.dashboard”, name = “enabled”,
matchIfMissing = true)
public EurekaController eurekaController() {
return new EurekaController(this.applicationInfoManager);
}

发现注册
发现注册作为主要的核心功能,也是必不可少的

@Bean
public PeerAwareInstanceRegistry peerAwareInstanceRegistry(
ServerCodecs serverCodecs) {
this.eurekaClient.getApplications(); // force initialization
return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig,
serverCodecs, this.eurekaClient,
this.instanceRegistryProperties.getExpectedNumberOfClientsSendingRenews(),
this.instanceRegistryProperties.getDefaultOpenForTrafficCount());
}

启动引导

@Bean
public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,
EurekaServerContext serverContext) {
return new EurekaServerBootstrap(this.applicationInfoManager,
this.eurekaClientConfig, this.eurekaServerConfig, registry,
serverContext);
}

Jersey提供rpc调用
jersey是一个restful风格的基于http的rpc调用框架,eureka使用它来为客户端提供远程服务。

@Bean
public javax.ws.rs.core.Application jerseyApplication(Environment environment,
ResourceLoader resourceLoader) {

ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(
        false, environment);

// Filter to include only classes that have a particular annotation.
//
provider.addIncludeFilter(new AnnotationTypeFilter(Path.class));
provider.addIncludeFilter(new AnnotationTypeFilter(Provider.class));

// Find classes in Eureka packages (or subpackages)
//
Set<Class<?>> classes = new HashSet<>();
for (String basePackage : EUREKA_PACKAGES) {
    Set<BeanDefinition> beans = provider.findCandidateComponents(basePackage);
    for (BeanDefinition bd : beans) {
        Class<?> cls = ClassUtils.resolveClassName(bd.getBeanClassName(),
                resourceLoader.getClassLoader());
        classes.add(cls);
    }
}

// Construct the Jersey ResourceConfig
Map<String, Object> propsAndFeatures = new HashMap<>();
propsAndFeatures.put(
        // Skip static content used by the webapp
        ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX,
        EurekaConstants.DEFAULT_PREFIX + "/(fonts|images|css|js)/.*");

DefaultResourceConfig rc = new DefaultResourceConfig(classes);
rc.setPropertiesAndFeatures(propsAndFeatures);

return rc;

}

这里将会扫描Resource,并添加到ResourceConfig当中。

EurekaServerInitializerConfiguration初始化
再回过头来,看看@EnableEurekaServer注解导入的EurekaServerInitializerConfiguration类。

@Configuration
public class EurekaServerInitializerConfiguration implements ServletContextAware, SmartLifecycle, Ordered {
// …

@Override
public void start() {
    new Thread(() -> {
        try {
            eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);

            publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
            EurekaServerInitializerConfiguration.this.running = true;
            publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
        } catch (Exception ex) {
            //
        }
    }).start();
}

}

初始化过程调用了EurekaServerBootstrap的contextInitialized方法,我们跟进看看

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);
}

}

这里初始化了EurekaEnvironment和EurekaServerContext,EurekaEnvironment无非就是设置了各种配置之类的东西。我们打开initEurekaServerContext看看

protected void initEurekaServerContext() throws Exception {
// …

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

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

}

这里主要做了两件事:
1)从相邻的集群节点当中同步注册信息
2)注册一个统计器

回到顶部
总结
@EnableEurekaServer注解开启了EurekaServerAutoConfiguration这个配置类的解析,EurekaServerAutoConfiguration这个配置了主要准备了看板、注册发现、启动引导、Jersey等,EurekaServerInitializerConfigration将会触发启动引导,引导过程会从其它Eureka集群节点当中同步注册信息。

文章来源:https://blog.csdn.net/LittleStar_Cao/article/details/135372646
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。