Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
本篇博客介绍如何启动Apollo,着重阐述了如何SpringBoot集成,另外介绍了@ConfigurationProperties的使用姿势。
相关的代码开源如下:
1.如何启动Apollo;
2.如何SpringBoot集成;
3.@ConfigurationProperties的使用姿势;
https://www.apolloconfig.com/#/zh/deployment/quick-start
https://github.com/apolloconfig/apollo/wiki
Quick Start安装包,大家只需要下载到本地,就可以直接使用,免去了编译、打包过程
准备数据库表
先编辑好MySQL相关的配置,用户名和密码
解压下载好的文件
通过git bash进行运行sh脚本
./demo.sh start即可运行
gitee代码仓库:https://gitee.com/pet365/spring-boot-apollo
https://github.com/apolloconfig/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97#3213-spring-boot%E9%9B%86%E6%88%90%E6%96%B9%E5%BC%8F%E6%8E%A8%E8%8D%90
引入依赖,注意最好引入高版本
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.tianjugroupId>
<artifactId>springboot-apolloartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<protoc.version>3.11.0protoc.version>
<protoc-gen-grpc-java.version>1.17.0protoc-gen-grpc-java.version>
<maven-compiler-plugin.version>3.7.0maven-compiler-plugin.version>
<grpc.version>1.28.0grpc.version>
<java.version>1.8java.version>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.14version>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.ctrip.framework.apollogroupId>
<artifactId>apollo-clientartifactId>
<version>2.1.0version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
project>
配置application.yml文件
server:
port: 9999
# 应用id,apollo中保持一致
app:
id: spring-boot-logger
apollo:
# 是否开启apollo
bootstrap:
enabled: true
# 设置命名空间namespace
namespaces: application
# apollo服务器 eureka地址
meta: http://localhost:8080
mysql:
username: root
myConfig: test
logging:
level:
com.tianju: debug
注解@EnableApolloConfig
package com.tianju;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableApolloConfig
public class ApolloApp {
public static void main(String[] args) {
SpringApplication.run(ApolloApp.class);
}
}
设置APPid
进行编辑配置
在表格视图中查看
配置需要发布后才能生效
配置发布后,再次访问参数
原因是用@ConfigurationProperties 这种姿势,需要处理一下才能动态更新
需要注意的是,@ConfigurationProperties
如果需要在Apollo配置变化时自动更新注入的值,需要配合使用EnvironmentChangeEvent或RefreshScope。相关代码实现,可以参考apollo-use-cases项目中的ZuulPropertiesRefresher.java和apollo-demo项目中的SampleRedisConfig.java以及SpringBootApolloRefreshConfig.java
官网给出的案例:https://github.com/apolloconfig/apollo-use-cases
package com.tianju.config;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "mysql")
public class MySQLPro {
private String username;
private String password;
}
package com.tianju.config;
import com.ctrip.framework.apollo.Config;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 动态获取username
*/
@Service
public class MySQLConfigService {
private static final Logger logger = LoggerFactory.getLogger(MySQLConfigService.class);
private static final String prefix = "mysql";
@ApolloConfig
private Config config;
@Autowired
private MySQLPro mySQLPro;
@ApolloConfigChangeListener
private void onChange(ConfigChangeEvent changeEvent){
Set<String> keyNames = config.getPropertyNames();
for (String key : keyNames){
logger.debug("the key is {}",key);
if (containsIgnoreCase(key, prefix)){
String username = config.getProperty("mysql.username", "admin-default");
String password = config.getProperty("mysql.password", "psdDefault");
Map map = new HashMap();
map.put("listenerUsername", username);
map.put("listerPassword", password);
logger.debug("new params is {}",map);
mySQLPro.setPassword(password);
mySQLPro.setUsername(username);
}
}
}
/**
* 比较str中是否包含了 searchStr
* @param str 这里是配置中心所有key
* @param searchStr 要匹配的key
* @return
*/
private static boolean containsIgnoreCase(String str, String searchStr) {
if (str == null || searchStr == null) {
return false;
}
int len = searchStr.length();
int max = str.length() - len;
for (int i = 0; i <= max; i++) {
// 忽略大小写进行比较
if (str.regionMatches(true, i, searchStr, 0, len)) {
return true;
}
}
return false;
}
public MySQLPro getMySQLPro() {
return mySQLPro;
}
}
两个都要设置一下
用2.1.0版本
在相同配置的情况下,用本地localhost进行apollo配置中心可以获得配置,而换成阿里云服务器就不行
2023-12-02 22:33:48.457 WARN 12096 --- [figRepository-1] c.c.f.a.i.AbstractConfigRepository : Sync config failed, will retry. Repository class com.ctrip.framework.apollo.internals.RemoteConfigRepository, reason: Load Apollo Config failed - appId: spring-boot-logger, cluster: default, namespace: application, url: http://172.29.88.152:8080/configs/spring-boot-logger/default/application?ip=192.168.245.1 [Cause: Could not complete get operation [Cause: connect timed out]]
2023-12-02 22:35:09.719 WARN 12096 --- [ngPollService-1] c.c.f.a.i.RemoteConfigLongPollService : Long polling failed, will retry in 120 seconds. appId: spring-boot-logger, cluster: default, namespaces: application, long polling url: http://172.29.88.152:8080/notifications/v2?cluster=default&appId=spring-boot-logger&ip=192.168.245.1¬ifications=%5B%7B%22namespaceName%22%3A%22application%22%2C%22notificationId%22%3A-1%7D%5D, reason: Could not complete get operation [Cause: connect timed out]
2023-12-02 22:37:10.729 WARN 12096 --- [ngPollService-1] c.c.f.a.i.RemoteConfigLongPollService : Long polling failed, will retry in 120 seconds. appId: spring-boot-logger, cluster: default, namespaces: application, long polling url: http://172.29.88.152:8080/notifications/v2?cluster=default&appId=spring-boot-logger&ip=192.168.245.1¬ifications=%5B%7B%22namespaceName%22%3A%22application%22%2C%22notificationId%22%3A-1%7D%5D, reason: Could not complete get operation [Cause: connect timed out]
2023-12-02 22:38:46.453 WARN 12096 --- [figRepository-1] c.c.f.a.i.RemoteConfigRepository : Load config failed, will retry in 1 SECONDS. appId: spring-boot-logger, cluster: default, namespaces: application
2023-12-02 22:38:48.466 WARN 12096 --- [figRepository-1] c.c.f.a.i.AbstractConfigRepository : Sync config failed, will retry. Repository class com.ctrip.framework.apollo.internals.RemoteConfigRepository, reason: Load Apollo Config failed - appId: spring-boot-logger, cluster: default, namespace: application, url: http://172.29.88.152:8080/configs/spring-boot-logger/default/application?ip=192.168.245.1 [Cause: Could not complete get operation [Cause: connect timed out]]
2023-12-02 22:39:11.753 WARN 12096 --- [ngPollService-1] c.c.f.a.i.RemoteConfigLongPollService : Long polling failed, will retry in 120 seconds. appId: spring-boot-logger, cluster: default, namespaces: application, long polling url: http://172.29.88.152:8080/notifications/v2?cluster=default&appId=spring-boot-logger&ip=192.168.245.1¬ifications=%5B%7B%22namespaceName%22%3A%22application%22%2C%22notificationId%22%3A-1%7D%5D, reason: Could not complete get operation [Cause: connect timed out]
2023-12-02 22:41:12.775 WARN 12096 --- [ngPollService-1] c.c.f.a.i.RemoteConfigLongPollService : Long polling failed, will retry in 120 seconds. appId: spring-boot-logger, cluster: default, namespaces: application, long polling url: http://172.29.88.152:8080/notifications/v2?cluster=default&appId=spring-boot-logger&ip=192.168.245.1¬ifications=%5B%7B%22namespaceName%22%3A%22application%22%2C%22notificationId%22%3A-1%7D%5D, reason: Could not complete get operation [Cause: connect timed out]
网上找了各种解决方法,均没有解决问题,目前还不清楚究竟是什么原因
https://github.com/apolloconfig/apollo/issues
1.如何启动Apollo;
2.如何SpringBoot集成;
3.@ConfigurationProperties的使用姿势;