sofa-rpc源碼分析 2-服務(wù)啟動(dòng)

一谱邪、服務(wù)啟動(dòng)(dubbo協(xié)議)

ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("dubbo-server");//應(yīng)用信息
        //聲明dubbo協(xié)議,因?yàn)閟ofa-rpc是支持一個(gè)接口的多協(xié)議發(fā)布
        ServerConfig serverConfig = new ServerConfig()
            .setProtocol("dubbo")
            .setHost("127.0.0.1")
            .setPort(20080)
            .setSerialization("hessian2")//序列化協(xié)議
            .setDaemon(false);
        //發(fā)布服務(wù)楞泼,采用的是構(gòu)造器模式驰徊,多次setServer就行
        ProviderConfig<HelloService> providerConfig = new ProviderConfig<HelloService>()
            .setInterfaceId(HelloService.class.getName())
            .setBootstrap("dubbo")
            .setApplication(applicationConfig)
            .setRef(new HelloServiceImpl())
            .setUniqueId("xxx")//UniqueId為了同一個(gè)接口能在發(fā)布為多個(gè)bean
            .setServer(serverConfig)
            .setRegister(false);

        ProviderConfig<EchoService> providerConfig2 = new ProviderConfig<EchoService>()
            .setInterfaceId(EchoService.class.getName())
            .setRef(new EchoServiceImpl())
            .setApplication(applicationConfig)
            .setBootstrap("dubbo")
            .setUniqueId("xxx")
            .setServer(serverConfig)
            .setRegister(false);

        //真正發(fā)布服務(wù)的入口,下面也是我們即將分析的代碼
        providerConfig.export();
        providerConfig2.export();

        LOGGER.warn("started at pid {}", RpcRuntimeContext.PID);

        synchronized (DubboServerMain.class) {
            while (true) {
                try {
                    DubboServerMain.class.wait();
                } catch (InterruptedException e) {

                }
            }
        }
    }

二堕阔、源碼分析

1.providerBootstrap = Bootstraps.from(this);//初始化ProviderBootstrap對(duì)象棍厂,ProviderBootstrap對(duì)象包裝了各類(lèi)bootstrap的發(fā)布和取消發(fā)布
    1.1 String bootstrap = providerConfig.getBootstrap();
        if (StringUtils.isEmpty(bootstrap)) {//如果沒(méi)設(shè)置bootstrap則使用默認(rèn)的bootstrap
            // Use default provider bootstrap
            bootstrap = RpcConfigs.getStringValue(RpcOptions.DEFAULT_PROVIDER_BOOTSTRAP);
            providerConfig.setBootstrap(bootstrap);
        }
        //通過(guò)SPI Extension反射獲取providerBootstrap對(duì)象
        ProviderBootstrap providerBootstrap = ExtensionLoaderFactory.getExtensionLoader(ProviderBootstrap.class)
            .getExtension(bootstrap, new Class[] { ProviderConfig.class }, new Object[] { providerConfig });
