Apollo(1) 基本概念和Core包

一、相關(guān)概念:
  1. Portal Service:管理界面,從eureka獲取admin service地址下發(fā)配置,允許不同環(huán)境用一套portal
  2. Config Service:配置讀取、推送狭郑,服務(wù)于client腹暖,需要注冊(cè)到eureka
  3. Admin Service:配置修改汇在,發(fā)布,服務(wù)于portal脏答,需要注冊(cè)到eureka
  4. portalDB表:用戶糕殉、權(quán)限、角色等數(shù)據(jù)
  5. configDB表:配置數(shù)據(jù)殖告,給Admin和Config Service使用
  6. Meta Server:Meta Service給eureka做了http包裝阿蝶,Meta Server = config service + eureka放在了同一個(gè)進(jìn)程
  7. 配置分級(jí):app - env - cluster - namespace
  • app對(duì)應(yīng)一個(gè)業(yè)務(wù)項(xiàng)目
  • env代表環(huán)境,apollo預(yù)設(shè)好了如開(kāi)發(fā)環(huán)境dev黄绩、測(cè)試環(huán)境fat羡洁、正式環(huán)境pro等
  • cluster這個(gè)不一定用得到,代表項(xiàng)目某個(gè)環(huán)境會(huì)有多個(gè)集群的場(chǎng)景
  • namespace代表某個(gè)具體配置文件比如application.properties爽丹、xxx.properties
二筑煮、調(diào)用關(guān)系(github):
  1. image
三、部署樣例(github):
  1. image
四粤蝎、代碼部分apollo-core(v2.1.0-SNAPSHOT):
  1. Core包主要是兩個(gè)SPI和一個(gè)超時(shí)策略真仲,SPI一個(gè)用于獲取Meta Service地址,一個(gè)用于獲取apollo基礎(chǔ)參數(shù)配置初澎,這里不用太關(guān)注業(yè)務(wù)秸应,主要是了解SPI和超時(shí)策略的用法
  2. Meta Service發(fā)現(xiàn):獲取用戶手動(dòng)配置的meta服務(wù)器地址,提供途徑有多種見(jiàn)github
  3. Meta Service內(nèi)部有一個(gè)Eureka,Config Service和Admin Service啟動(dòng)時(shí)會(huì)注冊(cè)上去软啼,Client調(diào)用Config Service還有Portal調(diào)用Admin Service就要從Meta Service獲取地址
/**
* meta服務(wù)發(fā)現(xiàn)的SPI接口
*/
public interface MetaServerProvider extends Ordered {
    String getMetaServerAddress(Env targetEnv);
}
// core為各個(gè)環(huán)境提供服務(wù)桑谍,所以緩存了各個(gè)環(huán)境的meta地址
// client包實(shí)現(xiàn)只連用戶指定環(huán)境,只需要唯一的meta地址祸挪,后面會(huì)寫(xiě)到
public class LegacyMetaServerProvider implements MetaServerProvider {
    ... 
    private static final Map<Env, String> domains = new HashMap<>();
    ...
    // 初始化時(shí)取各個(gè)環(huán)境meta地址霉囚,存入domains,get方法比較簡(jiǎn)單略過(guò)了
    private void initialize() {
        Properties prop = new Properties();
        prop = ResourceUtils.readConfigFile("apollo-env.properties", prop);

        domains.put(Env.LOCAL, getMetaServerAddress(prop, "local_meta", "local.meta"));
        domains.put(Env.DEV, getMetaServerAddress(prop, "dev_meta", "dev.meta"));
        domains.put(Env.FAT, getMetaServerAddress(prop, "fat_meta", "fat.meta"));
        domains.put(Env.UAT, getMetaServerAddress(prop, "uat_meta", "uat.meta"));
        domains.put(Env.LPT, getMetaServerAddress(prop, "lpt_meta", "lpt.meta"));
        domains.put(Env.PRO, getMetaServerAddress(prop, "pro_meta", "pro.meta"));
    }

