一、背景
最近做網關重構,技術選型爲spring cloud gateway,採用consul作爲配置中心和註冊中心,秉承不重啓原則,網關內部實現動態路由機制,採用定時任務定時更新網關路由信息。
二、服務信息
微服務網關:spring-cloud-gateway
微服務:order-service、user-service
三、問題描述
因爲網關服務集成了knife4j,因此可以通過訪問http://網關ip:port/doc.html,即可訪問所有在同一個註冊中心的服務的knife4j信息,但是實際訪問時用戶服務相關接口報404錯誤。
四、問題排查
1、排查發現order-service未設置server.servlet.context-path,user-service有設置;
2、驗證context-path的影響發現在路由設置時path字段值必須加前綴再截取才可以正常路由;
3、由於公司網關是既有產品,當前是技術框架重構,因此不能改動原來接口訪問路徑,因此不可以在原有路徑前面再加前綴;
排查源碼發現請求會經過
FilteringWebHandler的
filter方法,此方法
在路由過程中會走12個過濾器,其中第5個過濾器
RewritePathGatewayFilterFactory中的
apply方法會匹配服務啓動時加載的
regexp正則,從而對服務path進行改寫。
源碼如下:
五、解決方案
1)若配置路由URI爲lb,則註冊中心服務名稱不能和server.servlet.context-path名稱一致,否則contextPath會被改寫爲空字符串;
2)若註冊中心和server.servlet.context-path必須一致,則斷言中設置Path時需在contextPath前包裝一層前綴,且Filter中需截取第一個字符串;