背景

项目配置迁移到Apollo之后,通过统一的配置管理及配置监听使得项目配置修改的成本大大降低。

但是,在使用Apollo的过程中,强哥也遇到一个问题:如果我们要获取Apollo下的namespace信息需要通过ConfigServer.getConfig(String namespace)方法来获取,但是使用这个方法的前提是我们必须知道当前项目下有哪些namespace,或者说我们只能使用我们已知的namespace。这就对我们的代码扩展性产生了限制,假如项目已经上线,而之后我们又要新增namespace或者修改已有namespace名称,就必须更改代码将对应的namespace加入或修改,然后重新发布。

虽然我们不会经常修改namespace,但是,有这么一个痛点,就让人很不舒服。而且从官方文档中,强哥“并没有”找到:通过项目app_id获取到Apollo上对应的该项目下的所有namespace的方法。

那么这个问题要怎么解决呢?强哥今天就带大家通过Apollo源码来看看如何找到解决思路。

入手点

按常理出牌,我们先在Google中搜索一下我们的问题(这里提一下,别用百度,他么的根本定位不到要搜的点):



第一条搜索结果点进去看看,是其他开发者在github上提的issue:



我们可以看到,作者的回复是:通过open api来获取所有namespace。也就是官方文档中的这块内容:



额,这个……其实,官方文档中是有提到如何获取项目下的所有namespace的方法的,那么强哥上面为什么说没有找到呢?这不是啪啪啪打脸吗?

强哥这么说是因为官网提供的方式比较鸡肋。我们可以看到,需要获取项目下所有的namespace,需要接入Apollo开放平台。操作步骤如下:

注册第三方应用

给已注册的第三方应用授权

第三方应用通过获取的Token调用Apollo Open API

这尼玛,坑爹啊,这么麻烦,还要注册授权拿Token才能搞,这对于强哥这种懒人来说简直没法接受。

Token是不可能用Token的,这辈子都不会用Token来获取这玩意的。于是,从官方提供的Api来看是没法了,只能另谋出路啦。

追根溯源

虽然官方文档中没有直接提供解决问题的方法,可是我们从提供的开放平台API倒是也可以发现一些信息:



根据官网配置后调用如下:



发现确实可以获取到项目下的所有namespace信息,可是,信息有点太多了,将namespace下的配置也都返回了回来,而且请求中不加入Authorization属性的Token信息,调用会返回401没有权限。果然强扭的瓜不甜。

那么我们怎么从上面的信息找突破点呢?没错,如果有强哥一样思路的同学,应该会想到:既然开放平台提供了调用接口,那么我们就去源码里看看这个接口的具体实现,没准能够有所收获呢!

从上图中我们可以看到,接口地址是:http://{portal_address},那么源码就从apollo-portal入手啦:



直接进到Controller目录下(别问我为什么知道是这个目录,有点基础的点开项目自然就会这么去找了):



可以定位到我们调用的开放平台的方法是这个:



代码很简单,可以看到,获取namespace走的是namespaceService.findNamespaceBOs()方法,进去实现看看(这里为github点个赞,点击方法能够直接跳转到对应的实现,真的是方便):



第一行就获取了namespace:

namespaceAPI.findNamespaceByCluster(appId, env, clusterName);

进去看看:



吼吼,原来走的也是api调用,可是,这个api的服务地址是哪里呢?这就要小伙伴们对Apollo的架构有点熟悉了,上大图:



我们调用的接口是Portal进去的,而底层走的是Admin Service,所以,上面代码的restTemplate调用走的就是apollo-adminservice项目啦,话不多说,进apollo-adminservice看看:



其实到这里已经差不多了,因为再往细的研究已经没有了意义。我们已经可以通过调用上图提供的Api来获取到我们需要的内容了,试一下:



试验发现,确实是可以获取到项目下的所有namespace,且不需要注册第三方平台应用,也不需要在调用接口时传递Authorization参数,返回的结果也刚好是简单的所有namespace信息。完美的解决了我们的问题。

当然有些小伙伴可能会说,这样还是要调用http接口,还是有点不方便。强哥只想说,自己本地封装一个方法,获取应该还是比较简单的。而且,Apollo Client提供给我们的Api,比如:ConfigService.getConfig(String namespace)其实底层也是走的socket网络调用,只是client为我们做了一层封装对用户屏蔽了而已,同时还额外加入了缓存机制来提高效率。

当然,你也可以自己下载apollo-client的源码,然后在里面封装调用这个api的逻辑,然后maven部署到自己的私服,这样就能和其他Api一样调用啦!不过太麻烦了,强哥就不带大家试了。

总结

先总结一下解决方法:

直接越过portal,调用底层admin-service的api

http://{adminservice}/apps/{appId}/clusters/{clusterName}/namespaces

{adminservice}这个地址根据自己项目配置的地址及端口去设置哦,默认端口8090~



其实,我们发现,对于开源项目,很多东西只要我们愿意去找,还是能找到解决的思路的。不过,首先还是要了解其架构原理先,否则在查找源码的过程中,可能会无从下手。

