<dependency>
<groupId>com.ctrip.framework.apollogroupId>
<artifactId>apollo-clientartifactId>
<version>1.1.0version>
dependency>
2、通过JVM启动参数指定metaServer的地址
-Dapollo.meta=http://localhost:8080
指定开发环境的metaServer地址:
-Ddev_meta=http://config-service-url
3、在项目中读取配置中心配置
Config config = ConfigService.getAppConfig();
// 读取配置中心参数:timeout 的值
String someKey = "timeout";
String someDefaultValue = "112";
String value = config.getProperty(someKey, someDefaultValue);
System.out.println(value);
// 实时监听配置中心属性的改变
config.addChangeListener(new ConfigChangeListener() {
public void onChange(ConfigChangeEvent changeEvent) {
System.out.println("Changes for namespace " + changeEvent.getNamespace());
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format("属性更新 - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
}
}
});
apollo:
meta: http://localhost:8080
bootstrap:
namespaces: dev
同时在application.yml中允许apollo配置的更新springIOC容器中的Bean的配置属性。
apollo:
bootstrap:
enabled: true
eagerLoad:
enabled: true
等价于在application.properties中配置:
apollo.bootstrap.enabled=true
# 把日志相关的配置(如logging.level.root=info或logback-spring.xml中的参数)也放在Apollo管理
apollo.bootstrap.eagerLoad=true
3、在spring bean中获取apollo配置中心配置
@Service
public class TestServiceImpl implements{
TestService {
// 获取apollo配置中心属性:weixin.pay.url的值
@Value("${weixin.pay.url}")
private String url;
}
4、apollo配置中心使用springboot自动配置原因分析
4.1 在apollo-client.jar包中,使用了springboot自动配置类
ApolloAutoConfiguration.java
package com.ctrip.framework.apollo.spring.boot;
import com.ctrip.framework.apollo.spring.config.ConfigPropertySourcesProcessor;
import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants;
import com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
// 当springboot配置文件中配置属性apollo.bootstrap.enabled有值时才会注入ApolloAutoConfiguration类的实例
@ConditionalOnProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED)
@ConditionalOnMissingBean(PropertySourcesProcessor.class)
public class ApolloAutoConfiguration {
@Bean
public ConfigPropertySourcesProcessor configPropertySourcesProcessor() {
return new ConfigPropertySourcesProcessor();
}
}
4.2 配置属性类:
package com.ctrip.framework.apollo.spring.config;
public interface PropertySourcesConstants {
String APOLLO_PROPERTY_SOURCE_NAME = "ApolloPropertySources";
String APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME = "ApolloBootstrapPropertySources";
// 默认启用apollo配置中心
String APOLLO_BOOTSTRAP_ENABLED = "apollo.bootstrap.enabled";
String APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED = "apollo.bootstrap.eagerLoad.enabled";
String APOLLO_BOOTSTRAP_NAMESPACES = "apollo.bootstrap.namespaces";
}
4.3 在apollo-client.jar的路径META-INF/spring.factories中,指定了springboot扫描哪些自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration
org.springframework.context.ApplicationContextInitializer=\
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer
org.springframework.boot.env.EnvironmentPostProcessor=\
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer
4.4 springboot启动项目时,会读取所有classpath下的META-INF/spring.factories,实例化包括apollo配置中心等所有自动配置的Bean,加入到IOC容器,包括类:ApolloApplicationContextInitializer。ApolloApplicationContextInitializer类,实现了spring上下文管理的接口:ApplicationContextInitializer,从而在实例化时会执行initialize()方法,通过获取apollo配置中心的配置信息,更新springIOC容器中的Bean的属性(使用了配置参数的属性)。
public class ApolloApplicationContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> , EnvironmentPostProcessor {
@Override
public void initialize(ConfigurableApplicationContext context) {
ConfigurableEnvironment environment = context.getEnvironment();
// 读取springboot配文件中的属性:apollo.bootstrap.eagerLoad.enabled
String enabled = environment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED, "false");
if (!Boolean.valueOf(enabled)) {
logger.debug("Apollo bootstrap config is not enabled for context {}, see property: ${{}}", context, PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED);
return;
}
logger.debug("Apollo bootstrap config is enabled for context {}", context);
//如果springboot配文件中的属性:apollo.bootstrap.eagerLoad.enabled为true,则获取apollo配置中心的配置信息,并更新springIOC容器中的Bean的属性(使用了配置参数的属性)。
initialize(environment);
}
我这里使用linux虚拟机(IP: 192.168.234.133)部署apolloserver,在本机(IP:192.168.68.1)中部署eureka server和mysql数据库。
下载github包:https://github.com/ctripcorp/apollo
或者码云包:https://gitee.com/nobodyiam/apollo
注意:配置apollo server连接数据库时,不要用使用默认的数据库管理员用户root,这样在虚拟机连接主机中的mysql时连接报错,应该使用创建一个新的管理员用户:
3.创建数据库连接用户
在数据库ApolloPortalDB和ApolloConfigDB中执行,创建新用户apollo/123456
GRANT ALL PRIVILEGES ON *.* TO 'apollo'@'%' IDENTIFIED BY '123456'
编译打包
1.修改\scripts\build.bat文件,设置数据库连接信息和启用的meta环境地址
2.执行\scripts\build.bat,打包后生成zip文件:
\apollo-adminservice\target\apollo-adminservice-1.5.0-SNAPSHOT-github.zip,
\apollo-configservice\target\apollo-configservice-1.5.0-SNAPSHOT-github.zip
\apollo-portal\target\apollo-portal-1.5.0-SNAPSHOT-github.zip
解压ZIP文件,设置logs目录
在configservice的解压目录下,修改apollo-configservice.conf,参数LOG_FOLDER设置为有文件创建权限的目录,比如:
LOG_FOLDER=/mnt/apollo/logs/100003171/,同时,修改scripts下的startup.sh文件里的LOG_FOLDER,改为相同的值。
同理,在portal的解压目录下,修改apollo-portal.conf和scripts下的startup.sh文件里的LOG_FOLDER参数。
同理,在adminservice的解压目录下,修改apollo-adminservice.conf和scripts下的startup.sh文件里的LOG_FOLDER参数。
确认解压后的数据库地址维护正确
1.ConfigService
2.AdminService
3.PortalService
修改eureka服务地址。在apolloconfigdb.serverconfig表中,设置eureka server的注册地址。http://192.168.68.1:9991/eureka/是我本机中的eureka server地址。
启动服务
1.启动configservice。执行startup.sh后,在eurekaserver中可以看到,configserver注册成功。
configservice web默认使用端口8080:
2.启动adminservice,启动后在eurekaserver注册中心可以看到adminservice。
adminservice web默认使用端口8090:
3.启动portal服务
portal web默认使用端口8070:
访问portal
1.在本机中访问虚拟机中的portal web服务,需要关闭虚拟机的防火墙
2.浏览器访问http://192.168.234.133:8070/signin(192.168.234.133为不是portal服务的虚拟机IP,8070为portal服务web端口)
默认用户名密码器:apollo/admin
登录成功后:
点击示例项目:SampleApp,进入它的配置界面:
DEV为环境名称,
application为namespace名称,
AppId为应用名称
添加配置项,可以勾选多个环境,比如DEV,TEST,表示该配置项在DEV和TEST环境都会使用该配置项。
配置项会保存在apolloconfigdb.item表中:
配置项在点击发布后才会生效:
在变更历史页签中,可以查看配置项的变更历史记录:
对应数据库表apolloconfigdb.commit表:
在发布历史中,可以查看配置项的发布历史记录:
对应数据库表apolloconfigdb.release表
apollo客户端验证
1.maven依赖与config配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.7.RELEASEversion>
<relativePath/>
parent>
<groupId>com.yxqgroupId>
<artifactId>springcloud-configclientartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springcloud-configclientname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<spring-cloud.version>Greenwich.SR2spring-cloud.version>
<apollo.client.version>1.1.0apollo.client.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.ctrip.framework.apollogroupId>
<artifactId>apollo-clientartifactId>
<version>${apollo.client.version}version>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
配置:application.yml
环境名称不区分大小写:dev=DEV
apollo.meta地址其实就是configserver的地址。但其作用是配置中心eureka client服务消费者,可以通过配置nginx域名转发做负载均衡,相当于通过网关访问配置中心接口。
spring:
profiles:
active: dev
app:
id: SampleApp
apollo:
bootstrap:
enabled: true
eagerLoad:
enabled: true
---
spring:
profiles: dev
apollo:
meta: http://192.168.234.133:8080
bootstrap:
namespaces: application
---
2.java代码中测试配置中心
启动项目后,在本地电脑C:\opt\data\SampleApp\config-cache目录下生成SampleApp+default+application.properties本地配置文件,即apollo客户端缓存文件。在apollo配置中心服务端不可用时,客户端会使用本地缓存文件。
java测试代码:
package com.yxq.springcloudconfigclient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/apollo")
public class TestApolloConfigClientController {
@Value("${yxq.test.url}")
String testurl;
@RequestMapping("/getTestUrl")
public String from(){
return "testurl="+testurl;
}
}