1. 程式人生 > 實用技巧 >SpringCloud入門實戰(3)-Apollo使用

SpringCloud入門實戰(3)-Apollo使用

Apollo(阿波羅)是攜程框架部門研發的分散式配置中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,並且具備規範的許可權、流程治理等特性,適用於微服務配置管理場景。本文主要介紹Apollo的基本使用,文中使用到的軟體版本:Apollo 1.7.0、Spring Boot 2.2.5.RELEASE、Spring Cloud Hoxton.SR3、Java 1.8.0_191、 Mysql 5.7.26。

1、apollo架構

  • Config Service提供配置的讀取、推送等功能,服務物件是Apollo客戶端
  • Admin Service提供配置的修改、釋出等功能,服務物件是Apollo Portal(管理介面)
  • Config Service和Admin Service都是多例項、無狀態部署,所以需要將自己註冊到Eureka中並保持心跳
  • 在Eureka之上我們架了一層Meta Server用於封裝Eureka的服務發現介面
  • Client通過域名訪問Meta Server獲取Config Service服務列表(IP+Port),而後直接通過IP+Port訪問服務,同時在Client側會做load balance、錯誤重試
  • Portal通過域名訪問Meta Server獲取Admin Service服務列表(IP+Port),而後直接通過IP+Port訪問服務,同時在Portal側會做load balance、錯誤重試
  • 為了簡化部署,我們實際上會把Config Service、Eureka和Meta Server三個邏輯角色部署在同一個JVM程序中

2、服務端部署

2.1、環境

Apollo可以管理不同環境的配置:
DEV 開發環境
FAT 測試環境,相當於alpha環境(功能測試)
UAT 整合環境,相當於beta環境(迴歸測試)
PRO 生產環境

Apollo裡不同元件部署方式不一樣:

a、Portal只需部署一套,通過它來管理DEV、FAT、UAT、PRO等環境的配置
b、Meta Server、Config Service和Admin Service在每個環境都單獨部署,使用獨立的資料庫
c、Meta Server和Config Service部署在一個JVM程序中

2.2、部署步驟

2.2.1、規劃

假設所有服務都部署在10.49.196.10上,並都使用預設的埠:

服務 部署目錄
apollo-configservice 8080 /home/hadoop/app/apollo/apollo-configservice
apollo-adminservice 8090 /home/hadoop/app/apollo/apollo-adminservice
apollo-portal 8070 /home/hadoop/app/apollo/apollo-portal

2.2.1、建立ApolloPortalDB

通過Mysql客戶端匯入資料庫的初始化指令碼:

https://github.com/ctripcorp/apollo/blob/master/scripts/sql/apolloportaldb.sql

2.2.2、建立ApolloConfigDB

通過Mysql客戶端匯入資料庫的初始化指令碼:

https://github.com/ctripcorp/apollo/blob/master/scripts/sql/apolloconfigdb.sql

2.2.3、下載並解壓安裝包

https://github.com/ctripcorp/apollo/releases下載adminservice、configservice、portal三個包,如下載1.7.0版本的安裝包:apollo-adminservice-1.7.0-github.zip、apollo-configservice-1.7.0-github.zip、apollo-portal-1.7.0-github.zip。把三個安裝包放到三個單獨的目錄(apollo-adminservice、apollo-configservice、apollo-portal)裡,然後解壓:

cd apollo-adminservice
unzip apollo-adminservice-1.7.0-github.zip

cd apollo-configservice
unzip apollo-configservice-1.7.0-github.zip

cd apollo-portal
unzip apollo-portal-1.7.0-github.zip

2.2.4、配置修改

2.2.4.1、ApolloPortalDB配置

配置項統一儲存在ApolloPortalDB.ServerConfig表中,也可以通過管理員工具 - 系統引數頁面進行配置,無特殊說明則修改完一分鐘實時生效。

apollo.portal.envs 可支援的環境列表 預設值是dev,如果portal需要管理多個環境的話,以逗號分隔即可(大小寫不敏感),如:DEV,FAT,UAT,PRO
apollo.portal.meta.servers 各環境Meta Service列表 Apollo Portal需要在不同的環境訪問不同的meta service(apollo-configservice)地址,該配置優先順序高於其它方式設定的Meta Service地址

2.2.4.2、ApolloConfigDB配置

配置項統一儲存在ApolloConfigDB.ServerConfig表中,需要注意每個環境的ApolloConfigDB.ServerConfig都需要單獨配置,修改完一分鐘實時生效。

