Gateway 轉發請求至註冊中心Nacos中的服務404問題(閘道器日誌提示:niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647)
問題描述
其中閘道器最後給出的資訊是:Flipping property: login-module.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
問題排查
閘道器訪問出現404狀態碼的情況無非從這三個方面去排查:
1.閘道器問題
將gateway的配置轉發檔案改為:
server
接著訪問:localhost:8000 。發現跳轉百度頁面成功。因此轉發並沒有問題。於是閘道器端可能出現的問題還剩下 路徑匹配問題。
下面是我配置的閘道器轉發(部分):
spring
與之匹配的是註冊中心Nacos中的服務下的測試api (我這邊就從簡了):
請求的路徑是:http://127.0.0.1:8000/login/sout (gateway埠是:8000,服務模組的埠是:8081)
通過比對發現,路徑匹配沒有問題。
2. 服務註冊失敗
也就是說因為服務模組向服務註冊中心註冊失敗,導致閘道器查詢服務中心中的服務時,並沒有查詢到其中含有你匹配的模組服務名稱,從而導致匹配失敗,返回404狀態碼。
於是,檢視Nacos中服務發現列表(這裡同樣從簡,只開了兩個需要觀測的模組):
可以看出,服務註冊沒有問題。
3.服務模組呼叫問題
也就是說,是因為服務模組中的提供的請求路徑本來就返回404,訪問不通。因為原先在這個模組中進行了Sa-Token的分散式鑑權,所以將Maven依賴中的Sa-Token部分全部註釋,進行訪問,發現訪問失敗。
最終排查
經過業務部分和Controller部分程式碼檢測過後,發現並無問題。於是開始考慮是否是依賴間的衝突或者其他問題導致。此時,我注意到服務模組啟動後日志中仍有Sa-Token的Logo:
這說明,依賴中的Sa-Token並沒有完全去除。於是我反覆再次檢視依賴,發現這裡的Sa-Token是由工具類中的。
在這裡,我將專案中的一些工具類和實體類全部抽離,作為了一個工具模組,此工具模組中的pom檔案中,因為偷懶,所以將其他模組中的pom檔案中的依賴項進行拷貝複製到了工具模組的pom檔案中(切記每個模組引入的依賴複製後需要仔細核對一遍)。因此其中也帶有Sa-Token的相關依賴。於是在服務模組中將工具模組中的Sa-Token的相關依賴去除:
<dependency>
<groupId>com.utils</groupId>
<artifactId>utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
</exclusion>
<exclusion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
</exclusion>
<exclusion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-alone-redis</artifactId>
</exclusion>
<exclusion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId>
</exclusion>
</exclusions>
</dependency>
再次進行測試,發現仍然訪問為404異常。
於是將所有業務與Controller程式碼全部註釋,最後只剩一個測試api返回success的字串。進行測試後,發現仍然訪問不通。
因此,想到是包沒有被掃描到。於是檢視啟動類,找到了原因:
因為提取工具類時,參照網上的部落格中的做法,在啟動類上引入了:
至此原因排查結束。因為@ComponentScan 如果不設定basePackage的話 預設會掃描包的所有類,如果設定了basePackage的話,只會掃描設定路徑下的包。從而導致了我們原來專案模組中的包並不會被掃描到。
改正
將啟動類上的
去除即可。再次進行測試:訪問 http://127.0.0.1:8000/login/sout
跳轉成功!!!
總結
@ComponentScan 如果不設定basePackage的話 預設會掃描包的所有類,如果設定了basePackage的話,只會掃描設定路徑下的包。從而導致了我們原來專案模組中的包並不會被掃描到。
因此以後寫的時候注意一下,當然正式生產場景並不推薦你不寫從而掃描所有的包,而是應該將所有需要掃描的包全部寫上去。
@ComponentScan(basePackages = {})填String陣列 或者 用逗號隔開的String 都可以。為了idea顯示相容一點,還是改成了 String陣列