Eureka使用
Eureka客户端实现原理分析
Eureka服务端实现原理分析
本文主要内容:
- 客户端如何向Eureka注册信息
- 客户端如何通过心跳续约服务
- 客户端如何从Eureka获取服务列表
- 学习借鉴Eurek客户端如何使用定时线程
spring-cloud-netflix-eureka-client不同版本之间,代码会不一样,本文分析的是spring-cloud-netflix-eureka-client-2.2.2.RELEASE.jar版
一、Eureka客户端注册
1、SmartLifeCycle知识
在学习Eureka客户端如何注册之前,先了解一个关于SmartLifeCycle的知识点,即:在Springboot在执行FinshRefresh()方法时,会逐一调用容器中所有实现了Lifecycle接口的Bean的star()方法,而SmartLifeCycle继承Lifecycle接口,也就说会调用SmartLifeCycle实现类的star()方法
源码方法调用链路:
- SpringApplication.run()方法
- refreshContext()方法
- refresh()方法
- AbstractApplicationContext.refresh()方法
- finishRefresh()方法
- getLifecycleProcessor().onRefresh();方法
- DefaultLifecycleProcessor.onRefresh()方法
- startBeans():方法
DefaultLifecycleProcessor#startBeans()的源码:
private void startBeans(boolean autoStartupOnly) {
// 获取Lifecycle实现类bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
Lifecycle bean = entry.getValue();
// SmartLifecycle实现类bean
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(entry.getKey(), bean);
}
}
// 调用SmartLifecycle实现类的start()方法
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<Integer>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
可以自定义一个TestSmartLifeCycle类验证此过程:
@Component
public class TestSmartLifeCycle implements SmartLifecycle {
@Override
public void start() {
System.out.println("TestSmartLifeCycle start");
}
@Override
public void stop() {
System.out.println("TestSmartLifeCycle stop");
}
@Override
public boolean isRunning() {
return false;
}
}
Eureka客户端在进行服务注册时,就使用到了SmartLifeCycle相关功能,下面来看下具体注册流程
2、Eureka客户端注册流程及示意图
以下是Eureka客户端注册实例信息的流程流、和简易流程图,可以先看分析在回来看这部分介绍
Eureka Client会在服务启动时,调用EurekaAutoServiceRegistration#start()方法,此方法会进行以下操作:
- EurekaClientAutoConfiguration注册Bean:EurekaAutoServiceRegistration、EurekaRegistration、ApplicationInfoMangager、EurekaClient(实现类:CloudEurekaClient)
- 在Springboot.onFresh()方法中调用EurekaAutoServiceRegistration#star()方法
- EurekaAutoServiceRegistration调用EurekaServiceRegistry#register()方法
- EurekaServiceRegistry调用以下对象方法:
- ApplicationInfoManager.setInstanceStatus():设置ApplicationInfoManager的实例状态
- CloudEurekaClient.registerHealthCheck():注册一个心跳检测
- ApplicationInfoManager最终调用**监听器listener.notify(new StatusChangeEvent(prev, status));**方法
以下是Eureka Client注册流程示意图:
3、Eureka客户端原理分析
3.1、EurekaClientAutoConfiguration配置类源码分析
当我们启用了Eureka注册中心功能后,Springboot会自动加载Eureka定义的自动装载配置类:EurekaClientAutoConfiguration.class
,同时初始化以下几个重要的Bean:
- EurekaAutoServiceRegistration
- EurekaRegistration
- ApplicationInfoMangager
- EurekaClient(实现类:CloudEurekaClient)
@Bean
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(
value = "spring.cloud.service-registry.auto-registration.enabled",
matchIfMissing = true)
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(
ApplicationContext context, EurekaServiceRegistry registry,
EurekaRegistration registration) {
return new EurekaAutoServiceRegistration(context, registry, registration);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingRefreshScope
protected static class EurekaClientConfiguration {
@Autowired
private ApplicationContext context;
@Autowired
private AbstractDiscoveryClientOptionalArgs<?> optionalArgs;
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class,
search = SearchStrategy.CURRENT)
public EurekaClient eurekaClient(ApplicationInfoManager manager,
EurekaClientConfig config