在两种情况下客户端会主动像服务端发送自己的注册信息:
1.客户端刚启动的时候。
2.客户端状态发生变更,与server端状态不一致。
client的元数据信息类: InstanceInfo instanceId的工具类 IdUtils
DiscoveryClient是client端发起server交互的操作发起类。里面initScheduledTasks注册了很多定时器:
1.刷新缓存定时器(cacheRefresh).
2续约发送心跳定时器(heartbeat) renew
3.instance状态变更监听器(statusChangeListener).
4.开启应用状态复制器(instanceReplicator).
client 向server发起调用注册(register),续约(renew),服务下线(cancel)等默认使用jersey框架来完成http请求 : AbstractJerseyEurekaHttpClient。注册的是post调用eureka-server的apps/${app_name}接口,参数为instance,实现注册实例信息。
那么服务端是如何处理注册请求的呢? ApplicationResource.addInstance()方法,内部调用PeerAwareInstanceRegistryImpl的register方法。
在server端,应用信息也是存储在内存中的currentHashMap结构中。 Map<String, Lease<InstanceInfo>> gMap 。
自定义扩展增强:
增加服务注册与发现的纬度。默认情况下服务是按照serverId来进行服务注册与发现,当遇到公司的应用比较多的情况下,会出现应用名称重复。可以通过在项目都按照部门设定group,version等纬度来区分应用。 可以扩展EurekaServiceRegistry类,自定义实现EurekaServiceRegistryWrapper去扩展原来的服务注册,发现方法。然后在项目中自定义ApplicationContextInitializer的实现,去实现在加载过程中。用自定义的的包装部去替换系统默认的实现。达到扩展的效果。
@Override public void initialize(ConfigurableApplicationContext applicationContext) { ConfigurableEnvironment environment = applicationContext.getEnvironment(); applicationContext.getBeanFactory().addBeanPostProcessor(new InstantiationAwareBeanPostProcessorAdapter() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof EurekaServiceRegistry) { EurekaServiceRegistry eurekaServiceRegistry = (EurekaServiceRegistry)bean; return new EurekaServiceRegistryWrapper(eurekaServiceRegistry, environment); } else if (bean instanceof EurekaInstanceConfigBean) { EurekaInstanceConfigBean instanceConfig = (EurekaInstanceConfigBean)bean; instanceConfig.setPreferIpAddress(true); return bean; } else { return bean; } } }); }