前言
落地过微服务项目的敌人,对配置核心应该都不会生疏。利用配置核心能够集中化治理配置,还能够做到配置热更新等。目前市面常见的配置核心有QConf、spring-cloud-config、diamond、disconf、apollo、nacos等。而微服务项目最罕用应该是spring-cloud-config、apollo、nacos。
咱们可能会有这样的利用场景,将一些配置数据先落到数据库,而后再将这些数据长久化到配置核心。这边能够分成2步走,第一步将数据落库,第二步再手动通过配置核心提供的面板,将数据写到配置核心。不过可能咱们会更偏向,将数据落库后,间接将数据同步到配置核心。明天就以apollo为例,聊聊如何将数据同步到apollo配置核心
实现思路
利用apollo提供的凋谢API进行操作
实现步骤
1、将咱们的利用接入Apollo开放平台
Apollo管理员在 http://{portal_address}/open/manage.html 创立第三方利用,创立之前最好先查问此AppId是否曾经创立。创立胜利之后会生成一个token,如下图所示:
2、给已注册的利用受权
Apollo管理员在 http://{portal_address}/open/manage.html 页面给token赋权。赋权之后,利用就能够通过Apollo提供的Http REST接口来治理已受权的Namespace的配置了
3、利用调用Apollo Open API
示例演示
以将API网关路由信息同步到apollo为例
1、创立第三方利用
创立后提醒token
2、依据token给第三方利用受权操作的appId
咱们受权能够操作API网关上的所有配置,受权类型为APP
3、通过apollo-openapi调用Apollo Open API
我的项目中pom导入apollo-openapi坐标
<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-openapi</artifactId> <version>1.7.0</version></dependency>
引入后,咱们就能够间接操作apollo open api了
a、查问配置项
public long getMaxRouteRuleIndex(){ OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appInfoProperties.getAppId(),appInfoProperties.getEnv(),appInfoProperties.getClusterName(),appInfoProperties.getNameSpaceName()); List<OpenItemDTO> items = openNamespaceDTO.getItems(); if(CollectionUtils.isEmpty(items)){ return 0; } return items.stream().filter(item -> item.getKey().matches(ID_PATTERN)).count(); }
运行单元测试
@Test public void testGetMaxRouteRuleIndex(){ long index = routeService.getMaxRouteRuleIndex(); Assert.assertTrue(index >= 0); }
此时网关上的apollo面板
b、创立并公布配置项
注: apollo的创立和公布是两个不同的API
public boolean createRouteRule(RouteRule routeRule){ try { long curRouteRuleIndex = getMaxRouteRuleIndex(); buildOpenItemDTO(ROUTE_ID_KEY,curRouteRuleIndex,routeRule.getRouteId(),true); buildOpenItemDTO(ROUTE_URI_KEY,curRouteRuleIndex,routeRule.getUri(),true); buildOpenItemDTO(ROUTE_PREDICATES_KEY,curRouteRuleIndex,routeRule.getPredicate(),true); buildOpenItemDTO(ROUTE_FILTERS_KEY,curRouteRuleIndex,routeRule.getFilter(),true); return publish("新增网关路由","新增网关路由"); } catch (Exception e) { log.error("{}",e.getMessage()); } return false; }
运行单元测试
@Test public void testCreateRouteRule(){ RouteRule routeRule = RouteRule.builder().routeId(appName) .uri("http://localhost:8082") .predicate("Path=/dashboard/**") .filter("StripPrefix=1").build(); boolean isSuccess = routeService.createRouteRule(routeRule); Assert.assertTrue(isSuccess); }
查看api网关在apollo portal上的面板
发现呈现一条路由配置。因为api网关做了动静路由,因而从api网关的控制台能够发现如下输入
拜访一下浏览器
动静路由失效
b、更新并公布配置项
public boolean updateRouteRule(RouteRule routeRule){ long ruleIndex = getRouteRuleIndex(routeRule.getRouteId()); if(ruleIndex != -1){ try { buildOpenItemDTO(ROUTE_URI_KEY,ruleIndex,routeRule.getUri(),false); buildOpenItemDTO(ROUTE_PREDICATES_KEY,ruleIndex,routeRule.getPredicate(),false); buildOpenItemDTO(ROUTE_FILTERS_KEY,ruleIndex,routeRule.getFilter(),false); return publish("更新网关路由","更新网关路由"); } catch (Exception e) { log.error("{}",e.getMessage()); } } return false; }
运行单元测试
@Test public void testUpdateRouteRule(){ RouteRule routeRule = RouteRule.builder().routeId(appName) .uri("http://localhost:8082") .predicate("Path=/xxx/**") .filter("StripPrefix=1").build(); boolean isSuccess = routeService.updateRouteRule(routeRule); Assert.assertTrue(isSuccess); }
查看api网关在apollo portal上的面板
能够发现此时predicate的Path曾经改为xxx
查看API网关控制台
拜访一下浏览器,原先拜访http://localhost:8000/dashboa...会呈现
改拜访http://localhost:8000/xxx/ops...
阐明路由曾经胜利产生变更
b、删除并公布配置项
public boolean deleteRouteRule(String routeId){ long ruleIndex = getRouteRuleIndex(routeId); if(ruleIndex != -1){ try {// removeRouteItem(ROUTE_URI_KEY,ruleIndex);// removeRouteItem(ROUTE_PREDICATES_KEY,ruleIndex);// removeRouteItem(ROUTE_FILTERS_KEY,ruleIndex); buildOpenItemDTO(ROUTE_URI_KEY,ruleIndex,"http://null",false); buildOpenItemDTO(ROUTE_PREDICATES_KEY,ruleIndex,"Path=/-9999",false); return publish("删除网关路由","删除网关路由"); } catch (Exception e) { log.error("{}",e.getMessage()); } } return false; }
private void removeRouteItem(String key,long index){ if(key.equalsIgnoreCase(ROUTE_PREDICATES_KEY) || key.equalsIgnoreCase(ROUTE_FILTERS_KEY)){ key = String.format(key,index,0); }else{ key = String.format(key,index); } apolloOpenApiClient.removeItem(appInfoProperties.getAppId(),appInfoProperties.getEnv(),appInfoProperties.getClusterName(),appInfoProperties.getNameSpaceName(),key,appInfoProperties.getAuthUser()); }
注: 因为网关删除绝对简单点,波及到路由汇合重算,这边取巧采纳更新成无法访问的路由。如果是物理删除间接,调用apollo的removeItem即可
总结
apollo开放平台提供的api其实就是http restful操作,提供一系列的增删改查操作。这边有个小细节就是apollo的增删改和公布是离开操作。如果只调用增删改,则须要在portal上点公布,或者利用公布接口进行操作。更多细节能够查看apollo的开放平台链接
https://www.apolloconfig.com/#/zh/usage/apollo-open-api-platform?id=_3210-%e6%96%b0%e5%a2%9e%e9%85%8d%e7%bd%ae%e6%8e%a5%e5%8f%a3
本文提供的示例,仅做参考,不可间接用于生产环境。如果有敌人的配置核心是用nacos,也是能够实现相似的操作。因为nacos也有提供open api接口,感兴趣敌人能够查看如下链接
https://nacos.io/zh-cn/docs/open-api.html
demo链接
https://github.com/lyb-geek/springboot-learning/tree/master/springboot-sync-apollo