環境描述:
微服務技術棧: SpringCloud Alibaba
閘道器: Gateway
問題描述:
前臺傳送的請求的響應碼為200
具體響應內容:
後臺的Controller層方法卻沒有進入
注: 只有啟動微服務專案中的B服務時,才會出現介面概率性呼叫異常,關閉B服務不會出現
問題分析:
因為所有的Controller層的介面都會出現此問題,可以斷定與介面無關,所以決定先排查B服務與閘道器
排查過程:
-
在閘道器配置的Fallback類上打上斷點,檢視是否是介面呼叫失敗導致問題的出現
@RestController public class FallbackController { /** * 全域性熔斷處理 * @return */ @RequestMapping("/fallback") public Mono<String> fallback() { return Mono.just("訪問超時,請稍後再試!"); } }
果然,斷點卡在第9行上,並且返回值也與前臺獲得的相應內容一致
-
在閘道器配置的Filter類上打上斷點,檢視呼叫失敗的介面資訊
@Component public class GlobalAccessTokenFilter implements GlobalFilter, Ordered @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String url = exchange.getRequest().getURI().getPath(); }
結果發現此方法一直在被呼叫,速度極快,並且幾乎全是/login/xx與/getXXX介面,因為業務原因,作者十分
確定這兩個介面不會被頻繁呼叫,所以判斷是存在死迴圈在呼叫這兩個介面
-
繼續排查B服務,重點查詢呼叫上述兩個介面的方法,果然發現存在死迴圈(程式碼就不放了)
解決方法:
解決方法當然是幹掉死迴圈了,不過還有另一種解決方法: 搭建叢集。因為真實生產環境中此問題也完全有可能是併發量達到了gateway的上限造成的,那自然就需要對gateway服務做叢集
這裡說一下openFeign如何配置gateway叢集
@FeignClient(value = "gateway服務名稱", contextId = "xxx", fallbackFactory = "xxx")
上述配置即可自動進行負載均衡轉發到gateway服務上(注意: value屬性值不可重複,否則專案會啟動失敗,如果需要配置多個FeignClient的話並且value值需要一樣的話,請再額外配置contextId進行區分)
下一篇我會詳細說一下@FeignClient的常用配置