前言
有了springboot
的一些基础,可以开始springcloud
进阶啦,目前微服务比较流行的大致这三类,zookeeper
+dubbo
,spring cloud netflix
,alibaba
,而netflix
这套东西好多都停止维护了,可能要被alibaba
的代替了,当然这些都能了解那最好了,以后做计数选型的时候就可以根据不同场景和业务选更好的匹配技术。netflix
虽然大多停止维护了,但是还是很经典的,所以还是想从这个经典的微服务框架分析下这些组件的一些原理和源码,更好的理解微服务,其实更多的是一种设计思想,废话不多说,我们开始吧。
初始化基本流程图
EurekaServer注册中心
首先这个这么用的我就不多说了,这些框架用起来确实简单,几个注解就好了,我们还是分析下原理比较好,先从服务端,也就是注册中心开始。如果还没用过的话可以去了解下,不然可能看不懂。我们知道配置注册中心只需要一个注解,加点配置即可,配置怎么加我就不说了,我们来说说注解@EnableEurekaServer
。
EnableEurekaServer注解
没干什么,就将Marker
类注册到容器中,我们可以猜到,这个对象是标记对象,也就是说可能自动配置里会根据这个标记做什么事对吧。
其他什么都没了,因为我们学过springboot自动配置啦,相关的肯定是在spring.factories
中啦,一般这种框架命名还是很规范的,其实直接可以去找xxxAutoConfiguration
类:
EurekaServerAutoConfiguration
可以看到这里有个条件注解ConditionalOnBean
,因为自动配置解析处理是在其他配置类处理完后处理的,所以这个时候容器里已经有Marker
的bean
定义了,所以这个条件满足了,因为可以解析EurekaServerAutoConfiguration
了。关于这个类干了点什么,后面会说,但是有个很重要的地方跟初始化有关,就是实例化EurekaServerBootstrap
,而这个又依赖EurekaServerContext
,后面初始化跟他们有关:
然后,我要说的是被import
的EurekaServerInitializerConfiguration
。
EurekaServerInitializerConfiguration
这个名字一样就是初始化的,关键在SmartLifecycle
,他用SmartLifecycle
的start
回调来初始化。
看到了吧,初始化的时候跟EurekaServerBootstrap
和EurekaServerContext
有关。
EurekaServerContext
从依赖关系上看,最早被实例化初始化完成的应该是EurekaServerContext
,其实他就是服务上下文,应该是跟我们的服务器相关的,我们来看看他有什么特性,在他的一个initialize
方法上有初始化之前注解PostConstruct
:
因为他在初始化之前会被处理:
RefreshablePeerEurekaNodes的start
这个对象是依赖注入进来的,看名字好像是做集群结点启动的。其实他做的就是开一个单线程,然后定时去更新集群结点信息,因为我们集群的话配置文件里会进行相互配置,就是用来做这个相互注册的,默认好像600
秒一次。具体怎么做的可以去updatePeerEurekaNodes
看看,其实就是拿到其他结点的地址,进行网络通信,只是底层是用Jersey
的,当然里面还涉及一些批量任务,延迟执行的,有兴趣可以去看看。
public void start() {
taskExecutor = Executors.newSingleThreadScheduledExecutor(//单线程任务
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "Eureka-PeerNodesUpdater");
thread.setDaemon(true);
return thread;
}
}
);
try {
updatePeerEurekaNodes(resolvePeerUrls());//更新集群其他结点,里面会创建
Runnable peersUpdateTask = new Runnable() {
@Override
public void run() {
try {
updatePeerEurekaNodes(resolvePeerUrls());//定时更新
} catch (Throwable e) {
logger.error("Cannot update the replica Nodes", e);
}
}
};
taskExecutor.scheduleWithFixedDelay(//启动定时任务
peersUpdateTask,
serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
TimeUnit.MILLISECONDS
);
} catch (Exception e) {
throw new IllegalStateException(e);
}
for (PeerEurekaNode node : peerEurekaNodes) {
logger.info("Replica node URL: {}", node.getServiceUrl());
}
}
PeerAwareInstanceRegistryImpl的init
这里做一些服务端要初始化的事,比如需要有缓存,他的缓存同了三级,读缓存,读写缓存,注册表,具体后面会说,然后开启了一个续约阈值更新的定时任务,默认900
秒一次,这个跟后面自动保护机制相关。
@Override
public void init(PeerEurekaNodes peerEurekaNodes) throws Exception {
this.numberOfReplicationsLastMin.start();
this.peerEurekaNodes = peerEurekaNodes;
initializedResponseCache();//创建服务端缓存,读缓存,读写缓存等
scheduleRenewalThresholdUpdateTask();//开启续约阈值更新任务
initRemoteRegionRegistry();
try {
Monitors.registerObject(this);
} catch (Throwable e) {
logger.warn("Cannot register the JMX monitor for the InstanceRegistry :", e);
}
}
EurekaServerContext
的初始化基本说完了,后面说EurekaServerInitializerConfiguration
的初始化。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。