Apollo 配置中心安装&使用

Apollo 配置中心安装&使用

做微服务有一段时间了,但是一直没有去碰配置中心这块,其实在微服务当中,配置中心至关重要,比如:网关的配置的更改、网关限流策略的变更、数据源的切换等等,同时也需要实现热加载,选来选去,就选择了最近比较流行的Apollo配置中心,以此文章记录学习笔记。

Apollo 简介

Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。

Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。

.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。

详细介绍,请前往:Apollo-github

Apollo 本地安装

环境准备

  1. java: JDK 1.8.x
  2. maven:3.2.2
  3. mysql:5.7.18
  4. idea: 2019.1.3
  5. git : 2.10.0
  6. apollo: 1.4.0

以上是我本机的环境,以及各个组件对应的版本,其中 除了 idea 、git 外,其他都是必须的,请查缺补漏的部署环境。

安装包下载

方式一(需要安装git/idea或者eclipse):

直接从 Apollo-github 下载最新的源码(当前最新:v1.4.0),通过git clone 命令将源码下载到本地:

git clone https://github.com/ctripcorp/apollo

方式二:

直接去官方下载最新的安装包,下载地址如下:

https://github.com/ctripcorp/apollo/releases

注意,本人是使用方式一,进行下载。

创建数据库

数据库版本要求,5.6.5+,本机环境,mysql 版本为:5.7.18。

查看数据库版本:

SHOW VARIABLES WHERE Variable_name = 'version';
Variable_name Value
version 5.7.18-log

创建以下两个数据库并导入初始化数据:

  • ApolloConfigDB
  • ApolloPortalDB

ApolloConfigDB 所在的文件目录:

${your_file_directory}\apollo\scripts\db\migration\configdb

ApolloPortalDB

${your_file_directory}\apollo\scripts\db\migration\portaldb

在MySQL数据库中执行这两个SQL文件,完成数据库的创建和数据的初始化操作。

打包项目(build package)

将下载下来的 apollo 源码导入到idea中,我们需要关注的几个项目:

apollo-configservice apollo-adminservice apollo-protal
配置服务(meta server、eureka) 配置管理服务 apollo管理UI

找到 /apollo/scripts/build.bat(Linux 是 bulid.sh)

@echo off

rem apollo config db info
set apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8"
set apollo_config_db_username="root"
set apollo_config_db_password=""

rem apollo portal db info
set apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8"
set apollo_portal_db_username="root"
set apollo_portal_db_password=""

rem meta server url, different environments should have different meta server addresses
set dev_meta="http://localhost:8080"
set fat_meta="http://someIp:8080"
set uat_meta="http://anotherIp:8080"
set pro_meta="http://yetAnotherIp:8080"

set META_SERVERS_OPTS=-Ddev_meta=%dev_meta% -Dfat_meta=%fat_meta% -Duat_meta=%uat_meta% -Dpro_meta=%pro_meta%

rem =============== Please do not modify the following content ===============
rem go to script directory
cd "%~dp0"

cd ..

rem package config-service and admin-service
echo "==== starting to build config-service and admin-service ===="

call mvn clean package -DskipTests -pl apollo-configservice,apollo-adminservice -am -Dapollo_profile=github -Dspring_datasource_url=%apollo_config_db_url% -Dspring_datasource_username=%apollo_config_db_username% -Dspring_datasource_password=%apollo_config_db_password%

echo "==== building config-service and admin-service finished ===="

echo "==== starting to build portal ===="

call mvn clean package -DskipTests -pl apollo-portal -am -Dapollo_profile=github,auth -Dspring_datasource_url=%apollo_portal_db_url% -Dspring_datasource_username=%apollo_portal_db_username% -Dspring_datasource_password=%apollo_portal_db_password% %META_SERVERS_OPTS%

echo "==== building portal finished ===="

pause

更改数据库连接配置

rem apollo config db info
set apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8"
set apollo_config_db_username="root"
set apollo_config_db_password="123456"

rem apollo portal db info
set apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8"
set apollo_portal_db_username="root"
set apollo_portal_db_password="123456"

更改 meta server(apollo-configservice/apollo-erueka) 地址

set dev_meta="http://localhost:8080"
set fat_meta="http://someIp:8080"
set uat_meta="http://anotherIp:8080"
set pro_meta="http://yetAnotherIp:8080"

修改完上面的配置之后,执行build.bat 批处理命令文件进行编译打包,在执行的过程中可能会出现一些异常(一般是maven依赖异常),自行百度解决之后,再重新执行。

打包成功之后,找到 apollo-configservice、apollo-adminservice、apollo-portal 下的 target 目录(build是执行 maven 的 package 命令),找到已经打好的三个jar包,copy 出来放到一个单独的目录(方便启动)。

进入jar 的当前目录,==依次==启动apollo-configservice、apollo-adminservice、apollo-portal 三个服务。

java -jar apollo-configservice-1.5.0-SNAPSHOT.jar
java -jar apollo-adminservice-1.5.0-SNAPSHOT.jar
java -jar apollo-portal-1.5.0-SNAPSHOT.jar

全部启动完成之后,打开浏览器输入:

