2023-09-15
原文作者:王伟王胖胖 原文地址:https://blog.csdn.net/wangwei19871103/article/details/105610087

前言

有了springboot的一些基础,可以开始springcloud进阶啦,目前微服务比较流行的大致这三类,zookeeper
+dubbo,spring cloud netflix,alibaba,而netflix这套东西好多都停止维护了,可能要被alibaba的代替了,当然这些都能了解那最好了,以后做计数选型的时候就可以根据不同场景和业务选更好的匹配技术。netflix虽然大多停止维护了,但是还是很经典的,所以还是想从这个经典的微服务框架分析下这些组件的一些原理和源码,更好的理解微服务,其实更多的是一种设计思想,废话不多说,我们开始吧。

初始化基本流程图

202309152310019281.png

EurekaServer注册中心

首先这个这么用的我就不多说了,这些框架用起来确实简单,几个注解就好了,我们还是分析下原理比较好,先从服务端,也就是注册中心开始。如果还没用过的话可以去了解下,不然可能看不懂。我们知道配置注册中心只需要一个注解,加点配置即可,配置怎么加我就不说了,我们来说说注解@EnableEurekaServer

EnableEurekaServer注解

202309152310032152.png
没干什么,就将Marker类注册到容器中,我们可以猜到,这个对象是标记对象,也就是说可能自动配置里会根据这个标记做什么事对吧。

202309152310037603.png
其他什么都没了,因为我们学过springboot自动配置啦,相关的肯定是在spring.factories中啦,一般这种框架命名还是很规范的,其实直接可以去找xxxAutoConfiguration类:

202309152310042814.png

202309152310047335.png

EurekaServerAutoConfiguration

可以看到这里有个条件注解ConditionalOnBean,因为自动配置解析处理是在其他配置类处理完后处理的,所以这个时候容器里已经有Markerbean定义了,所以这个条件满足了,因为可以解析EurekaServerAutoConfiguration了。关于这个类干了点什么,后面会说,但是有个很重要的地方跟初始化有关,就是实例化EurekaServerBootstrap,而这个又依赖EurekaServerContext,后面初始化跟他们有关:

202309152310054356.png
然后,我要说的是被importEurekaServerInitializerConfiguration

202309152310061457.png

EurekaServerInitializerConfiguration

这个名字一样就是初始化的,关键在SmartLifecycle,他用SmartLifecyclestart回调来初始化。

202309152310067108.png
看到了吧,初始化的时候跟EurekaServerBootstrapEurekaServerContext有关。

202309152310072279.png

EurekaServerContext

从依赖关系上看,最早被实例化初始化完成的应该是EurekaServerContext,其实他就是服务上下文,应该是跟我们的服务器相关的,我们来看看他有什么特性,在他的一个initialize方法上有初始化之前注解PostConstruct

2023091523100787210.png
因为他在初始化之前会被处理:

2023091523100851911.png

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的初始化。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

阅读全文