一、准备工作
系统:CentOS7
Java:Apollo服务端要求Java1.8+,客户端要求Java1.7+,我们环境都是Java1.8
mysql:需要5.6.5以上版本
Apollo:SpringBoot热发布需要0.10.0以上版本,OpenAPI需要Apollo需要1.1.0以上版本,我们使用1.2.0版本
二、SpringBoot热发布
2.1 环境配置
Windows系统新建C:\opt\settings目录,Unix/Linux系统新建/opt/settings目录,在该目录下新建server.properties文件,添加以下属性
env=DEV
apollo.meta=http://192.168.207.30:8080
2.2 项目配置
2.2.1 Maven依赖
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.2.0</version>
</dependency>
2.2.2 application.properties配置
Apollo0.10.0版本支持在SpringBoot中将Apollo配置放入application.properties中
app.id=20000
#注入默认application namespace
apollo.bootstrap.enabled = true
#Apollo meta服务地址,已经将该配置放入到server.properties
#apollo.meta=http://192.168.207.30:8080
2.2.3 JavaConfig实现热发布
Apollo热发布与SpringBoot集合依赖于ApolloConfigChangeListener与RefreshScope,下面是示例代码
AppConfig.java
@Configuration
@EnableApolloConfig(value = "application")
public class AppConfig {
}
SampleRedisConfig.java
@ConfigurationProperties(prefix = "redis.cache")
@Component("sampleRedisConfig")
@RefreshScope
public class SampleRedisConfig {
private static final Logger logger = LoggerFactory.getLogger(SampleRedisConfig.class);
private int expireSeconds;
private String clusterNodes;
private int commandTimeout;
@PostConstruct
private void initialize() {
logger.info(
"SampleRedisConfig initialized - expireSeconds: {}, clusterNodes: {}, commandTimeout: {}",
expireSeconds, clusterNodes, commandTimeout);
}
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
public void setClusterNodes(String clusterNodes) {
this.clusterNodes = clusterNodes;
}
public void setCommandTimeout(int commandTimeout) {
this.commandTimeout = commandTimeout;
}
@Override
public String toString() {
return String.format(
"[SampleRedisConfig] expireSeconds: %d, clusterNodes: %s, commandTimeout: %d",
expireSeconds, clusterNodes, commandTimeout);
}
}
SpringBootApolloRefreshConfig.java
@Component
public class SpringBootApolloRefreshConfig {
private static final Logger logger = LoggerFactory.getLogger(SpringBootApolloRefreshConfig.class);
private final SampleRedisConfig sampleRedisConfig;
private final RefreshScope refreshScope;
public SpringBootApolloRefreshConfig(
final SampleRedisConfig sampleRedisConfig,
final RefreshScope refreshScope) {
this.sampleRedisConfig = sampleRedisConfig;
this.refreshScope = refreshScope;
}
@ApolloConfigChangeListener
public void onChange(ConfigChangeEvent changeEvent) {
logger.info("before refresh {}", sampleRedisConfig.toString());
refreshScope.refresh("sampleRedisConfig");
logger.info("after refresh {}", sampleRedisConfig.toString());
}
}
三、OpenAPI调用实现新增/编辑配置,发布配置
3.1 环境准备
3.1.1 注册应用
应用负责人需要向Apollo管理员提供一些第三方应用基本信息。
基本信息如下:
第三方应用的AppId、应用名、部门
第三方应用负责人
Apollo管理员在 http://{portal_address}/open/manage.html 创建第三方应用,创建之前最好先查询此AppId是否已经创建。创建成功之后会生成一个token,如下图所示:
3.1.2 应用授权
第三方应用不应该能操作任何Namespace的配置,所以需要给token绑定可以操作的Namespace。Apollo管理员在 http://{portal_address}/open/manage.html 页面给token赋权。赋权之后,第三方应用就可以通过Apollo提供的Http REST接口来管理已授权的Namespace的配置了。
3.2 Maven依赖
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>1.2.0</version>
</dependency>
3.3 实例化ApolloOpenApiClient
String portalUrl = "http://docker:8070"; // portal url
String token = "db01daca90bad8641551d5cae0d75fd6c057032f"; // 申请的token
@Bean
public ApolloOpenApiClient apolloOpenApiClient() {
ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
.withPortalUrl(portalUrl)
.withToken(token)
.build();
return client;
}
3.4 使用ApolloOpenAPIClient操作Apollo
@RestController
public class TestController {
@Autowired
private ApolloOpenApiClient client;
@Value("${app.id}")
private String appId;
@GetMapping("/envclusters")
public Object getEnvclusters() {
return JSON.toJSONString(client.getEnvClusterInfo(appId));
}
//新增配置
@PostMapping("/add")
public Object addParam() {
OpenItemDTO openItemDTO = new OpenItemDTO();
openItemDTO.setKey("timeout");
openItemDTO.setValue("100");
openItemDTO.setComment("超时时间");
openItemDTO.setDataChangeCreatedBy("apollo");
OpenItemDTO item = client.createItem(appId, "DEV", "default", "application", openItemDTO);
return JSON.toJSONString(item);
}
//修改配置
@PostMapping("/update")
public Object updateParam() {
OpenItemDTO openItemDTO = new OpenItemDTO();
openItemDTO.setKey("timeout");
openItemDTO.setValue("200");
openItemDTO.setComment("超时时间");
openItemDTO.setDataChangeCreatedBy("apollo");
client.createOrUpdateItem(appId, "DEV", "default", "application", openItemDTO);
return JSON.toJSONString(openItemDTO);
}
//发布配置
@PostMapping("/release")
public Object releaseParam() {
NamespaceGrayDelReleaseDTO namespaceGrayDelReleaseDTO = new NamespaceGrayDelReleaseDTO();
namespaceGrayDelReleaseDTO.setReleaseTitle("2019-03-27 17:38 release");
namespaceGrayDelReleaseDTO.setReleaseComment("test release");
namespaceGrayDelReleaseDTO.setReleasedBy("apollo");
OpenReleaseDTO openReleaseDTO = client.publishNamespace(appId, "DEV", "default", "application", namespaceGrayDelReleaseDTO);
return JSON.toJSONString(openReleaseDTO);
}
//获取名称空间下所有的配置
@GetMapping("/namespace")
public Object getAllNameSpace() {
return JSON.toJSONString(client.getNamespace(appId, "DEV", "default", "application"));
}
}