项目配置迁移到Apollo以后,经过统一的配置管理及配置监听使得项目配置修改的成本大大下降。git
可是,在使用Apollo的过程当中,强哥也遇到一个问题:若是咱们要获取Apollo下的namespace信息须要经过ConfigServer.getConfig(String namespace)方法来获取,可是使用这个方法的前提是咱们必须知道当前项目下有哪些namespace,或者说咱们只能使用咱们已知的namespace。这就对咱们的代码扩展性产生了限制,假如项目已经上线,而以后咱们又要新增namespace或者修改已有namespace名称,就必须更改代码将对应的namespace加入或修改,而后从新发布。github
虽然咱们不会常常修改namespace,可是,有这么一个痛点,就让人很不舒服。并且从官方文档中,强哥“并无”找到:经过项目app_id获取到Apollo上对应的该项目下的全部namespace的方法。编程
那么这个问题要怎么解决呢?强哥今天就带你们经过Apollo源码来看看如何找到解决思路。api
按常理出牌,咱们先在Google中搜索一下咱们的问题(这里提一下,别用百度,他么的根本定位不到要搜的点):
第一条搜索结果点进去看看,是其余开发者在github上提的issue:
咱们能够看到,做者的回复是:经过open api来获取全部namespace。也就是官方文档中的这块内容:
额,这个……其实,官方文档中是有提到如何获取项目下的全部namespace的方法的,那么强哥上面为何说没有找到呢?这不是啪啪啪打脸吗?缓存
强哥这么说是由于官网提供的方式比较鸡肋。咱们能够看到,须要获取项目下全部的namespace,须要接入Apollo开放平台。操做步骤以下:网络
注册第三方应用
给已注册的第三方应用受权
第三方应用经过获取的Token调用Apollo Open API
这尼玛,坑爹啊,这么麻烦,还要注册受权拿Token才能搞,这对于强哥这种懒人来讲简直无法接受。架构
Token是不可能用Token的,这辈子都不会用Token来获取这玩意的。因而,从官方提供的Api来看是无法了,只能另谋出路啦。app
虽然官方文档中没有直接提供解决问题的方法,但是咱们从提供的开放平台API却是也能够发现一些信息:
根据官网配置后调用以下:
发现确实能够获取到项目下的全部namespace信息,但是,信息有点太多了,将namespace下的配置也都返回了回来,并且请求中不加入Authorization属性的Token信息,调用会返回401没有权限。果真强扭的瓜不甜。socket
那么咱们怎么从上面的信息找突破点呢?没错,若是有强哥同样思路的同窗,应该会想到:既然开放平台提供了调用接口,那么咱们就去源码里看看这个接口的具体实现,没准可以有所收获呢!maven
从上图中咱们能够看到,接口地址是: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的部分实现有所熟悉。因此,有时候,走一些“该走的弯路”也不是坏事。
但愿这篇文章对你们有用,好啦,今天就到这~
关注公众号获取更多内容,有问题也可在公众号提问哦:强哥叨逼叨
叨逼叨编程、互联网的看法和新鲜事