1.好味道源码定位
在com.netflix.eureka.EurekaBootStrap#initEurekaServerContext
方法中,
通过new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get()
方法来获取InstanceInfo单例。
这个类主要是为Guice轻量级依赖注入使用。
通过上面这种new 出来的只能保证单个EurekaConfigBasedInstanceInfoProvider
对象内的InstanceInfo是单例的,而无法保证全局唯一。
@Provider 是用于提供复杂对象创建使用的。
2.单例
Provider<InstanceInfo>
自动注入EurekaConfigBasedInstanceInfoProvider到Guice框架的容器中去。
@Singleton
用于保证EurekaConfigBasedInstanceInfoProvider是单例。
如果EurekaConfigBasedInstanceInfoProvider是单例的,
那么通过Guice容器获取的EurekaConfigBasedInstanceInfoProvider实例生成的InstanceInfo是全局单例的。
保证InstanceInfo单例
3.InstanceInfo中有哪些东西呢?
3.1 续约对象
// 默认的 续约(心跳)刷新周期为30秒。就是每30秒发送一次心跳
// 默认的过期周期为90秒,也就是超过90秒没有收到心跳信息,认为已经掉线,可以踢出服务
LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder()
.setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds())
.setDurationInSecs(config.getLeaseExpirationDurationInSeconds());
3.2 使用builder建造者模式构建复杂对象
InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(vipAddressResolver);
3.3 坏味道之硬判断亚马逊云服务信息
eureka中包涵了大量对亚马逊云的特殊处理,如果作为一个通用框架的话,这种处理是不具备扩展性的。属于硬编码兼容亚马逊云,对国内来说,就是影响阅读的代码。
3.4 builder 清晰简单构建InstanceInfo
3.5 InstanceInfo 状态变更
if (!config.isInstanceEnabledOnit()) {
// 服务实例状态变更
InstanceStatus initialStatus = InstanceStatus.STARTING;
LOG.info("Setting initial instance status as: " + initialStatus);
builder.setStatus(initialStatus);
} else {
LOG.info("Setting initial instance status as: {}. This may be too early for the instance to advertise "
+ "itself as available. You would instead want to control this via a healthcheck handler.",
InstanceStatus.UP);
}
3.6 自定义元数据加载及续约信息绑定InstanceInfo
4.总结
这里使用单例模式和建造者模式,这里有两个单例模式:一个单例模式是有容器框架Guice框架保证,一个是由synchronized
与 instanceInfo == null
来保证单例。
eureka本身是由Netflix自身内部使用的,所以为了更好的与亚马逊云服务进行契合,做了很多特殊处理。但是对于一个框架来说,瑕疵却比较多。辩证看待,辩证学习。