攜程 apollo 分布式配置中心解決方案

背景

? ? 隨著程序功能的日益復(fù)雜妹蔽,系統(tǒng)的配置參數(shù)越來越多,應(yīng)用系統(tǒng)的配置信息變的越來越難以高效管理蔗喂。這里有兩個(gè)原因:

? ? 微服務(wù)的流行。隨著企業(yè)的發(fā)展高帖,用戶量的增長缰儿,應(yīng)用服務(wù)越來越多。這里的多有兩個(gè)方面:一方面是應(yīng)用服務(wù)的種類越來越多散址,另一方便是單一應(yīng)用服務(wù)走向集群部署乖阵。種類越來越多導(dǎo)致了應(yīng)用系統(tǒng)的配置參數(shù)分散在各個(gè)微服務(wù)中,如果配置信息發(fā)生變化预麸,則需要去修改對應(yīng)的應(yīng)用服務(wù)配置文件甚至需要去重啟服務(wù)瞪浸,這樣維護(hù)起來繁瑣吏祸,更重要的是容易出錯(cuò)。單一應(yīng)用服務(wù)走向集群部署贡翘,同樣當(dāng)配置信息發(fā)生變化時(shí),需要依次去修改集群中所有該服務(wù)的配置信息鸣驱,這樣會導(dǎo)致同一件事情重復(fù)的做泛鸟,就不符合互聯(lián)網(wǎng)要解決的根本問題:提升生產(chǎn)效率踊东,解放生產(chǎn)力。

? ? 企業(yè)級技術(shù)架構(gòu)的升級闸翅。企業(yè)在發(fā)展的各個(gè)階段再芋,需要形成與之相匹配相適應(yīng)的技術(shù)戰(zhàn)略布局用來服務(wù)于當(dāng)前的業(yè)務(wù)發(fā)展。在這個(gè)不斷變革升級的過程中缎脾,需要形成協(xié)同遗菠,高效,統(tǒng)一豁遭,管控有力的企業(yè)級具有戰(zhàn)略性的技術(shù)體系贺拣。因此捂蕴,分布式配置中心作為企業(yè)技術(shù)體系戰(zhàn)略布局中的重要一環(huán)闪幽,在滿足以往業(yè)務(wù)在迭代中要分環(huán)境,可用的硬性要求的同時(shí)溉知,還需要形成新的生命力腕够。這個(gè)新的生命力就是:安全可靠帚湘,權(quán)限可控,維護(hù)簡單捅厂,能夠熱修改底挫。

? ? 攜程的開源項(xiàng)目 apollo 無疑是一把提供企業(yè)分布式配置中心解決方案的利器脸侥。今天我們就來分享一下基于 攜程開源項(xiàng)目 apollo 的分布式配置中心解決方案睁枕。

需求分析

? ?在應(yīng)用服務(wù)的開發(fā)過程中為了軟件的快速迭代,我們通常會隔離出3套環(huán)境:dev(開發(fā)環(huán)境)外遇,fat(測試環(huán)境)跳仿,pro(生產(chǎn)環(huán)境)。不同的軟件環(huán)境對系統(tǒng)的穩(wěn)定性和可靠性的要求不同妄辩,通常我們對生產(chǎn)環(huán)境的穩(wěn)定性和可靠性要求是苛刻的山上,而開發(fā)和測試環(huán)境則相對略低。本著在能滿足要求的情況下哮伟,最低成本的原則我們來分配資源來搭建環(huán)境。

資源分配

機(jī)器 IP 環(huán)境 部署應(yīng)用 數(shù)據(jù)庫
apollo01(192.168.0.111) pro (生產(chǎn)環(huán)境) protal ProtalDB
apollo02(192.168.0.112) pro (生產(chǎn)環(huán)境) config,admin ConfigDB_Pro
apollo03(192.168.0.113) pro (生產(chǎn)環(huán)境) config,admin ConfigDB_Pro
apollo04(192.168.0.114) dev (開發(fā)環(huán)境) config,admin ConfigDB_Dev
apollo05(192.168.0.115) fat (測試環(huán)境) config,admin ConfigDB_Fat

