• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • EurekaServer自動裝配及啟動流程解析

    在開始本篇文章之前,我想你對SpringCloud和SpringBoot的基本使用以及比較熟悉了,如果不熟悉的話可以參考我之前寫過的文章

    本篇文章的源碼基于SpringBoot2.0,SpringCloud的Finchley.RELEASE

    @EnableEurekaServer注解

    我們知道,在使用Eureka作為注冊中心的時候,我們會在啟動類中增加一個@EnableEurekaServer注解,這個注解我們是一個自定義的EnableXXX系列的注解,主要作用我們之前也多次提到了,就是引入配置類而已。看一下源碼吧

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({EurekaServerMarkerConfiguration.class})
    public @interface EnableEurekaServer {
    }
    

    引入了一個配置類EurekaServerMarkerConfiguration,看一下這個類的具體內容

    @Configuration
    public class EurekaServerMarkerConfiguration {
    
        @Bean
        public Marker eurekaServerMarkerBean() {
            return new Marker();
        }
    
        class Marker {
        }
    }
    

    現在看這里好像難以理解,這是啥意思,搞個空的類干啥的,不要著急,接著往下看

    自動裝配

    既然注解上沒有找到我們想要的東西,那么就看一下spring.factories文件吧,這里自動配置的實現類是EurekaServerAutoConfiguration

    由于這個類涉及的代碼實在是太多了,這里就不貼了,咱們直接來解析這個類:

    1. 引入EurekaServerInitializerConfiguration類

    看名字就知道了這個類是負責Eureka的初始化工作的,這個類實現了SmartLifecycle接口,所以在spring初始化和銷毀的時候,就會分別調用它的start和stop方法

    首先看一下start方法

    public void start() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //啟動EurekaServer
    eurekaServerBootstrap.contextInitialized(EurekaServerInitializerConfiguration.this.servletContext);
                        log.info("Started Eureka Server");
    
                        publish(new EurekaRegistryAvailableEvent(getEurekaServerConfig()));
                        EurekaServerInitializerConfiguration.this.running = true;
                        publish(new EurekaServerStartedEvent(getEurekaServerConfig()));
                    }
                    catch (Exception ex) {
                        // Help!
                        log.error("Could not initialize Eureka servlet context", ex);
                    }
                }
            }).start();
        }
    

    這個代碼好像比較直接了當啊,直接就起個線程啟動了EurekaServer,然后發布了一些啟動事件,來看啟動的過程吧

    
    public void contextInitialized(ServletContext context) {
                    try {
                //初始化執行環境
                            initEurekaEnvironment();
                //初始化上下文
                            initEurekaServerContext();
    
                            context.setAttribute(EurekaServerContext.class.getName(), this.serverContext);
                    }
                    catch (Throwable e) {
                            log.error("Cannot bootstrap eureka server :", e);
                            throw new RuntimeException("Cannot bootstrap eureka server :", e);
                    }
            }
    

    這里一共包含初始化環境和初始化上下文兩個分支

    初始化執行環境

    這個不是很重要,可以過濾掉

    
    protected void initEurekaEnvironment() throws Exception {
                    log.info("Setting the eureka configuration..");
                   //AWS相關的東西,可以忽略
                    String dataCenter = ConfigurationManager.getConfigInstance()
                                    .getString(EUREKA_DATACENTER);
                    if (dataCenter == null) {
                            log.info(
                                            "Eureka data center value eureka.datacenter is not set, defaulting to default");
                            ConfigurationManager.getConfigInstance()
                                            .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT);
                    }
                    else {
                            ConfigurationManager.getConfigInstance()
                                            .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter);
                    }
            //設置 Eureka 環境,默認為test
                    String environment = ConfigurationManager.getConfigInstance()
                                    .getString(EUREKA_ENVIRONMENT);
                    if (environment == null) {
                            ConfigurationManager.getConfigInstance()
                                            .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
                            log.info(
                                            "Eureka environment value eureka.environment is not set, defaulting to test");
                    }
                    else {
                            ConfigurationManager.getConfigInstance()
                                            .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment);
                    }
            }
    
    初始化上下文
    
    protected void initEurekaServerContext() throws Exception {
                    // 設置json與xml序列化工具
                    JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
                                    XStream.PRIORITY_VERY_HIGH);
                    XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(),
                                    XStream.PRIORITY_VERY_HIGH);
    
                    if (isAws(this.applicationInfoManager.getInfo())) {
                            this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig,
                                            this.eurekaClientConfig, this.registry, this.applicationInfoManager);
                            this.awsBinder.start();
                    }
    
                    EurekaServerContextHolder.initialize(this.serverContext);
    
                    log.info("Initialized server context");
    
                    // 同步Eureka集群數據
                    int registryCount = this.registry.syncUp();
                    this.registry.openForTraffic(this.applicationInfoManager, registryCount);
    
                    // 注冊監控統計信息
                    EurekaMonitors.registerAllStats();
            }
    

    這個方法中同步集群數據和注冊監控信息都涉及的內容比較多,所以本篇文章就不再展開了,請關注我留意后續文章

    @ConditionalOnBean({Marker.class})

    看到這里就揭開了開篇@EnableEurekaServer注解注入的那個bean的含義了。也就是說如果咱們的啟動類沒有使用@EnableEurekaServer注解的話,這個自動配置類就不會執行,那也就沒有Eureka的事了

    @EnableConfigurationProperties({EurekaDashboardProperties.class, InstanceRegistryProperties.class})

    深入這個注解發現這個還是使用的@Import注解的機制引入了兩個類,這個注解在之前的源碼解析文章中也多次提到了,這里就不展開了

    EurekaDashboardProperties這個類比較簡單,主要是Eureka的控制臺的相關配置

    //控制臺默認路徑
    private String path = "/";
    //是否開啟控制臺
    private boolean enabled = true;
    

    InstanceRegistryProperties,這個類是控制Eureka的注冊時的配置信息

        //每分鐘續約次數
        @Value("${eureka.server.expectedNumberOfRenewsPerMin:1}") 
        private int expectedNumberOfRenewsPerMin = 1;
        //默認打開的通信數量
        @Value("${eureka.server.defaultOpenForTrafficCount:1}")
        private int defaultOpenForTrafficCount = 1;
    
    @PropertySource("classpath:/eureka/server.properties")

    相信大家比較熟悉這個注解,加載Eureka的配置文件而已

    配置文件中也僅僅只包含這個信息

    spring.http.encoding.force=false
    
    自動注入的bean

    EurekaServerAutoConfiguration類上幾個注解就解析完了,接著看一下這個類中注入的幾個比較重要的類吧

    配置類EurekaServerConfigBeanConfiguration

    EurekaServerConfig 如果當前應用允許注冊到其他Eureka服務中時,也就是屬性eureka.client.fetch-registry為true時。就設置屬性registrySyncRetries的值為5,這個屬性的意思是當Eureka服務器啟動時嘗試去獲取集群里其他服務器上的注冊信息的次數

    EurekaController

    這個就是Eureka自己的controller了,控制臺的相關信息就是從這里獲取的

    ServerCodecs

    設置Eureka的序列化工具

    PeerAwareInstanceRegistry

    集群注冊信息同步相關的類,請期待后續深入解析文章

    FilterRegistrationBean

    EurekaServer接受請求的一個攔截器,感興趣的同學可以研究一下

    往期好文

     

    640?wx_fmt=png

    如果文章對您有所幫助,收藏、轉發、在看安排一下!!!

    版權聲明:本文為javaxuexilu原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/javaxuexilu/article/details/102512907

    智能推薦

    虛擬機centos配置網絡,固定ip地址

    執行 ifconfig,查看網絡是沒有ip地址的 一、首先將虛擬機的網絡配置設置為橋接模式 二、查看虛擬網絡配置 三、進入到系統控制臺中 配置如圖所示:...

    中移OneNET 云平臺 >>> 一塊ESP8266 的WiFi 定位之旅

    前言 WiFi 定位功能是OneNET 繼基站定位之后最新推出的一項定位服務。(編稿時仍處于灰度測試階段) 然后我有幸參與了WiFi 定位功能的灰度測試,測試成功,在此記錄一下 開始 1)為設備開啟WiFi 定位功能 WiFi 定位功能門戶(編稿時處于半開放狀態,官網不能查詢到,直接點擊下方鏈接進入): https://open.iot.10086.cn/develop/lbs/#/wifi/wi...

    NDK29_FFmpeg內存釋放

    NDK開發匯總 文章目錄 一 native層內存泄漏 二 內存回收 BaseChannel VideoChannel AudioChannel DNFFmpeg native-lib調用結束,并釋放內存的方法 三 進行回收后效果圖 四 Demo 一 native層內存泄漏 在上一篇文章中,實現了音視頻播放與同步 NDK27_FFmpeg音視頻同步 當退出播放后,native的內存沒有降低,內存產生...

    Java_函數

    java_函數 函數的定義 概念:實現特定功能的一段代碼,可反復使用 三要素:返回值、函數名、參數表 語法 函數定義的位置 ····函數定義在類的內部,與main函數并列 函數的調用 在需要執行函數代碼的位置,通過函數名進行調用 注意:調用函數時,會優先執行函數內部代碼,結束后,反回到函數調用處,繼續向下執行 函數的參數 形參與實參 注意:調...

    實現元素的左右移動

    實現元素的左右移動 我們先來看一下要實現的效果,如下圖所示那樣,讓方框內的元素左右移動。 首先,先寫一個簡單的結構 寫好了HTML的結構,接下來給元素寫樣式 然后鼠標到元素上按shift鍵+鼠標滾輪就可以左右移動了。...

    猜你喜歡

    Java序列化: Serializable

    說起序列化,可能大部分人在實際工作中都沒有使用過,雖然沒用過,但不表示它不重要,那什么是JAVA序列化呢? JAVA序列化也可稱為對象序列化機制:允許把內存中的Java對象轉換成平臺無關的二進制流,從而允許把這種二進制流持久地保存在磁盤上,或通過網絡將這種二進制流傳輸到另一個網絡節點。序列化的好處在于可將任何實現了Serializable接口的對象轉化為字節數據,使其在保存和傳輸時可被還原。序列化...

    HDU 2680 Choose the best route(dij)

      有 n 個地點,有 m 個條路,以及終點 e 給出 m 條路的起點和終點,以及路費 再給出 q 個起始點,求到達 e 點最小花費  默認起始點為 0 ,利用 dij 求解   ...

    Scrapy——理解HTML和XPath

    HTML、DOM樹以及XPath 從用戶在瀏覽器輸入URL到屏幕顯示的過程。 在瀏覽器輸入URL。URL的第一部分用于在網絡上找到合適的服務器,而URL以及cookie等其他數據則構成一個請求,用于發送到那臺服務器中。 服務器回應,向瀏覽器發送一個HTML頁面。也可能返回其他格式,比如XML和JSON。 將HTML轉換成瀏覽器內部的樹狀表示形式:文檔對象模型。 基于一些布局規則渲染內部表示,達到你...

    vue封裝全局loading

    首先創建一個loading文件 在store中添加變量 在app.vue中引入loading文件 然后就可以使用啦 全局使用 各位客官要是感覺有用的話能留個小心心嘛,謝謝啦!!!^ v ^...

    vrep筆記

    這些天主要對vrep做了一些探索,一些筆記如下: 1.urdf機器人模型文件的導入 點擊plugins-urdf importing即可 2.動力學模型的配置 將此處改成零,大意是以方框的正中心為質心,否則很容易抖!!模型導入后坐標系都會被這個包圍盒的坐標系覆蓋,上面的bady is responsable表示剛體是有碰撞特性的,一般前一個臂如果前四個打鉤,后一個臂則后四個打鉤,bady is d...

    精品国产乱码久久久久久蜜桃不卡