Gateway 轉發請求至注冊中心Nacos中的服務404問題(網關日志提示:niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647)


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

問題描述

一次練手項目中,原本沒問題並且測試過的gateway,再次轉發鏈接的時候返回404狀態碼。gateway和被調用模塊的日志信息中均無報錯信息。

image-20210913144510396

其中網關最后給出的信息是:Flipping property: login-module.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

img


問題排查

網關訪問出現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中服務發現列表(這里同樣從簡,只開了兩個需要觀測的模塊):

image-20210913150414137

可以看出,服務注冊沒有問題。

3.服務模塊調用問題

也就是說,是因為服務模塊中的提供的請求路徑本來就返回404,訪問不通。因為原先在這個模塊中進行了Sa-Token的分布式鑒權,所以將Maven依賴中的Sa-Token部分全部注釋,進行訪問,發現訪問失敗


最終排查

經過業務部分和Controller部分代碼檢測過后,發現並無問題。於是開始考慮是否是依賴間的沖突或者其他問題導致。此時,我注意到服務模塊啟動后日志中仍有Sa-Token的Logo:

image-20210913151215172

這說明,依賴中的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

image-20210913153119353

跳轉成功!!!


總結

@ComponentScan 如果不設置basePackage的話 默認會掃描包的所有類,如果設置了basePackage的話,只會掃描設置路徑下的包。從而導致了我們原來項目模塊中的包並不會被掃描到。

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

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




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM