如何获取Apollo上项目下的所有namespace?
背景
项目配置迁移到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?的更多相关文章
- 通过SSH key获取GitHub上项目,导入到IDEA中
1.在Windows上安装Git 在Windows上使用Git,可以从Git官网直接下载安装程序,然后按默认选项安装即可 安装完成后,在开始菜单里找到“Git”->“Git Bash”,或者在文 ...
- SpringBoot 项目打包后获取不到resource下资源的解决
SpringBoot 项目打包后获取不到resource下资源的解决 在项目中有几个文件需要下载,然后不想暴露真实路径,又没有CDN,便决定使用接口的方式来获取文件.最初的时候使用了传统的方法来获取文 ...
- 通过getResourceAsStream方法获取项目下的指定资源
properties配置文件调用 通过getResourceAsStream方法获取项目下的指定资源 一:获取src下的指定资源 1). Class.getResourceAsStream(Strin ...
- Android项目,从web上取下汉字,中文部分乱码
Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...
- Java反射获取当前项目下所有类,支持Servlet
反射在很多时候要用,尤其自己编写框架时,那么如何获得当前项目下所有类呢!以下是本人封装的一个比较简洁的方法: [功能代码] //通过loader加载所有类 private List<Class& ...
- 解决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 ...
- linux下的shell命令的编写,以及java怎样调用linux的shell命令(java怎样获取linux上的网卡的ip信息)
程序猿都非常懒,你懂的! 近期在开发中,须要用到server的ip和mac信息.可是server是架设在linux系统上的,对于多网口,在获取ip时就产生了非常大的问题.以下是在windows系统上, ...
- iOS获取UIView上某点的颜色值
项目需求中遇到获取UIView上某个坐标点的RGB颜色值的需求,现在把自己找到的解决方案简单总结记录一下,遇到了下面的情况: 不可移动的UIView 旋转式的UIView 滑条式的UIView 不可移 ...
- jenkins获取git上的源码
jenkins获取git上的源码会遇到三种情况,我们在这里会分别介绍一下: 一.获取git上public(公有)的项目 只需配置仓库的URL即可 jenkins下使用git获取源码的配置方法 二.获取 ...
随机推荐
- CF948B Primal Sport
题目链接:http://codeforces.com/contest/948/problem/B 知识点: 素数 解题思路: \(f(x)\) 表示 \(x\) 的最大素因子.不难想到:\(X_1 \ ...
- J2EE项目分类管理中,提交表单数据是二进制形式时,对数据的修改失败。category赋值失败。
原因: 在条件判断时,对字符串的比较进行了错误比较. 解决方法: A==B,比较的是两个字符串是否是同一个对象. A.equal(B),比较的是两个字符串内容是否相同. 出现错误是用了第一种比较,应该 ...
- poi 针对word模板内容替换
最近多了一个需求,需要对word模板内容进行替换,一开始用的是word03版的,替换起来比较简单,主要是range对像替换非常方便,而且可以保留替换前的字体样式. InputStream is = n ...
- [256个管理学理论]002.青蛙效应(Frog Effect)
青蛙效应(Frog Effect) 从一个话题开始: 当下,社会发展突飞猛进,日新月异.在世界经济危机中,我国国民生产总值增长幅度始终在8%以上,引起世人的瞩目. 但,在国内时常也能听到广大投资者对股 ...
- XMLHttpRequest实现Ajax &数据格式JSON
GET请求 index <%@ page language="java" contentType="text/html; charset=utf-8" p ...
- jchdl - RTL实例 - Adder4Carry
https://mp.weixin.qq.com/s/j4zLmjKgau2vRXVNfm0SIA 带进位的加法. 参考链接 https://github.com/wjcdx/jchdl/bl ...
- Java实现 蓝桥杯VIP 算法训练 JAM计数法
题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小 写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文 ...
- Java实现 蓝桥杯 算法训练 Cowboys
试题 算法训练 Cowboys 问题描述 一个间不容发的时刻:n个牛仔站立于一个环中,并且每个牛仔都用左轮手枪指着他旁边的人!每个牛仔指着他顺时针或者逆时针方向上的相邻的人.正如很多西部片那样,在这一 ...
- Java实现 LeetCode 1013 将数组分成和相等的三个部分
1013. 将数组分成和相等的三个部分 给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false. 形式上,如果可以找出索引 i+1 < j 且满足 ...
- 第五届蓝桥杯JavaA组国(决)赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.海盗分金币 有5个海盗,相约进行一次帆船比赛. 比赛中天气发生突变,他们被冲散了. 恰巧,他们都先后经过途中的一个无名的荒岛,并且每个 ...