一烟逊、準(zhǔn)備工作
系統(tǒng):CentOS7
Java:Apollo服務(wù)端要求Java1.8+抡笼,客戶端要求Java1.7+畔柔,我們環(huán)境都是Java1.8
mysql:需要5.6.5以上版本
Apollo:SpringBoot熱發(fā)布需要0.10.0以上版本咖驮,OpenAPI需要Apollo需要1.1.0以上版本哼丈,我們使用1.2.0版本
二启妹、SpringBoot熱發(fā)布
2.1 環(huán)境配置
Windows系統(tǒng)新建C:\opt\settings目錄,Unix/Linux系統(tǒng)新建/opt/settings目錄削祈,在該目錄下新建server.properties文件翅溺,添加以下屬性
env=DEV
apollo.meta=http://192.168.207.30:8080
2.2 項(xiàng)目配置
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
#注入默認(rèn)application namespace
apollo.bootstrap.enabled = true
#Apollo meta服務(wù)地址,已經(jīng)將該配置放入到server.properties
#apollo.meta=http://192.168.207.30:8080
2.2.3 JavaConfig實(shí)現(xiàn)熱發(fā)布
Apollo熱發(fā)布與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調(diào)用實(shí)現(xiàn)新增/編輯配置,發(fā)布配置
3.1 環(huán)境準(zhǔn)備
3.1.1 注冊應(yīng)用
應(yīng)用負(fù)責(zé)人需要向Apollo管理員提供一些第三方應(yīng)用基本信息吨拍。
基本信息如下:
第三方應(yīng)用的AppId褪猛、應(yīng)用名、部門
第三方應(yīng)用負(fù)責(zé)人
Apollo管理員在 http://{portal_address}/open/manage.html 創(chuàng)建第三方應(yīng)用羹饰,創(chuàng)建之前最好先查詢此AppId是否已經(jīng)創(chuàng)建伊滋。創(chuàng)建成功之后會生成一個token,如下圖所示:
3.1.2 應(yīng)用授權(quán)
第三方應(yīng)用不應(yīng)該能操作任何Namespace的配置队秩,所以需要給token綁定可以操作的Namespace笑旺。Apollo管理員在 http://{portal_address}/open/manage.html 頁面給token賦權(quán)。賦權(quán)之后馍资,第三方應(yīng)用就可以通過Apollo提供的Http REST接口來管理已授權(quán)的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 實(shí)例化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);
}
//發(fā)布配置
@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"));
}
}