    // 從各個(gè)源獲找對(duì)應(yīng)數(shù)據(jù)匕积,順序如下
    private String getMetaServerAddress(Properties prop, String sourceName, String propName) {
        // 1\. 從System Property獲取
        String metaAddress = System.getProperty(sourceName);
        if (Strings.isNullOrEmpty(metaAddress)) {
            // 2\. 從env獲取
            metaAddress = System.getenv(sourceName.toUpperCase());
        } 
        if (Strings.isNullOrEmpty(metaAddress)) {
            // 3\. 從apollo-env.properties配置文件獲取
            metaAddress = prop.getProperty(propName);
        }
        return metaAddress;
    }
    ...
}
/**
* 根據(jù)env查詢meta服務(wù)地址盈罐,這里允許用戶指定多個(gè)meta服務(wù)地址用逗號(hào)分割
* 每分鐘會(huì)隨機(jī)取其中一個(gè)模擬負(fù)載均衡,比較簡(jiǎn)單就沒(méi)貼了闪唆,但最好還是nginx
*/
public class MetaDomainConsts {
    // 環(huán)境 -> meta地址
    private static final Map<Env, String> metaServerAddressCache = Maps.newConcurrentMap();

    // meta地址 -> 其中某個(gè)地址
    private static final Map<String, String> selectedMetaServerAddressCache = Maps.newConcurrentMap();
    ...

    // 按SPI順序獲取環(huán)境和meta對(duì)應(yīng)地址盅粪,存入metaServerAddressCache
    private static void initMetaServerAddress(Env env) {
        if (metaServerProviders == null) {
            synchronized (LOCK) {
                if (metaServerProviders == null) {
                    metaServerProviders = initMetaServerProviders();
                }
            }
        }

        String metaAddress = null;

        for (MetaServerProvider provider : metaServerProviders) {
            metaAddress = provider.getMetaServerAddress(env);
            if (!Strings.isNullOrEmpty(metaAddress)) {
                logger.info("Located meta server address {} for env {} from {}", metaAddress, env,
                            provider.getClass().getName());
                break;
            }
        }

        if (Strings.isNullOrEmpty(metaAddress)) {
            // Fallback to default meta address
            metaAddress = DEFAULT_META_URL;
            logger.warn(
                "Meta server address fallback to {} for env {}, because it is not available in all MetaServerProviders",
                metaAddress, env);
        }

        metaServerAddressCache.put(env, metaAddress.trim());
    }

    // 根據(jù)Order給meta SPI排序
    private static List<MetaServerProvider> initMetaServerProviders() {
        Iterator<MetaServerProvider> metaServerProviderIterator = ServiceBootstrap
            .loadAll(MetaServerProvider.class);

        List<MetaServerProvider> metaServerProviders = Lists.newArrayList(metaServerProviderIterator);

        metaServerProviders.sort(Comparator.comparingInt(Ordered::getOrder));

        return metaServerProviders;
    }
    ...
}
  1. Provider Manager SPI:和上面類似,Provider Manager可以獲取三種配置分別是app悄蕾、net票顾、server,常見(jiàn)的如appId帆调、env都包括在這奠骄,獲取配置途徑也類似就不貼代碼了
  2. 指數(shù)超時(shí)策略:很多框架都有類似的策略,通過(guò)失敗的次數(shù)指數(shù)性遞增超時(shí)時(shí)間
// 計(jì)算超時(shí)時(shí)間番刊,從0開(kāi)始遞增含鳞,每次失敗后<< 1直到設(shè)定上線,成功后重置芹务,用于Client查詢請(qǐng)求重試等
public class ExponentialSchedulePolicy implements SchedulePolicy {
  @Override
  public long fail() {
    long delayTime = lastDelayTime;

    if (delayTime == 0) {
      delayTime = delayTimeLowerBound;
    } else {
      delayTime = Math.min(lastDelayTime << 1, delayTimeUpperBound);
    }

    lastDelayTime = delayTime;

    return delayTime;
  }

