如何获取Apollo上项目下的所有namespace?

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

背景


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


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


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


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


入手点


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


0.png


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


1.png


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


2.png


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


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


  1. 注册第三方应用
  2. 给已注册的第三方应用授权
  3. 第三方应用通过获取的Token调用Apollo Open API


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


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

追根溯源


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


3.png


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


4.png


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


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


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


5.png


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


6.png


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


7.png


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


8.png


第一行就获取了namespace:


namespaceAPI.findNamespaceByCluster(appId, env, clusterName);


进去看看:


9.png


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


11.png


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


15.png


12.png


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


13.png


试验发现,确实是可以获取到项目下的所有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~


14.png


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

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


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

相关文章
|
Java 数据库
Apollo公共类型的Namespace配置需要进行关联才能用吗?
其实,这个问题在强哥看来应该有稍微深入了解Apollo的使用者应该都能回答的上来。 不过也是前些天,刚好看到公司新来的实习生在找Apollo配置时抓耳挠腮,了解情况之后,我发现,原来这个问题确实有许多人容易弄混。所以,强哥就在这里也简单科普一下。
Apollo公共类型的Namespace配置需要进行关联才能用吗?
|
1月前
|
网络协议 Linux 应用服务中间件
Namespace技术概述
【10月更文挑战第6天】在Linux内核中,为了隔离不同类型的资源,实现了多种namespace,包括UTS(hostname)、User(用户和组)、Mount(文件系统挂载点)、PID(进程ID)和Network(网络协议栈)。常用指令`nsenter`可进入指定的namespace,而`unshare`则创建并加入新的namespace。在内核层面,每个进程的`task_struct`包含这些namespace的信息。
|
3月前
|
Kubernetes 前端开发 API
在K8S中,在容器内如何获取pod和namespace名字?
在K8S中,在容器内如何获取pod和namespace名字?
|
3月前
|
Kubernetes API 容器
在K8s中,容器内如何获取pod和namespace名?
在K8s中,容器内如何获取pod和namespace名?
淘东电商项目(15) -项目配置信息分类(Apollo Namespace命名空间)
淘东电商项目(15) -项目配置信息分类(Apollo Namespace命名空间)
53 0
|
JSON Kubernetes 数据中心
05-Kubernetes-Namespace入门
05-Kubernetes-Namespace入门
05-Kubernetes-Namespace入门
|
算法 C语言 C++
【C++技能树】NameSpace --命名空间的使用
我在这段代码中想使用rand这个变量名字.这是正常的行为.
96 0
|
Kubernetes 调度 数据中心
K8S 集群 NameSpace(命名空间)_NameSpace 介绍及查看 | 学习笔记
快速学习 K8S 集群 NameSpace(命名空间)_NameSpace 介绍及查看
1097 0
K8S 集群 NameSpace(命名空间)_NameSpace 介绍及查看 | 学习笔记
|
SpringCloudAlibaba Java 测试技术
Nacos Config 使用自定义的NameSpace & Group
在之前的章节中,我们并没有对`SpringCloud Alibaba Nacos Config`的`NameSpace`、`Group`做过修改,都是使用的默认值,默认值分别是:`Public`、`DEFAULT_GROUP`,我们本章来看下如何自定义这两项参数。
|
Kubernetes 开发者 容器
K8S 集群 NaneSpace(命名空间)NameSpace 删除及学习总结 | 学习笔记
快速学习 K8S 集群 NaneSpace(命名空间)NameSpace 删除及学习总结
1899 0
K8S 集群 NaneSpace(命名空间)NameSpace 删除及学习总结 | 学习笔记