2.providerBootstrap.export();//目前sofa-rpc提供了兩種bootstrap,DefaultProviderBootstrap和DubboProviderBootstrap
    2.1 DubboProviderBootstrap
        //將providerBootstrap轉(zhuǎn)換為dubbo 原生的ServiceConfig
        2.1.1 covert(providerConfig, serviceConfig);
            2.1.1.1copyApplication(providerConfig, serviceConfig);//復(fù)制應(yīng)用信息
            //復(fù)制服務(wù)提供者需要的注冊(cè)中心信息超陆,提供了本地緩存映射牺弹,提升復(fù)制性能
            2.1.1.2DubboConvertor.copyRegistries(providerConfig, serviceConfig);
            //復(fù)制ProtocolConfig協(xié)議相關(guān)的信息,包括序列化器、IO線程大小张漂、業(yè)務(wù)線程大小晶默、線程池、報(bào)文長(zhǎng)度限制
            2.1.1.3copyServers(providerConfig, serviceConfig);
            //復(fù)制ServiceConfig相關(guān)的服務(wù)提供者信息航攒,包括相關(guān)的接口磺陡、bean引用等,但是代碼里強(qiáng)制set了dubbo的服務(wù)版本是1.0屎债,如果你想用sofa-rpc去發(fā)布dubbo 2.0協(xié)議的服務(wù)仅政,發(fā)布出來(lái)的永遠(yuǎn)是1.0的服務(wù),因?yàn)楝F(xiàn)在sofa-rpc并沒(méi)提供服務(wù)版本的概念
            [issues](https://github.com/alipay/sofa-rpc/issues/587)
            2.1.1.4copyProvider(providerConfig, serviceConfig);
            //復(fù)制MethodConfig
            2.1.1.5copyMethods(providerConfig, serviceConfig);
        //通過(guò)duubo 的ServiceConfig.export方法將服務(wù)發(fā)布
        2.1.2 serviceConfig.export();
    //sofa-rpc還提供了默認(rèn)的發(fā)布協(xié)議
    2.2 DefaultProviderBootstrap
        //校驗(yàn)參數(shù)盆驹,組裝方法發(fā)布的黑白名單
        2.2.1checkParameters()
        // 構(gòu)造請(qǐng)求調(diào)用器圆丹,主要是初始化服務(wù)端的Filter過(guò)濾器,包含了系統(tǒng)自定義的服務(wù)端的過(guò)濾器和用戶(hù)自定義的過(guò)濾器
        2.2.2providerProxyInvoker = new ProviderProxyInvoker(providerConfig);
              //初始化過(guò)濾器鏈FilterChain
              2.2.2.1 this.filterChain = FilterChain.buildProviderChain(providerConfig,
            new ProviderInvoker(providerConfig))
                //獲取服務(wù)端需要加載的過(guò)濾器躯喇,providerConfig里包含了用戶(hù)通過(guò)別名和Filter示例自定義的過(guò)濾器辫封,PROVIDER_AUTO_ACTIVES是static加載的系統(tǒng)默認(rèn)Filter過(guò)濾器,相關(guān)的過(guò)濾器我們?cè)诤罄m(xù)Filter過(guò)濾器原理分析
                2.2.2.1.1selectActualFilters(providerConfig, PROVIDER_AUTO_ACTIVES)
                //判斷優(yōu)先加載用戶(hù)自定義的過(guò)濾器廉丽,并且只加載能加載的過(guò)濾器(這個(gè)判定在各子類(lèi)定義)
                2.2.2.1.2 new FilterChain(selectActualFilters(providerConfig, PROVIDER_AUTO_ACTIVES), lastFilter, providerConfig)
      //根據(jù)注冊(cè)中心配置獲取注冊(cè)中心對(duì)象
      2.2.3 RegistryFactory.getRegistry(registryConfig)
      //根據(jù)服務(wù)配置已經(jīng)用戶(hù)選擇發(fā)布的服務(wù)類(lèi)型初始化server對(duì)象倦微,目前sofa-rpc僅支持三種服務(wù)端,http、sofa-bolt正压、rest(netty-resteasy)
      2.2.4 Server server = serverConfig.buildIfAbsent();
      //注冊(cè)請(qǐng)求調(diào)用器(這里我們分析rest方式)
      2.2.5 server.registerProcessor(providerConfig, providerProxyInvoker)
        //初始化發(fā)布的服務(wù)bean欣福,并將上面初始化好的ProviderProxyInvoker對(duì)象通過(guò)字節(jié)增加jdk/javassist將Invoker對(duì)象動(dòng)態(tài)注入到bean里,ProviderProxyInvoker包含和服務(wù)發(fā)布后請(qǐng)求進(jìn)入的filterchain
        2.2.5.1 Object obj = ProxyFactory.buildProxy(providerConfig.getProxy(), providerConfig.getProxyClass(), instance);
        //通過(guò)netty resteasy進(jìn)行rest服務(wù)發(fā)布
        2.2.5.2 httpServer.getDeployment().getRegistry().addResourceFactory(new SofaResourceFactory(providerConfig, obj), serverConfig.getContextPath());
          //初始化SofaResteasyDeployment焦履,展示簡(jiǎn)單的重寫(xiě)了ResteasyDeployment的start方法拓劝,SynchronousDispatcher里重寫(xiě)同步分發(fā)器的Registry
          2.2.5.2.1 SynchronousDispatcher dis = new SofaSynchronousDispatcher(providerFactory)
          //往資源發(fā)布工廠添加一個(gè)自定義的節(jié)點(diǎn)
          2.2.5.2.2 SofaResourceMethodRegistry.addResourceFactory(ref, basePath)
      //生成rest接口服務(wù),這個(gè)sofa-rpc參照了jboss 的NettyJaxrsServer 嘉裤,重寫(xiě)了其start方法郑临,主要指支持了守護(hù)線程、支持epoll屑宠、支持線程池
      2.2.6 server.start()
      //監(jiān)聽(tīng)配置文件的變化厢洞,重新加載providerConfig對(duì)象的配置屬性,并重新發(fā)布rest服務(wù)
      2.2.7 providerConfig.setConfigListener(new ProviderAttributeListener())
      //根據(jù)發(fā)布配置典奉,將服務(wù)發(fā)布躺翻,目前支持Consul、Service Mesh秋柄、Nacos获枝、Zookeeper、Local骇笔、Mock方式
      //注冊(cè)服務(wù),這里就是接入各類(lèi)客戶(hù)端的初始化和注冊(cè),不過(guò)多贅述
      2.2.8 register();
         2.2.8.1 registry.init();
         2.2.8.2 registry.start();
         2.2.8.3 registry.register(providerConfig);

三笨触、總結(jié)

ProviderConfig:服務(wù)發(fā)布相關(guān)配置懦傍,維護(hù)了服務(wù)發(fā)布相關(guān)的基礎(chǔ)配置信息和服務(wù)發(fā)布后的相關(guān)服務(wù)信息維護(hù)
ProviderBootstrap:服務(wù)發(fā)布的實(shí)操啟動(dòng)類(lèi),提供對(duì)ProviderConfig各類(lèi)發(fā)布類(lèi)型的export和unexport
Registry:服務(wù)發(fā)布的真正的接口芦劣,目前sofa-rpc支持ConsulRegistry粗俱、LocalRegistry、MeshRegistry(并非service mesh虚吟,只是HTTP方式)寸认、NacosRegistry、ZookeeperRegistry串慰、MockTestRegistry(MockTestSlowRegistry)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末偏塞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子邦鲫,更是在濱河造成了極大的恐慌灸叼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庆捺,死亡現(xiàn)場(chǎng)離奇詭異古今,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)滔以,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)捉腥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人你画,你說(shuō)我怎么就攤上這事抵碟。” “怎么了撬即?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵立磁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我剥槐,道長(zhǎng)唱歧,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任粒竖,我火速辦了婚禮颅崩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕊苗。我一直安慰自己沿后,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布朽砰。 她就那樣靜靜地躺著尖滚,像睡著了一般喉刘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漆弄,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天睦裳,我揣著相機(jī)與錄音,去河邊找鬼撼唾。 笑死廉邑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的倒谷。 我是一名探鬼主播蛛蒙,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼渤愁!你這毒婦竟也來(lái)了牵祟?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤猴伶,失蹤者是張志新(化名)和其女友劉穎课舍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體他挎,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筝尾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了办桨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筹淫。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呢撞,靈堂內(nèi)的尸體忽然破棺而出损姜,到底是詐尸還是另有隱情,我是刑警寧澤殊霞,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布摧阅,位于F島的核電站,受9級(jí)特大地震影響绷蹲,放射性物質(zhì)發(fā)生泄漏棒卷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一祝钢、第九天 我趴在偏房一處隱蔽的房頂上張望比规。 院中可真熱鬧,春花似錦拦英、人聲如沸蜒什。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)灾常。三九已至霎冯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岗憋,已是汗流浹背肃晚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工锚贱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仔戈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓拧廊,卻偏偏與公主長(zhǎng)得像监徘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吧碾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容