<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前段時間同事碰到一個問題,需要在 SpringCloud
的 Feign 呼叫中使用自定義的 URL;通常情況下是沒有這個需求的;畢竟都用了 SpringCloud
的了,那服務之間的呼叫都是走註冊中心的,不會需要自定義 URL 的情況。
但也有特殊的,比如我們這裡碰到 ToB
場景,需要對每個商戶自定義的 URL
進行呼叫。
雖說也可以使用原生的 Feign
甚至是自定義一個 OKHTTP Client
實現,但這些方案都得換一種寫法;
打算利用現有的 SpringCloud
OpenFeign
來實現,畢竟原生的 Feign 其實是支援該功能的,而 SpringCloud OpenFeign
也只是在這基礎上封裝了一層。
只需要在介面宣告處加上一個 URI
引數即可,這樣就可以在每次呼叫時傳遞不同的 URI
來實現動態 URL
的目的。
想法很簡單,但實踐起來卻不是那麼回事了。 虛擬碼如下:
@FeignClient(name = "dynamic") interface DynamicClient { @GetMapping("/") String get(URI uri); } dynamicClient.get(URI.create("https://github.com"));
執行後會丟擲負載均衡的異常:
java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: github.com
這個異常也能理解,就是找不到 github 這個服務;找不到也是合理的,畢竟也不是一個內部註冊的服務。
但按照 Feign
的官方介紹,只要介面中宣告了 URI
這個引數就能自定義,同時我自己也用原生的 Feign 測試過確實沒什麼問題。
那問題只能出在 SpringCloud OpenFeign
的封裝上了;經過同事的搜尋在網上找到一篇部落格解決了這個問題。
按照文中的說法,確實只需要加上 URL 引數同時有值就可以了,但原因不明。
本著打破砂鍋問到底的精神,我個人也想知道 OpenFeign
是如何處理的,只要 url 有值就可以,這完全是個黑盒,而且在官方的註釋中並沒有對這種情況有特殊說明。
所以我準備從原始碼中找到答案。
既然是 url 有值就能正常執行,那一定是在執行過程中獲取了這個值;
但我在原始碼中檢視 url 所使用的地方,並沒有在單測之外找到哪裡有所應用,說明原始碼中並沒有直接呼叫 url()
這個函數來獲取值。
但 org.springframework.cloud.openfeign.FeignClient
這個註解總會使用吧,於是我又查詢這個註解的使用情況。
最終在這裡查到了使用的痕跡。
這裡查閱原始碼時也有一些小技巧,比如如果我們直接查詢時,IDEA 預設的查詢範圍是整個專案和所有依賴庫,會有許多幹擾資訊。
比如我這裡就需要只看專案原始碼,單測這些都不用看;所以在查詢的時候可以過濾一下,這樣干擾資訊就會少很多。
左邊的工具列還有許多過濾條件,大家可以自行研究一下。
接著從原始碼中進行閱讀,會發現是將 @FeignClient
中的所有資料都寫到一個 Map
裡進行使用的。
最終會發現這個 url 被寫入到了 FeignClientFactoryBean
中的 url 成員變數中了。
檢視哪裡在使用這個 url 就知道背後的原理了。
在這裡打個斷點會發現:當 url 為空時會返回一個 LoadBalance
的 client
,也就是會從註冊中心獲取 url
的使用者端,而 url
有值時則會獲取一個預設的使用者端,這樣就不會走負載均衡了。
所以我們如果想在 OpenFeign 中使用動態 url 時就得讓 @Feign 的 url 有值才行,無論是什麼都可以。
既然已經看到這一步了,我也比較好奇 Feign 是如何做到只要有 URI 引數就使用指定的 URL 呢?
這裡也分享一個讀原始碼的小技巧,如果我們跟著程式執行的思路去一步步 debug
的話會非常消耗時間,畢竟這類成熟庫的程式碼量也不小。
這裡我們從官方檔案中可以得知只要在介面引數中使用了 java.net.URI
便會走自定義的 url,所以我們反過來只要在原始碼中找到哪裡在使用 java.net.URI
便能知道關鍵原始碼。
畢竟使用 java.net.URI
的場景也不會太多。
所以只需要在這個依賴的地方 cmd+shift+f
全域性搜尋 java.net.URI
就能查到結果,果然不多,只有兩處使用。
再結合使用場景猜測大概率是判斷引數中是否是有 URL.class
這樣的條件,或者是 url 物件;總之我們先用 URL
這樣關鍵字在這兩個檔案中搜尋一下,記得勾選匹配大小寫;最後會發現的確是判斷了引數中是否有 URL
這個類,同時將這個索引位置記錄了下來。
想必後續會通過這個索引位置讀取最終的 url
資訊。
最終通過這個索引的使用地方查詢到了核心原始碼,如果有值時就取這個 URI 中所指定的地址作為 target
。
到此為止這個問題的背後原理都已經分析完畢了。
其實本文重點是分析了一些 debug
和閱讀原始碼的一些小技巧,特別是在讀關於 Spring
相關的程式碼時一定不能 debug 跟蹤到細節中,因為呼叫鏈通常是很長的,稍不留神就把自己都繞暈了,只需要知道核心、關鍵原始碼是如何處理的即可。
最後對於 OpenFeign 處理動態 url 的方案確實也有些疑惑,是一個典型的約定大於設定
的場景,但問題就在於我們並不知道這個約定是 @Feign
的 url 得有值。
所以我也提了一個 PR
給 OpenFeign
,感興趣的朋友也可以檢視一下:
以上就是剖析SpringCloud Feign中所隱藏的坑的詳細內容,更多關於SpringCloud Feign坑的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45