1. 程式人生 > 其它 >Gateway 轉發請求至註冊中心Nacos中的服務404問題(閘道器日誌提示:niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647)

Gateway 轉發請求至註冊中心Nacos中的服務404問題(閘道器日誌提示:niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647)

Gateway 轉發請求至註冊中心Nacos中的服務404問題

問題描述

一次練手專案中,原本沒問題並且測試過的gateway,再次轉發連結的時候返回404狀態碼。gateway和被呼叫模組的日誌資訊中均無報錯資訊。

其中閘道器最後給出的資訊是:Flipping property: login-module.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647


問題排查

閘道器訪問出現404狀態碼的情況無非從這三個方面去排查:

1.閘道器問題

將gateway的配置轉發檔案改為:

server:
port: 8000
spring:
application:
name: gateway-module
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
discovery:
locator:
enabled: false #啟用DiscoveryClient閘道器整合的標誌,可以實現服務的發現
#gateway 定義路由轉發規則
routes:
#一份設定
- id: baidu #唯一標識
uri: http://www.baidu.com #訪問的路徑,lb://負載均衡訪問固定寫法,通過負載均衡調取所有設定中的一份
predicates: #謂詞,判斷,是否匹配。使用者請求的路徑是否與...進行匹配,如果匹配則可以訪問,否則就404
- Path=/**

接著訪問:localhost:8000 。發現跳轉百度頁面成功。因此轉發並沒有問題。於是閘道器端可能出現的問題還剩下 路徑匹配問題。

下面是我配置的閘道器轉發(部分):

spring:
application:
name: gateway-module
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
discovery:
locator:
enabled: true #啟用DiscoveryClient閘道器整合的標誌,可以實現服務的發現
#gateway 定義路由轉發規則
routes:
#一份設定
- id: login-module #唯一標識
uri: lb://login-module #訪問的路徑,lb://負載均衡訪問固定寫法,通過負載均衡調取所有設定中的一份
predicates: #謂詞,判斷,是否匹配。使用者請求的路徑是否與...進行匹配,如果匹配則可以訪問,否則就404
- Path=/login/**

與之匹配的是註冊中心Nacos中的服務下的測試api (我這邊就從簡了):

@RestController
public class TestController {

@RequestMapping("/login/sout")
public String sout(){
return "success";
}
}

請求的路徑是: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(basePackages = "com.utils")

至此原因排查結束。因為@ComponentScan 如果不設定basePackage的話 預設會掃描包的所有類,如果設定了basePackage的話,只會掃描設定路徑下的包。從而導致了我們原來專案模組中的包並不會被掃描到。


改正

將啟動類上的

@ComponentScan(basePackages = "com.utils")

去除即可。再次進行測試:訪問 http://127.0.0.1:8000/login/sout

跳轉成功!!!


總結

@ComponentScan 如果不設定basePackage的話 預設會掃描包的所有類,如果設定了basePackage的話,只會掃描設定路徑下的包。從而導致了我們原來專案模組中的包並不會被掃描到。

因此以後寫的時候注意一下,當然正式生產場景並不推薦你不寫從而掃描所有的包,而是應該將所有需要掃描的包全部寫上去。

@ComponentScan(basePackages = {})填String陣列 或者 用逗號隔開的String 都可以。為了idea顯示相容一點,還是改成了 String陣列