http://localhost:8070 如果出现apollo 的登录界面,说明已经启动成功(登录名/密码:apollo/admin)。

Apollo-portal登录界面

http://localhost:8080 如果出现eureka 的管理界面,说明服务启动正常。

apollo-configservice/eureka界面

Apollo 集群部署

Apollo 的使用(Java)

持续更新使用案例

拿spring boot 项目简单直白地说一下配置刷新的原理;spring boot 项目都有一个 application.yml/properties 的应用配置文件,里面写了各种配置,如:datasource 的连接、redis 连接、mq连接、server.port、application.name 、网关配置等等吧。

在spring boot 项目启动的时候,会将这些配置加载到相应的类里面,如:spring.datasource 的配置会在datasource 初始化的时候,将这类配置注入到DataSourceProperties.java 相对应的属性里面,从而实现数据源的实例。

那么目前使用Apollo 需要做到,这类的配置文件,从Apollo的配置中心拉取,而且,在Apollo 变更某一个属性可以做到不重启应用就生效的目的。那么我们需要怎么做呢?

应用需要监听Apollo 上面的配置的内容改变(配置改变发布),去刷新这类的xxxProperties.java 类,然后重新编译该配置的client端。

例如,刷新DataSourceProperties.java 的属性配置,然后通过反射重新编译DataSource 应用,通过最新的配置重新初始化实例,那么后面调用DataSource的client端就是使用最新的配置。

引入apollo-client 依赖

<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>${apollo.client.version}</version>
</dependency>

apollo 发布配置

登录apollo 配置中心


apollo配置中心主页

里面建了两个应用

  • appId:001,是一些基础设施的配置,如Mysql/redis/mq等的连接配置,属于公共配置
  • appId:clz-front-gateway,是一个网关的独立配置

appID:001的内容

App.id:001配置内容

clz-front-gateway 的配置内容


App.id:clz-front-gateway

spring boot 使用apollo 管理配置

在spring boot 中使用 apollo 的配置非常简单,在application.yml/properties中设置app.id、apollo.meta以及指定命名空间即可。

application.yml 配置

app:
  id: front-gateway
apollo:
  meta: http://localhost:8080
  bootstrap:
    enabled: true
    namespaces: PC.datasource-mysql-config.yml,clz-front-gateway.yml

spring boot 启动类,启动 @EnableApolloConfig

@SpringBootApplication
@EnableEurekaClient
@Slf4j
@EnableApolloConfig
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
        log.info("application web started.");
    }
}


这样就可以从 meta: http://localhost:8080 (apollo-configservice)中拉取 PC.datasource-mysql-config.yml,clz-front-gateway.yml 这两个命名空间的配置了。

Apollo 实现 Mysql DataSource 热加载

新增一个DataSourceConfig 类处理配置的热加载

package com.ph.framework.core.config;

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * @ClassName DataSourceConfig
 * @Description 数据源刷新配置
 * @Author rongqin.he
 * @Date 2019/7/30 0030
 * @Version 1.0
 **/
@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
@Slf4j
public class DataSourceConfig {


    @RefreshScope
    @Bean("dataSource_Bean")
    public DataSource dataSource(DataSourceProperties dataSourceProperties){
        return dataSourceProperties.initializeDataSourceBuilder().build();
    }

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private org.springframework.cloud.context.scope.refresh.RefreshScope refreshScope;

    /***
     * 监听apollo 的配置变更
     * @Param [configChangeEvent]
     * @return void
     * @Author rongqin.he
     * @Date 2019/8/1 0001
     **/
    @ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION,"PC.datasource-mysql-config"},interestedKeyPrefixes = {"spring.datasource"})
    public void onChange(ConfigChangeEvent configChangeEvent){
        // 重新编译DataSource 初始化bean
        refreshScope.refresh("dataSource_Bean");
        log.info("Apollo config changed {}",applicationContext.getBean(DataSourceProperties.class).toString());

    }
}

Apollo 实现 Redisson 热加载

Apollo 实现 Zuul 动态路由

新增zuul配置变更监听

/**
 * @ClassName ZuulPropertiesRefresher
 * @Description Apollo 配置刷新类
 * @Author rongqin.he
 * @Date 2019/7/29 0029
 * @Version 1.0
 **/
@Component
@Slf4j
public class ZuulPropertiesRefresher {

    @Autowired
    private RefreshScope refreshScope;

    @Autowired
    private ZuulProperties zuulProperties;

    @ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION,"zuul-rout-config"},interestedKeyPrefixes = "zuul.")
    private void onChange(ConfigChangeEvent configChangeEvent){
        log.info("Apollo config change - Before refresh {}", zuulProperties);
        refreshScope.refresh("ZuulProperties_bean");
        log.info("Apollo config change - After refresh {}", zuulProperties);
    }
    
    @Bean("ZuulProperties_bean")
    @ConfigurationProperties("zuul")
    @RefreshScope
    @Primary
    public ZuulProperties zuulProperties(){
        return new ZuulProperties();
    }

}

Apollo 实现 Spring Security 白名单

Apollo 实现 RabbitMq配置 热加载

Apollo 实现 ES 热加载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341