說明:
1.apollo依賴于注冊中心eureka池凄,這里還需要搭建 dev修赞,fat桑阶,pro 三套環(huán)境的注冊中心。注冊中心可以搭建高單機(jī)版或高可用版割择,這個(gè)并非本次演示重點(diǎn)萎河,這里不再做具體搭建說明虐杯。
2.apollo依賴與mysql數(shù)據(jù)庫,這里也不再做具體搭建說明擎椰。通常生產(chǎn)環(huán)境建議使用高可用版本的數(shù)據(jù)庫达舒。

apollo 分布式配置中心拓?fù)鋱D

環(huán)境搭建

1.初始化數(shù)據(jù)庫:

ProtalDB數(shù)據(jù)庫執(zhí)行腳本:apolloportaldb.sql
ConfigDB_Pro, ConfigDB_Dev, ConfigDB_Fat 數(shù)據(jù)庫執(zhí)行sql腳本:apolloconfigdb.sql
注意:數(shù)據(jù)庫名要和 sql 腳本中的庫名保持一致巩搏。

2.下載 apollo 源碼 并打包:
apollo打包成功
3.將對應(yīng)的zip包分別上傳到對應(yīng)的服務(wù)器目錄下:
機(jī)器 環(huán)境 上傳zip zip上傳位置
apollo01 pro (生產(chǎn)環(huán)境) apollo-protal-1.7.0.zip /opt/apollo/protal
apollo02 pro (生產(chǎn)環(huán)境) apollo-adminservice-1.7.0.zip 和 apollo-configservice-1.7.0.zip /opt/apollo/configservice 和 /opt/apollo/adminservice
apollo03 pro (生產(chǎn)環(huán)境) apollo-adminservice-1.7.0.zip 和 apollo-configservice-1.7.0.zip /opt/apollo/configservice 和 /opt/apollo/adminservice
apollo04 dev (開發(fā)環(huán)境) apollo-adminservice-1.7.0.zip 和 apollo-configservice-1.7.0.zip /opt/apollo/configservice 和 /opt/apollo/adminservice
apollo05 fat (測試環(huán)境) apollo-adminservice-1.7.0.zip 和 apollo-configservice-1.7.0.zip /opt/apollo/configservice 和 /opt/apollo/adminservice
4.注冊中心:
環(huán)境 key Value
pro (生產(chǎn)環(huán)境) eureka.service.url http://1.1.1.1:8080/eureka/
dev (開發(fā)環(huán)境) eureka.service.url http://1.1.1.2:8080/eureka/
fat (測試環(huán)境) eureka.service.url http://1.1.1.3:8080/eureka/
5.修改相應(yīng)的配置文件:
配置apollo-portal的meta service信息:

? ? Apollo Portal需要在不同的環(huán)境訪問不同的meta service(apollo-configservice)地址丰辣,所以我們需要在配置中提供這些信息禽捆。默認(rèn)情況下,meta service和config service是部署在同一個(gè)JVM進(jìn)程得湘,所以meta service的地址就是config service的地址顿仇。
修改完的效果如下:

dev.meta = http://apollo02:8080,http://apollo03:8080
fat.meta = http://apollo04:8080
pro.meta = http://apollo05:8080
配置apollo-adminservice的數(shù)據(jù)庫連接信息:

解壓apollo-adminservice-x.x.x-github.zip
打開config目錄下的application-github.properties文件
填寫正確的ApolloConfigDB數(shù)據(jù)庫連接串信息摆马,注意用戶名和密碼后面不要有空格!
改完的效果如下:

# DataSource
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = someuser
spring.datasource.password = somepwd

注:由于ApolloConfigDB在每個(gè)環(huán)境都有部署囤采,所以對不同的環(huán)境admin-service需要配置對應(yīng)環(huán)境的數(shù)據(jù)庫參數(shù)

配置apollo-configservice的數(shù)據(jù)庫連接信息:

