網關服務核心是將進入的請求正確合理的路由到下層具體的服務進行業務處理,由此可見網關服務的核心就是路由信息的構建。下面學習和閱讀下Spring-Cloud-Gateway的route數據模型
首先查看Route模型的代碼如下:
public class Route implements Ordered {
/**
* 路由編號
* ID 編號,唯一
*/
private final String id;
/**
* 路由向的 URI
*
*/
private final URI uri;
/**
* 順序
* 當請求匹配到多個路由時,使用順序小的
*/
private final int order;
/**
* 謂語數組
* 請求通過 predicates 判斷是否匹配
*/
private final Predicate<ServerWebExchange> predicate;
/**
* 過濾器數組
*/
private final List<GatewayFilter> gatewayFilters;
}
由代碼可以看到一個路由應該包含如下必要的信息:
- id:路由編號,唯一
- uri:路由向的 URI,對應的具體業務服務的URL
- order:順序,當請求匹配多個路由時,使用順序小的
- predicate: 請求匹配路由的斷言條件
- gatewayFilters: 當前路由上存在的過濾器,用于對請求做攔截處理
Route模型是通過RouteDefinition(路由定義)模型構建起來的,接下來查看RouteDefinition
/**
* 路由定義實體信息,包含路由的定義信息
* @author Spencer Gibb
*/
@Validated
public class RouteDefinition {
/**
* 路由ID 編號,唯一
*/
@NotEmpty
private String id = UUID.randomUUID().toString();
/**
* 謂語定義數組
* predicates 屬性,謂語定義數組
* 請求通過 predicates 判斷是否匹配。在 Route 里,PredicateDefinition 轉換成 Predicate
*/
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
/**
*過濾器定義數組
* filters 屬性,過濾器定義數組。
* 在 Route 里,FilterDefinition 轉換成 GatewayFilter
*/
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
/**
* 路由指向的URI
*/
@NotNull
private URI uri;
/**
* 順序
*/
private int order = 0;
}
這個模型與上面的Route模型是不是很相似,它是對route的定義以及描述,Spring-Cloud-Gateway最終會通過RouteDefinition來構建起Route實例信息。
細看RouteDefinition代碼會發現其中包含兩個數組分別是PredicateDefinition,FilterDefinition的數組。
- PredicateDefinition : 斷言條件(謂語)定義,構建 Route 時,PredicateDefinition 轉換成 Predicate
- FilterDefinition : 過濾條件的定義,構建Route 時,FilterDefinition 轉換成 GatewayFilter
那么我們看下PredicateDefinition與FilterDefinition的代碼
- PredicateDefinition
/**
* 謂語定義,在 Route 里,PredicateDefinition將轉換成 Predicate
* @author Spencer Gibb
*/
@Validated
public class PredicateDefinition {
/**
* 謂語定義名字
* 通過 name 對應到 org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory 的實現類。
* 例如: name=Query 對應到 QueryRoutePredicateFactory
*/
@NotNull
private String name;
/**
* 參數數組
* 例如,name=Host / args={"_genkey_0" : "iocoder.cn"} ,匹配請求的 hostname 為 iocoder.cn
*/
private Map<String, String> args = new LinkedHashMap<>();
}
PredicateDefinition 描述了構建Predicate的必要條件
- name:名稱,Spring-Cloud-Gateway會根據name找到Predicate的構建工廠類
- args:參數,構建Predicate的參數
- FilterDefinition
/**
* 過濾器定義,在 Route 里,FilterDefinition將轉換成 GatewayFilter
* @author Spencer Gibb
*/
@Validated
public class FilterDefinition {
/**
* 過濾器定義名字
* 通過 name 對應到 org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory 的實現類。
* 例如,name=AddRequestParameter 對應到 AddRequestParameterGatewayFilterFactory
*/
@NotNull
private String name;
/**
* 參數數組
* 例如 name=AddRequestParameter / args={"_genkey_0": "foo", "_genkey_1": "bar"} ,添加請求參數 foo 為 bar
*/
private Map<String, String> args = new LinkedHashMap<>();
}
FilterDefinition 描述了構建GatewayFilter的必要條件
- name:名稱,Spring-Cloud-Gateway會根據name找到GatewayFilter的構建工廠類
- args:參數,構建GatewayFilter的參數
通過這些基礎的數據模型我可以清晰看到Spring-Cloud-Gateway構建路由的數據流向
路由數據流向.png
通過數據流向可以幫助我們接下來閱讀Route信息的初始化加載以及路由的使用