eureka是由Netflix开发的服务发现框架,本身是基于rest服务,是一个Servlet应用,github地址:https://github.com/Netflix/eureka;SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能,github地址:https://github.com/spring-cloud/spring-cloud-netflix/tree/v1.2.2.RELEASE。
eureka分为server端和client端,本文主要来总结server端。
在微服务的架构中,为了提供高可用,在生产环境中可以部署多个注册中心(Eureka server),也就是将自己作为服务注册到其他的注册中心上,这样形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
示例:
注册中心1:
server.port=8760
eureka.instance.appname=eurekaone
eureka.instance.hostname=eurekaone
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
eureka.client.register-with-eureka=true
注册中心2:
spring.application.name=eurekatwo
server.port=8761
eureka.instance.hostname=eurekatwo
eureka.client.service-url.defaultZone=http://localhost:8760/eureka/
eureka.client.register-with-eureka=true
服务1:
spring.application.name=servera
eureka.instance.hostname=localhost
eureka.client.service-url.defaultZone=http://localhost:8760/eureka/
server.port=8080
服务1注册到注册中心1之后,可同步到注册中心2
PS:
服务注册信息不会被二次传播:注册中心1注册到注册中心2,注册中心2注册到注册中心3,注册中心3注册到注册中心1;服务1注册到注册中心1上,注册中心1和注册中心2可以看到新注册上来的服务1,但是服务1不会注册到注册中心3上。
注册中心1:
注册中心二:
注册中心三:
如果想让服务1注册到这三个节点上,则将注册中心1需要注册到其他2个注册中心上。
在spring-cloud-netflix-eureka-server模块的resources下的META-INF中有一个spring.factories文件,文件内容为:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration
即当装配spring-cloud-netflix-eureka-server模块时,会通过该配置文件找到具体的实现类名——EurekaServerAutoConfiguration,并装载实例化,完成模块的注入。
用于EurekaServer往beanfactory中添加与eureka server有关的bean
@Configuration
@Import(EurekaServerInitializerConfiguration.class)
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
@PropertySource("classpath:/eureka/server.properties")
public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter {
(原来有@EnableDiscoveryClient后来没有了,不知道自己的猜测对不对,先保留)
①、@Import:导入EurekaServerInitializerConfiguration.class—spring启动eureka server的bean
@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();
}
②、@ConditionalOnBean: 当且仅当指定的EurekaServerMarkerConfiguration.Marker.class类在当前容器中,才创建标记上该注解的类(EurekaServerAutoConfiguration类)的实例,那EurekaServerMarkerConfiguration.Marker.class类是何时创建的呢?
创建eureka服务模块的application类中:
@EnableEurekaServer
@SpringBootApplication
public class EurekademoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekademoApplication.class, args);
}
}
@EnableEurekaServer注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EurekaServerMarkerConfiguration.class)
public @interface EnableEurekaServer {
}
EurekaServerMarkerConfiguration.class
@Configuration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}
可以发现当启动eureka server服务后,最终EurekaServerMarkerConfiguration.class类创建了一个Marker实例
③、