解壓apollo-adminservice-x.x.x-github.zip
用程序員專用編輯器(如vim惩淳,notepad++思犁,sublime等)打開config目錄下的application-github.properties文件
填寫正確的ApolloConfigDB數(shù)據(jù)庫連接串信息,注意用戶名和密碼后面不要有空格!
修改完的效果如下:

# DataSource
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = someuser
spring.datasource.password = somepwd

注:由于ApolloConfigDB在每個(gè)環(huán)境都有部署棉磨,所以對不同的環(huán)境admin-service需要配置對應(yīng)環(huán)境的數(shù)據(jù)庫參數(shù)

配置apollo-portal的數(shù)據(jù)庫連接信息:

解壓apollo-portal-x.x.x-github.zip
打開config目錄下的application-github.properties文件
填寫正確的ApolloAdminDB數(shù)據(jù)庫連接串信息学辱,注意用戶名和密碼后面不要有空格!
修改完的效果如下:

# DataSource
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloAdminDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = someuser
spring.datasource.password = somepwd
調(diào)整ApolloConfigDB配置:

? ? 不管是apollo-configservice還是apollo-adminservice都需要向eureka服務(wù)注冊策泣,所以需要配置eureka服務(wù)地址。 按照目前的實(shí)現(xiàn)统抬,apollo-configservice本身就是一個(gè)eureka服務(wù)任洞,所以只需要填入apollo-configservice的地址即可发侵,如有多個(gè),用逗號分隔(注意不要忘了/eureka/后綴)盅弛。

在PRO環(huán)境的ApolloConfigDB.ServerConfig表中設(shè)置eureka.service.url為:

http://1.1.1.1:8080/eureka/

在DEV環(huán)境的ApolloConfigDB.ServerConfig表中設(shè)置eureka.service.url為:

http://1.1.1.2:8080/eureka/

在FAT環(huán)境的ApolloConfigDB.ServerConfig表中設(shè)置eureka.service.url為:

http://1.1.1.3:8080/eureka/
6.啟動各個(gè)服務(wù):

啟動apollo01上的protal

bash /opt/apollo/protal/scripts/startup.sh

啟動apollo02挪鹏,apollo03愉烙,apollo04,apollo05上的 configservice

bash /opt/apollo/configservice/scripts/startup.sh

啟動apollo02返顺,apollo03,apollo04振乏,apollo05上的 adminservice

bash /opt/apollo/adminservice/scripts/startup.sh

使用說明

系統(tǒng)啟動成功后可以訪問 apollo 配置中心的管理頁面:http://apollo01:8070
注意:需要將 url 中的 apollo01 替換成你部署 protal 的機(jī)器IP

apollo 配置中心的管理頁面

首次登陸的用戶名是:apollo 密碼:admin
Apollo使用指南

基于springboot的apollo客戶端使用方式

1.引入 apollo 客戶端依賴包

 <dependency>
      <groupId>com.ctrip.framework.apollo</groupId>
      <artifactId>apollo-client</artifactId>
      <version>1.4.0</version>
</dependency>

2.在springboot的啟動程序上添加開啟 @EnableApolloConfig 注解:

@SpringBootApplication
@EnableApolloConfig
public class ApolloApplication {

  public static void main(String[] args) {
    SpringApplication.run( ApolloApplication.class, args );
  }
}

3.修改yml配置文件慧邮,因?yàn)槲疫@里有dev(開發(fā)環(huán)境)舟陆,fat(測試環(huán)境)秦躯,pro(生產(chǎn)環(huán)境) 三套環(huán)境,具體配置如下:
基礎(chǔ)配置文件:application.yml

spring:
  profiles:
    ## 使用 pro 環(huán)境
    active: pro

app:
  id: message

apollo:
  bootstrap:
    enabled: true
    ## 添加使用到的 namespace
    namespaces: application,grobal
    eagerLoad:
      enabled: true
  autoUpdateInjectedSpringProperties: true

dev(開發(fā)環(huán)境): application-dev.yml

apollo:
  meta: http://192.168.0.114:8080

