不論是使用傳統路由的配置方式還是服務路由的配置方式,我們都需要為每個路由規則定義匹配表示式,也就是上面所說的path
引數。在zuul中,路由匹配的路徑表示式採用了ant風格定義。
ant風格的路徑表示式使用起來非常簡單,它一共有下面這三種萬用字元:
萬用字元說明
?匹配任意的單個字元
*匹配任意數量的字元
**匹配任意數量的字元,支援多級目錄
url路徑
說明/user-service/?
它可以匹配/user-service/
之後拼接乙個任務字元的路徑,比如:/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/*
包含的內容之外,還可以匹配形如/user-service/a/b
的多級目錄路徑
另外,當我們使用萬用字元的時候,經常會碰到這樣的問題:乙個url路徑可能會被多個不同路由的表示式匹配上。比如:有這樣的乙個場景,我們在系統建設的一開始實現了user-service
服務,並且配置了如下路由規則:
zuul.routes.user-service.path=/user-service/**
zuul.routes.user-service.serviceid=user-service
但是隨著版本的迭代,我們對user-service
服務做了一些功能拆分,將原屬於user-service
服務的某些功能拆分到了另外乙個全新的服務user-service-ext
中去,而這些拆分的外部呼叫url路徑希望能夠符合規則/user-service/ext/**
,這個時候我們需要就在配置檔案中增加乙個路由規則,完整配置如下:
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
這個時候,呼叫user-service-ext
服務的url路徑實際上會同時被/user-service/**
和/user-service/ext/**
兩個表示式所匹配。在邏輯上,api閘道器服務需要優先選擇/user-service/ext/**
路由,然後再匹配/user-service/**
路由才能實現上述需求。但是如果使用上面的配置方式,實際上是無法保證這樣的路由優先順序的。
從下面的路由匹配演算法中,我們可以看到它在使用路由規則匹配請求路徑的時候是通過線性遍歷的方式,在請求路徑獲取到第乙個匹配的路由規則之後就會返回並結束匹配過程。所以當存在多個匹配的路由規則時,匹配結果完全取決於路由規則的儲存順序。
@override
public route getmatchingroute(final string path)
} }log.debug("route matched=" + route);
return getroute(route, adjustedpath);
}
下面所示**是基礎的路由規則載入演算法,我們可以看到這些路由規則是通過linkedhashmap
儲存的,也就是說路由規則的儲存是有序的,而內容的載入是通過遍歷配置檔案中路由規則依次加入的,所以導致問題的根本原因是對配置檔案中內容的讀取。
protected maplocateroutes()
return routesmap;
}
由於properties
的配置內容無法保證有序,所以當出現這種情況的時候,為了保證路由的優先順序,我們需要使用yaml檔案來配置,以實現有序的路由規則,比如使用下面的定義:
zuul:
routes:
user-service-ext:
path: /user-service/ext/**
serviceid: user-service-ext
user-service:
path: /user-service/**
serviceid: user-service
忽略表示式
通過path
引數定義的ant表示式已經能夠完成api閘道器上的路由規則配置功能,但是為了更細粒度和更為靈活的配置路由規則,zuul還提供了乙個忽略表示式引數:zuul.ignored-patterns
。該引數可以用來設定不希望被api閘道器進行路由的url表示式。
比如,以快速入門中的示例為基礎,如果我們不希望/hello
介面被路由,那麼我們可以這樣設定:
zuul.ignored-patterns=/**/hello/**
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceid=hello-service
然後,可以嘗試通過閘道器來訪問hello-service
的/hello
介面:http://localhost:5555/api-a/hello
。雖然該訪問路徑的完全符合path
引數定義的/api-a/**
規則,但是由於該路徑符合zuul.ignored-patterns
引數定義的規則,所以不會被正確路由。同時,我們在控制台或日誌中還能看到沒有匹配路由的輸出資訊:
o.s.c.n.z.f.pre.predecorationfilter : no route found for uri: /api-a/hello
另外,該引數在使用時還需要注意它的範圍並不是對某個路由,而是對所有路由的。所以在設定的時候需要全面的考慮url規則,防止忽略了不該被忽略的url路徑。 springcloud zuul 路由配置
自定義微服務的訪問路徑 配置zuul.routes.指定微服務的serviceid 指定路徑即可。例如 zuul routes microservice provider user user 這樣設定,microservice provider user微服務就會被對映到 user 路徑。忽略指定微...
Spring Cloud zuul 負載均衡
eureka的pom檔案 org.springframework.cloud spring cloud starter eureka server org.springframework.boot spring boot starter security org.springframework.bo...
Spring Cloud Zuul許可權整合
由於zuul對請求 全程的可控性,我們可以在 requestcontext的基礎上做任何事情,設定乙個執行順序靠前的filter,就可專門 用於對請求特定內容做許可權認證。這種方式的優點是實現靈活度高,可整合已有許可權 系統,對原始系統微服務化特別友好 缺點是需要開發 一套新的邏輯,維護增加成本,而...