前言
源码解析基于Hoxton.SR1版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
1、摘要
- 服务注册
- 服务发现
- 服务下架 client--主动 服务下架和服务剔除最终调用的是同一个方法 server集群间会进行同步
- 服务剔除 client--被动(eureka server维持一个定时任务扫描服务注册表,判断服务心跳续约是否过期) eureka server判断心跳过期 server集群间不进行同步
- 心跳续约
- 自我保护机制
- 缓存机制(包含客户端缓存和服务端缓存)
- 集群同步 (PeerAwareInstanceRegistryImpl#renew负责所有eureka server的集群同步)
eureka server也是一个mvc架构,controller层使用jersey框架实现(本文只关注请求处理逻辑)
注册中心需要与客户端进行交互 接受请求 返回响应 -- mvc架构(不是springmvc(基于servlet),而是通过jersey(基于过滤器)实现的)
2、eureka server自动配置原理
springboot项目使用注册中心
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
查看@EnableEurekaServer的类定义
@Import({EurekaServerMarkerConfiguration.class})
public @interface EnableEurekaServer {
}
@EnableEurekaServer给容器里导入了一个bean == EurekaServerMarkerConfiguration
public class EurekaServerMarkerConfiguration {
@Bean
public Marker eurekaServerMarkerBean() {
return new Marker();
}
class Marker {
}
}
EurekaServerMarkerConfiguration给容器里导入了一个Marker(标记) bean 这个Marker的作用就是一个标记 标记用户有没有使用@EnableEurekaServer这个注解
在spring-cloud-netflix-eureka-server的META-INF/spring.factories中 导入了EurekaServerAutoConfiguration自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration
@Configuration(proxyBeanMethods = false)
//导入配置类
@Import(EurekaServerInitializerConfiguration.class)
@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) //当前配置类是否生效
@EnableConfigurationProperties({ EurekaDashboardProperties.class,
InstanceRegistryProperties.class })
@PropertySource("classpath:/eureka/server.properties")
public class EurekaServerAutoConfiguration implements WebMvcConfigurer {
//省略部分代码
//jersey框架基于过滤器 注册过滤器到容器中
@Bean
public FilterRegistrationBean<?> jerseyFilterRegistration(
javax.ws.rs.core.Application eurekaJerseyApp) {
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<Filter>();
bean.setFilter(new ServletContainer(eurekaJerseyApp));
bean.setOrder(Ordered.LOWEST_PRECEDENCE);
bean.setUrlPatterns(
Collections.singletonList(EurekaConstants.DEFAULT_PREFIX + "/*"));
return bean;
}
@Bean
public javax.ws.rs.core.Application jerseyApplication(Environment environment,
ResourceLoader resourceLoader) {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(
false, environment);
/**
* includeFilters:允许过滤的条件 指定需要扫描的内容(此处内容是Component注解)
*
* 代表只有被includeFilters内匹配的注解才可以被扫描解析
*/
provider.addIncludeFilter(new AnnotationTypeFilter(Path.class));
provider.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
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;
}
3、整体架构
springcloud整合netflix的eureka server模块,在业务逻辑(服务注册、心跳续约、服务下架...)处理上基于责任链模式。
InstanceRegistry extends PeerAwareInstanceRegistryImpl extends AbstractInstanceRegistry 责任链模式
- InstanceRegistry spring cloud提供的 用来整合netflix eureka server,主要是发布事件
EurekaInstanceRegisteredEvent:注册事件
EurekaInstanceRenewedEvent:心跳续约时间
EurekaInstanceCanceledEvent:服务下架和服务剔除事件
我们可以在spring应用中编写监听器 监听这些事件
- PeerAwareInstanceRegistryImpl
netflix提供的 用来的做集群同步操作的
- AbstractInstanceRegistry
netflix提供的 真正用来实现服务注册 心跳续约 的业务类