fat(測試環(huán)境):application-fat.yml

apollo:
  meta: http://192.168.0.115:8080

fat(生產(chǎn)環(huán)境):application-pro.yml 高可用配置

apollo:
  meta: http://192.168.0.112:8080,http://192.168.0.113:8080

4.使用@Value注解引入apollo中配置的屬性:

@RestController
@RequestMapping("/message")
public class ApolloController {

  @Value("${environmet}")
  private String environment;

  @Value("${grobal.user.name}")
  private String name;

  @Value("${grobal.user.phone}")
  private String phone;

  @Value("${grobal.user.id}")
  private String id;

  @Value("${user.alias:UNDEFINED}")
  private String alias;

    @GetMapping("/getInfo")
  public String getInfo() {
    return "ApolloController{" +
            "environment='" + environment + '\'' +
            ", name='" + name + '\'' +
            ", phone='" + phone + '\'' +
            ", id='" + id + '\'' +
            ", alias='" + alias + '\'' +
            '}';
  }


  public String getEnvironment() {
    return environment;
  }

  public void setEnvironment(String environment) {
    this.environment = environment;
  }

 public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getPhone() {
    return phone;
  }

  public void setPhone(String phone) {
    this.phone = phone;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getAlias() {
    return alias;
  }

  public void setAlias(String alias) {
    this.alias = alias;
  }

}

5.注冊監(jiān)聽器,監(jiān)聽apollo中屬性配置的變化:
@ApolloConfigChangeListener 監(jiān)聽的是默認(rèn)的 namespace毡琉,如果需要監(jiān)聽指定的namespace 需要加入指定妙色。

@Component
public class ApolloChangeListener {
  
  @ApolloConfigChangeListener("application")
  private void someChangeHandler1(ConfigChangeEvent changeEvent) {
    for (String key : changeEvent.changedKeys()) {
      ConfigChange change = changeEvent.getChange(key);
      System.out.println(String.format(
              "Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
              change.getPropertyName(), change.getOldValue(),
              change.getNewValue(), change.getChangeType()));
    }
  }

  @ApolloConfigChangeListener("grobal")
  private void someChangeHandler2(ConfigChangeEvent changeEvent) {
    for (String key : changeEvent.changedKeys()) {
      ConfigChange change = changeEvent.getChange(key);
      System.out.println(String.format(
              "Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
              change.getPropertyName(), change.getOldValue(),
              change.getNewValue(), change.getChangeType()));
    }
  }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末身辨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子号俐,更是在濱河造成了極大的恐慌定庵,老刑警劉巖蔬浙,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異笨忌,居然都是意外死亡俱病,警方通過查閱死者的電腦和手機(jī)杂曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門擎勘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颖榜,“玉大人,你說我怎么就攤上這事噪漾∏遗睿” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵诈胜,是天一觀的道長焦匈。 經(jīng)常有香客問我昵仅,道長,這世上最難降的妖魔是什么够滑? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任吕世,我火速辦了婚禮寞冯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吮龄。我一直安慰自己漓帚,他們只是感情好午磁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昧辽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪红氯。 梳的紋絲不亂的頭發(fā)上咕痛,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天茉贡,我揣著相機(jī)與錄音,去河邊找鬼放椰。 笑死愉粤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的藻烤。 我是一名探鬼主播头滔,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兴猩!你這毒婦竟也來了早歇?” 一聲冷哼從身側(cè)響起箭跳,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎借尿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狈癞,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茂契,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年掉冶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疼邀。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旁振,死狀恐怖涨岁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梢薪,我是刑警寧澤秉撇,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站规阀,受9級特大地震影響瘦麸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厉碟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一箍鼓、第九天 我趴在偏房一處隱蔽的房頂上張望勿她。 院中可真熱鬧,春花似錦逢并、人聲如沸砍聊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俯树。三九已至,卻和暖如春阳欲,著一層夾襖步出監(jiān)牢的瞬間陋率,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工筒愚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菩浙,地道東北人劲蜻。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像倔约,于是被迫代替她去往敵國和親坝初。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

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