背景

项目配置迁移到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. vue-cli中的index.html ,main.js , App.vue的关系

    ###发现不少小伙伴才刚开始接触到这个结构都被绕的迷糊,而发现很多人说的也不是那么准确,那么下面我来说一下是怎么回事### 1.首先我们来看看原生Vue中组件的写法, 我们按照vue-cli的结构按照 ...

  2. PHP关于syntax error语法错误的问题(Parse error: syntax error, unexpected end of file in xxxxxxxx)

    在php程序出现类似 Parse error: syntax error, unexpected end of file in xxxxxxxx  on line xx 的错误. 如图 如果发现php ...

  3. MySQL8多实例安装与mycat连接,最详细版本。

    [版权所有,转载请注明出处!违者必究!] 最近在搞mycat去实现主从库读写分离,所以博主就在自己的windows机器上进行了环境的搭建,在搭建MySQL多实例的时候还算顺利,就是mysql8和myc ...

  4. Android_存储之文件存储

    前面几篇随笔 讲到的关于存储的,SharedPreferences.Room.数据库等 最终都是以文件形式 存储到手机上的(除特殊的存储于手机内存的:如Room可以创建内存数据库). 这些存储方式,A ...

  5. VNC远程控制,如何使用VNC远程控制来管理公司?

    VNC是功能强大的远程操作软件,可以实现日常的远程连接操作:如果稍加利用,可以实现公司的日常管理:既能够节省自身的时间,还可高效的完成这个功能! 我们可以使用:服务器管理工具来进行相关的操作 一.首先 ...

  6. 【Kafka】知识总结

    Kafka是什么? Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据. Kafka架构 1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除) 点对 ...

  7. F5忘记密码修改教程

    !!!首先查看系统版本,13版本和14版本修改密码方式不一致 首先介绍13版本修改密码 注:12版本也适用,11版本未测试,应该也可以,有问题欢迎留言) 1. 将终端连接到BIG-IP串行控制台端口. ...

  8. Java实现第七届蓝桥杯国赛 赢球票

    标题:赢球票 某机构举办球票大奖赛.获奖选手有机会赢得若干张球票. 主持人拿出 N 张卡片(上面写着 1~N 的数字),打乱顺序,排成一个圆圈. 你可以从任意一张卡片开始顺时针数数: 1,2,3- 如 ...

  9. Java实现 LeetCode 677 键值映射(字典树)

    677. 键值映射 实现一个 MapSum 类里的两个方法,insert 和 sum. 对于方法 insert,你将得到一对(字符串,整数)的键值对.字符串表示键,整数表示值.如果键已经存在,那么原来 ...

  10. Java实现 LeetCode 462 最少移动次数使数组元素相等 II

    462. 最少移动次数使数组元素相等 II 给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1. 您可以假设数组的长度最多为10000. 例如: 输 ...