就拿为什么强哥上面会知道apollo-client获取namespace信息的时候有使用了缓存机制呢?因为强哥当时找这个问题的解决方法时,也简单的研究了下client的源码,想要看看官方是否有提供对应的Api,结果没有找到,但是也对apollo-client的部分实现有所熟悉。所以,有时候,走一些“该走的弯路”也不是坏事。

希望这篇文章对大家有用,好啦,今天就到这~

关注公众号获取更多内容,有问题也可在公众号提问哦:强哥叨逼叨

叨逼叨编程、互联网的见解和新鲜事

如何获取Apollo上项目下的所有namespace?的更多相关文章

  1. 通过SSH key获取GitHub上项目,导入到IDEA中

    1.在Windows上安装Git 在Windows上使用Git,可以从Git官网直接下载安装程序,然后按默认选项安装即可 安装完成后,在开始菜单里找到“Git”->“Git Bash”,或者在文 ...

  2. SpringBoot 项目打包后获取不到resource下资源的解决

    SpringBoot 项目打包后获取不到resource下资源的解决 在项目中有几个文件需要下载,然后不想暴露真实路径,又没有CDN,便决定使用接口的方式来获取文件.最初的时候使用了传统的方法来获取文 ...

  3. 通过getResourceAsStream方法获取项目下的指定资源

    properties配置文件调用 通过getResourceAsStream方法获取项目下的指定资源 一:获取src下的指定资源 1). Class.getResourceAsStream(Strin ...

  4. Android项目,从web上取下汉字,中文部分乱码

    Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...

  5. Java反射获取当前项目下所有类,支持Servlet

    反射在很多时候要用,尤其自己编写框架时,那么如何获得当前项目下所有类呢!以下是本人封装的一个比较简洁的方法: [功能代码] //通过loader加载所有类 private List<Class& ...

  6. 解决Linux下Svn检出Windows SVN服务器上项目SSL handshake failed: SSL error: Key usage violation in certificate has been detected.

    在Linux上检出windows SVN服务器上项目时出现了SSL handshake failed: SSL error: Key usage violation in certificate ha ...

  7. linux下的shell命令的编写,以及java怎样调用linux的shell命令(java怎样获取linux上的网卡的ip信息)

    程序猿都非常懒,你懂的! 近期在开发中,须要用到server的ip和mac信息.可是server是架设在linux系统上的,对于多网口,在获取ip时就产生了非常大的问题.以下是在windows系统上, ...

  8. iOS获取UIView上某点的颜色值

    项目需求中遇到获取UIView上某个坐标点的RGB颜色值的需求,现在把自己找到的解决方案简单总结记录一下,遇到了下面的情况: 不可移动的UIView 旋转式的UIView 滑条式的UIView 不可移 ...

  9. jenkins获取git上的源码

    jenkins获取git上的源码会遇到三种情况,我们在这里会分别介绍一下: 一.获取git上public(公有)的项目 只需配置仓库的URL即可 jenkins下使用git获取源码的配置方法 二.获取 ...

随机推荐

  1. sklearn学习:为什么roc_auc_score()和auc()有不同的结果?

    为什么roc_auc_score()和auc()有不同的结果? auc():计算ROC曲线下的面积.即图中的area roc_auc_score():计算AUC的值,即输出的AUC 最佳答案 AUC并 ...

  2. Docker虚拟机配置手札(centos)

    一.Docker只支持CentOS7及以上系统,不支持6.x系统 二.yum安装Docker 1.安装相关环境和设置仓库 yum install -y yum-utils device-mapper- ...

  3. Istio DestinationRule 目标规则

    概念及示例 与VirtualService一样,DestinationRule也是 Istio 流量路由功能的关键部分.您可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的 ...

  4. GRpc添加客户端的四种方式

    随着微服务的发展,相信越来越多的.net人员也开始接触GRpc这门技术,大家生成GRpc客户端的方式也各不相同,今天给大家介绍一下依据Proto文件生成Rpc客户端的四种方式 前提:需要安装4个Nug ...

  5. 四、Spring-面向切面编程

    内容 面向切面编程基本原理 通过POJO创建切面 使用@AspectJ注解 为AspectJ切面注入依赖 关键词 横切关注点(cross-cutting concern) 继承 (inheritanc ...

  6. Spring_配置Bean & 属性配置细节

    1.Spring容器 在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.Sp ...

  7. Bank2

    Account: package banking2; //账户 public class Account { private double balance;// 账户余额 public Account ...

  8. ASP.NET MVC 数据传递 视图向控制器传递

    视图向控制器传递 MVC 视图向控制器传递,就是获取用户输入的数据,在去进行操作 好了,我们不多说直接进行我们的案例. 在HomeController类中添加下来方法 [HttpPost] publi ...

  9. Java实现 蓝桥杯 算法训练 纪念品分组

    问题描述 元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作.为使得参加晚会的同学所获得的纪念品价值 相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价 ...

  10. Java实现LeetCode_0035_SearchInsertPosition

    package javaLeetCode.primary; public class SearchInsertPosition_35 { public static void main(String[ ...