日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringCloud实战小贴士:Zuul的路径匹配

發(fā)布時(shí)間:2024/7/5 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringCloud实战小贴士:Zuul的路径匹配 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

路徑匹配

不論是使用傳統(tǒng)路由的配置方式還是服務(wù)路由的配置方式,我們都需要為每個(gè)路由規(guī)則定義匹配表達(dá)式,也就是上面所說的path參數(shù)。在Zuul中,路由匹配的路徑表達(dá)式采用了Ant風(fēng)格定義。

Ant風(fēng)格的路徑表達(dá)式使用起來非常簡(jiǎn)單,它一共有下面這三種通配符:

通配符說明
?匹配任意的單個(gè)字符
*匹配任意數(shù)量的字符
**匹配任意數(shù)量的字符,支持多級(jí)目錄

我們可以通過下表的示例來進(jìn)一步理解這三個(gè)通配符的含義并參考著來使用:

URL路徑說明
/user-service/?它可以匹配/user-service/之后拼接一個(gè)任務(wù)字符的路徑,比如:/user-service/a、/user-service/b、/user-service/c
/user-service/*它可以匹配/user-service/之后拼接任意字符的路徑,比如:/user-service/a、/user-service/aaa、/user-service/bbb。但是它無法匹配/user-service/a/b
/user-service/**它可以匹配/user-service/*包含的內(nèi)容之外,還可以匹配形如/user-service/a/b的多級(jí)目錄路徑

另外,當(dāng)我們使用通配符的時(shí)候,經(jīng)常會(huì)碰到這樣的問題:一個(gè)URL路徑可能會(huì)被多個(gè)不同路由的表達(dá)式匹配上。比如:有這樣的一個(gè)場(chǎng)景,我們?cè)谙到y(tǒng)建設(shè)的一開始實(shí)現(xiàn)了user-service服務(wù),并且配置了如下路由規(guī)則:

zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.serviceId=user-service

但是隨著版本的迭代,我們對(duì)user-service服務(wù)做了一些功能拆分,將原屬于user-service服務(wù)的某些功能拆分到了另外一個(gè)全新的服務(wù)user-service-ext中去,而這些拆分的外部調(diào)用URL路徑希望能夠符合規(guī)則/user-service/ext/**,這個(gè)時(shí)候我們需要就在配置文件中增加一個(gè)路由規(guī)則,完整配置如下:

zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.serviceId=user-service

zuul.routes.user-service-ext.path=/user-service/ext/**
zuul.routes.user-service-ext.serviceId=user-service-ext

這個(gè)時(shí)候,調(diào)用user-service-ext服務(wù)的URL路徑實(shí)際上會(huì)同時(shí)被/user-service/**和/user-service/ext/**兩個(gè)表達(dá)式所匹配。在邏輯上,API網(wǎng)關(guān)服務(wù)需要優(yōu)先選擇/user-service/ext/**路由,然后再匹配/user-service/**路由才能實(shí)現(xiàn)上述需求。但是如果使用上面的配置方式,實(shí)際上是無法保證這樣的路由優(yōu)先順序的。

從下面的路由匹配算法中,我們可以看到它在使用路由規(guī)則匹配請(qǐng)求路徑的時(shí)候是通過線性遍歷的方式,在請(qǐng)求路徑獲取到第一個(gè)匹配的路由規(guī)則之后就會(huì)返回并結(jié)束匹配過程。所以當(dāng)存在多個(gè)匹配的路由規(guī)則時(shí),匹配結(jié)果完全取決于路由規(guī)則的保存順序。

@Override
public Route getMatchingRoute(final String path) {
...
ZuulRoute route = null;
if (!matchesIgnoredPatterns(adjustedPath)) {
for (Entry<String, ZuulRoute> entry : this.routes.get().entrySet()) {
String pattern = entry.getKey();
log.debug("Matching pattern:" + pattern);
if (this.pathMatcher.match(pattern, adjustedPath)) {
route = entry.getValue();
break;
}
}
}
log.debug("route matched=" + route);
return getRoute(route, adjustedPath);
}

下面所示代碼是基礎(chǔ)的路由規(guī)則加載算法,我們可以看到這些路由規(guī)則是通過LinkedHashMap保存的,也就是說路由規(guī)則的保存是有序的,而內(nèi)容的加載是通過遍歷配置文件中路由規(guī)則依次加入的,所以導(dǎo)致問題的根本原因是對(duì)配置文件中內(nèi)容的讀取。

protected Map<String, ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
for (ZuulRoute route : this.properties.getRoutes().values()) {
routesMap.put(route.getPath(), route);
}
return routesMap;
}

由于properties的配置內(nèi)容無法保證有序,所以當(dāng)出現(xiàn)這種情況的時(shí)候,為了保證路由的優(yōu)先順序,我們需要使用YAML文件來配置,以實(shí)現(xiàn)有序的路由規(guī)則,比如使用下面的定義:

zuul:
routes:
user-service-ext:
path: /user-service/ext/**
serviceId: user-service-ext
user-service:
path: /user-service/**
serviceId: user-service

忽略表達(dá)式

通過path參數(shù)定義的Ant表達(dá)式已經(jīng)能夠完成API網(wǎng)關(guān)上的路由規(guī)則配置功能,但是為了更細(xì)粒度和更為靈活的配置路由規(guī)則,Zuul還提供了一個(gè)忽略表達(dá)式參數(shù):zuul.ignored-patterns。該參數(shù)可以用來設(shè)置不希望被API網(wǎng)關(guān)進(jìn)行路由的URL表達(dá)式。

比如,以快速入門中的示例為基礎(chǔ),如果我們不希望/hello接口被路由,那么我們可以這樣設(shè)置:

zuul.ignored-patterns=/**/hello/**
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=hello-service

然后,可以嘗試通過網(wǎng)關(guān)來訪問hello-service的/hello接口:http://localhost:5555/api-a/hello。雖然該訪問路徑的完全符合path參數(shù)定義的/api-a/**規(guī)則,但是由于該路徑符合zuul.ignored-patterns參數(shù)定義的規(guī)則,所以不會(huì)被正確路由。同時(shí),我們?cè)诳刂婆_(tái)或日志中還能看到?jīng)]有匹配路由的輸出信息:

o.s.c.n.z.f.pre.PreDecorationFilter : No route found for uri: /api-a/hello

另外,該參數(shù)在使用時(shí)還需要注意它的范圍并不是對(duì)某個(gè)路由,而是對(duì)所有路由的。所以在設(shè)置的時(shí)候需要全面的考慮URL規(guī)則,防止忽略了不該被忽略的URL路徑。


總結(jié)

以上是生活随笔為你收集整理的SpringCloud实战小贴士:Zuul的路径匹配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。