項目配置遷移到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的部分實現有所熟悉。因此,有時候,走一些「該走的彎路」也不是壞事。
但願這篇文章對你們有用,好啦,今天就到這~
關注公衆號獲取更多內容,有問題也可在公衆號提問哦:強哥叨逼叨
叨逼叨編程、互聯網的看法和新鮮事