eureka.service.url Eureka服務Url apollo-configservice本身就是一個eureka服務,所以只需要填入apollo-configservice的地址即可,如有多個,用逗號分隔

2.2.4.3、配置資料庫連線資訊

修改apollo-configservice、apollo-adminservice、apollo-portal三個應用包中config/application-github.properties配置檔案,配置資料庫連線:

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

2.2.4.4、修改腳本里的日誌檔案路徑

修改apollo-configservice、apollo-adminservice、apollo-portal三個應用包中scripts/startup.sh啟動指令碼,修改日誌檔案路徑:

LOG_DIR=/opt/logs/100003171

2.2.4.5、修改樣例

ApolloPortalDB.ServerConfig,配置了dev和pro環境,並指向了同一個meta地址

ApolloConfigDB.ServerConfig:

config/application-github.properties:

spring.datasource.url = jdbc:mysql://10.49.196.10:3306/ApolloConfigDB?characterEncoding=utf8
spring.datasource.username = admin
spring.datasource.password = Root_123!

scripts/startup.sh

#apollo-configservice/scripts/startup.sh
LOG_DIR=/home/hadoop/app/appolo/apollo-configservice/scripts/logs

#apollo-adminservice/scripts/startup.sh
LOG_DIR=/home/hadoop/app/appolo/apollo-adminservice/scripts/logs

#apollo-portal/scripts/startup.sh
LOG_DIR=/home/hadoop/app/appolo/apollo-portal/scripts/logs

2.2.5、啟動各應用

cd apollo-configservice/scripts
./startup.sh

cd apollo-adminservice/scripts
./startup.sh

cd apollo-portal/scripts
./startup.sh

2.2.6、portal控制檯

http://10.49.196.10:8070/

在控制檯先建立專案,在專案裡先選擇環境,預設會有一個application的namespace,可以建立新的namespace,建立的namespace可以設定為public或private,public的namespace可以被其他的專案關聯,private的只能本專案訪問,客戶端訪問的時候需指定namespace。

3、客戶端使用

3.1、引入依賴

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

3.2、修改application.yml

app:
  id: general

apollo:
  meta: http://10.49.196.10:8080
  bootstrap:
    enabled: true
    namespaces: application,db,sms

3.3、在控制檯增加配置資訊

建立一個general的專案,裡面有一個預設的namespace(application),一個關聯其他專案(public)的公共namespce(db),一個新增的namespace(sms):

3.4、編寫controller

package com.inspur.scdemo.general.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@RestController
public class HelloController {
    private static Logger logger = LoggerFactory.getLogger(HelloController.class);

    @Value( "${spring.application.name}" )
    private String applicationName;
    @Value( "${server.port}" )
    private String applicationPort;

    @Value("${spring.datasource.url}")
    private String dbUrl;
    @Value("${spring.datasource.driverClassName}")
    private String dbDriverClassName;

    @Value("${sms.host}")
    private String smsHost;
    @Value("${sms.port}")
    private String smsPort;

    @GetMapping("getInfo")
    public Map<String, Properties> getInfo() {
        logger.debug("getInfo start....");
        Properties application = new Properties();
        application.setProperty("name", applicationName);
        application.setProperty("port", applicationPort);

        Properties db = new Properties();
        db.setProperty("url", dbUrl);
        db.setProperty("driverClassName", dbDriverClassName);

        Properties sms = new Properties();
        sms.setProperty("host", smsHost);
        sms.setProperty("port", smsPort);

        Map<String, Properties> info = new HashMap<>();
        info.put("application", application);
        info.put("db", db);
        info.put("sms", sms);

        logger.debug("getInfo end.");

        return info;
    }
}

3.5、驗證

啟動應用後並訪問controller可以看到獲取到相關資訊:

3.6、監控配置項變化

package com.inspur.scdemo.general.config;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;


@Configuration
public class ApolloConf {
    private static Logger logger = LoggerFactory.getLogger(ApolloConf.class);

    //inject config for namespace application
    @ApolloConfig("application")
    private Config anotherConfig;

    /**config change listener for namespace application*/
    @ApolloConfigChangeListener
    public void configChangeListter(ConfigChangeEvent changeEvent) {
        logger.info("配置改變。。。");
        String item = "someItem";
        if (changeEvent.isChanged(item)) {
            ConfigChange configChange = changeEvent.getChange(item);
            logger.info(item + "配置項改變,oldValue={},newValue={}", configChange.getOldValue(), configChange.getNewValue());
        }
    }
}