  @Override
  public void success() {
    lastDelayTime = 0;
  }
}
五蝉绷、相關(guān)知識(shí)點(diǎn)
  • SPI:https://blog.csdn.net/lemon89/article/details/79189475
    • 類似于依賴注入,統(tǒng)一的接口枣抱,不同包里的實(shí)現(xiàn)通過(guò)META-INF/services下的文件配置聲明熔吗,可加載多個(gè)實(shí)現(xiàn)按需獲取,提升了擴(kuò)展性可插拔佳晶,在apollo里比如core包提供接口和默認(rèn)實(shí)現(xiàn)桅狠,各個(gè)服務(wù)里有具體實(shí)現(xiàn),使用時(shí)通過(guò)規(guī)劃優(yōu)先級(jí)獲取
  • spring.factory:https://blog.csdn.net/qq_43522770/article/details/117284372
    • spring.factory和SPI很相似轿秧,后面的Client包也會(huì)用到中跌,SPI是Java機(jī)制需要手動(dòng)Load,spring.factory是spring的機(jī)制自動(dòng)檢索加載并成為Bean
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末淤刃,一起剝皮案震驚了整個(gè)濱河市晒他,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逸贾,老刑警劉巖陨仅,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件津滞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡灼伤,警方通過(guò)查閱死者的電腦和手機(jī)触徐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狐赡,“玉大人撞鹉,你說(shuō)我怎么就攤上這事∮敝叮” “怎么了鸟雏?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)览祖。 經(jīng)常有香客問(wèn)我孝鹊,道長(zhǎng),這世上最難降的妖魔是什么展蒂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任又活,我火速辦了婚禮,結(jié)果婚禮上锰悼,老公的妹妹穿的比我還像新娘柳骄。我一直安慰自己,他們只是感情好箕般,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布耐薯。 她就那樣靜靜地躺著,像睡著了一般隘世。 火紅的嫁衣襯著肌膚如雪可柿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天丙者,我揣著相機(jī)與錄音,去河邊找鬼营密。 笑死械媒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的评汰。 我是一名探鬼主播纷捞,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼被去!你這毒婦竟也來(lái)了主儡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惨缆,失蹤者是張志新(化名)和其女友劉穎糜值,沒(méi)想到半個(gè)月后丰捷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寂汇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年病往,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骄瓣。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡停巷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出榕栏,到底是詐尸還是另有隱情畔勤,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布扒磁,位于F島的核電站硼被,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏渗磅。R本人自食惡果不足惜嚷硫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望始鱼。 院中可真熱鬧仔掸,春花似錦、人聲如沸医清。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)会烙。三九已至负懦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間柏腻,已是汗流浹背纸厉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留五嫂,地道東北人颗品。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像沃缘,于是被迫代替她去往敵國(guó)和親躯枢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • 配置中心 配置中心簡(jiǎn)介 說(shuō)到配置中心槐臀, 大家可能都不陌生锄蹂。我們攜程現(xiàn)在用的qconfig, 就是一個(gè)典型的配置中心...
    窩潘狂奔閱讀 7,978評(píng)論 0 3
  • 1.Apollo簡(jiǎn)介 Apollo 是由攜程開(kāi)發(fā)的得糜,開(kāi)源的分布式配置中心敬扛。Apollo支持不同環(huán)境,不同集群下的配...
    meicuosjiushiwo閱讀 1,735評(píng)論 0 1
  • 1.引言 Apollo(阿波羅)是攜程框架部門(mén)研發(fā)的分布式配置中心掀亩,能夠集中化管理應(yīng)用不同環(huán)境舔哪、不同集群的配置,配...
    圣杰閱讀 1,267評(píng)論 0 4
  • Apollo(阿波羅)是攜程開(kāi)源的分布式配置中心槽棍,能夠集中化管理應(yīng)用不同環(huán)境捉蚤、不同集群的配置,支持配置熱發(fā)布并實(shí)時(shí)...
    云時(shí)代的運(yùn)維開(kāi)發(fā)閱讀 1,154評(píng)論 0 1
  • 傳統(tǒng)應(yīng)用配置問(wèn)題 靜態(tài)配置傳統(tǒng)應(yīng)用的配置炼七,都是靜態(tài)配置缆巧,寫(xiě)在配置文件中,運(yùn)行時(shí)無(wú)法動(dòng)態(tài)修改豌拙,如果修改之后陕悬,就需要重...
    一生逍遙一生閱讀 3,449評(píng)論 0 1