前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊如何将数据同步到apollo配置中心

聊聊如何将数据同步到apollo配置中心

作者头像
lyb-geek
发布2022-03-04 14:06:32
7130
发布2022-03-04 14:06:32
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路

01、前言

落地过微服务项目的朋友,对配置中心应该都不会陌生。利用配置中心可以集中化管理配置,还可以做到配置热更新等。目前市面常见的配置中心有QConf、spring-cloud-config、diamond、disconf、apollo、nacos等。而微服务项目最常用应该是spring-cloud-config、apollo、nacos。

我们可能会有这样的应用场景,将一些配置数据先落到数据库,然后再将这些数据持久化到配置中心。这边可以分成2步走,第一步将数据落库,第二步再手动通过配置中心提供的面板,将数据写到配置中心。不过可能我们会更倾向,将数据落库后,直接将数据同步到配置中心。今天就以apollo为例,聊聊如何将数据同步到apollo配置中心

02、实现思路

利用apollo提供的开放API进行操作

03、实现步骤

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

04、示例演示

1、创建第三方应用

创建后提示token

2、根据token给第三方应用授权操作的appId

我们授权可以操作API网关上的所有配置,授权类型为APP

3、通过apollo-openapi调用Apollo Open API

项目中pom导入apollo-openapi坐标

代码语言:javascript
复制
<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-openapi</artifactId>
    <version>1.7.0</version>
</dependency>

引入后,我们就可以直接操作apollo open api了

a、查询配置项

代码语言:javascript
复制
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();
    }

运行单元测试

代码语言:javascript
复制
@Test
    public void testGetMaxRouteRuleIndex(){
        long index = routeService.getMaxRouteRuleIndex();
        Assert.assertTrue(index >= 0);
    }

此时网关上的apollo面板

b、创建并发布配置项

注: apollo的创建和发布是两个不同的API

代码语言:javascript
复制
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;
    }

运行单元测试

代码语言:javascript
复制
@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、更新并发布配置项

代码语言:javascript
复制
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;
    }

运行单元测试

代码语言:javascript
复制
@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/dashboard/ops/index会出现

改访问http://localhost:8000/xxx/ops/index

说明路由已经成功发生变更

c、删除并发布配置项

代码语言:javascript
复制
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;
    }
代码语言:javascript
复制
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即可

05、总结

apollo开放平台提供的api其实就是http restful操作,提供一系列的增删改查操作。这边有个小细节就是apollo的增删改和发布是分开操作。如果只调用增删改,则需要在portal上点发布,或者利用发布接口进行操作。更多细节可以查看apollo的开放平台链接

https://www.apolloconfig.com

本文提供的示例,仅做参考,不可直接用于生产环境。如果有朋友的配置中心是用nacos,也是可以实现类似的操作。因为nacos也有提供open api接口,感兴趣朋友可以查看如下链接

https://nacos.io/zh-cn/docs/open-api.html

06、demo链接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-sync-apollo

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档