Apollo 配置中心安装&使用
Apollo 配置中心安装&使用
做微服务有一段时间了,但是一直没有去碰配置中心这块,其实在微服务当中,配置中心至关重要,比如:网关的配置的更改、网关限流策略的变更、数据源的切换等等,同时也需要实现热加载,选来选去,就选择了最近比较流行的Apollo配置中心,以此文章记录学习笔记。
Apollo 简介
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。
Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。
详细介绍,请前往:Apollo-github
Apollo 本地安装
环境准备
- java: JDK 1.8.x
- maven:3.2.2
- mysql:5.7.18
- idea: 2019.1.3
- git : 2.10.0
- 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)。
http://localhost:8080 如果出现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 依赖
com.ctrip.framework.apollo
apollo-client
${apollo.client.version}
apollo 发布配置
登录apollo 配置中心
里面建了两个应用
- appId:001,是一些基础设施的配置,如Mysql/redis/mq等的连接配置,属于公共配置
- appId:clz-front-gateway,是一个网关的独立配置
appID:001的内容
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();
}
}
共有 0 条评论