spring:
cloud:
gateway:
routes:
- id: test_my_provider # 自定義,全域性唯一即可
uri: http://localhost:8081 # 實際呼叫的地址
predicates:
- Path=/test/** # 請求匹配規則
- id: test_my_consumer
uri: http://localhost:8082
predicates:
- Path=/feign/**
上一篇文章 gateway 快速入門的配置檔案如上,uri 中 ip 和 port 寫死的,請求最終會到具體的某個節點,如果多節點部署,直接G
多節點 uri
8081 對應服務是 my-test-provider,8082 對應的服務是 my-test-consumer,如下改動即可
- id: test_my_provider
uri: lb://my-test-provider # 服務名代替 ip+port
predicates:
- Path=/test/**
- id: test_my_consumer
uri: lb://my-test-consumer # 服務名代替 ip+port
predicates:
- Path=/feign/**
predicates 更多用法
前面 predicates 只是配了一個 Path,表示匹配 url,還能增加判斷規則,即使能找到 url,也要滿足條件才能呼叫,預設的有 12 種
-
時間判斷
-
BeforeRoutePredicateFactory、AfterRoutePredicateFactory、BetweenRoutePredicateFactory
-
指定時間之前、指定時間之後、時間範圍內(如果是範圍英文逗號分隔,start,end)
-
值是 ZonedDateTime 決定的
public static void main(String[] args) { System.out.println(ZonedDateTime.now()); } // 2024-07-15T21:41:48.868923400+08:00[Asia/Shanghai]
-
比如電商系統某個商品限時搶購,2024-07-13 一整天
- id: flash-sale-promotion uri: lb://my-test-provider # 服務名代替 ip+port predicates: - Path=/onsale/** - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai]
-
-
cookie 判斷
- id: flash-sale-promotion uri: lb://my-test-provider # 服務名代替 ip+port predicates: - Path=/onsale/** - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai] - Cookie=username,zhangsan # 請求中必須有 username = zhangsan 的 cookie,後面其實是個政策表示式
-
header 請求頭判斷
- id: flash-sale-promotion uri: lb://my-test-provider # 服務名代替 ip+port predicates: - Path=/onsale/** - Between=2024-07-13T00:00:00+08:00[Asia/Shanghai],2024-07-14T00:00:00+08:00[Asia/Shanghai] - Cookie=username,zhangsan - Header=userage,\d+ # 請求頭必須有 userage,並且值是正整數
-
Path,前面用了很多了,就是透過 url 判斷是否符合
-
Query,請求必須帶有某個 QueryString 才可以(get 請求?xx=xx&xx=xx)
-
RemoteAddr,IP 限制,符合的 IP 才能訪問
-
Method,請求方式限制,只能符合的才能訪問,GET、POST、PUT ...
自定義判斷規則
/**
* 類名必須為 xxxRoutePredicateFactory 格式(RoutePredicateFactory 結尾)
*
* @author yujian
* @since 2024/7/18
*/
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
// 參照別的 RoutePredicateFactory,直接拷過來
public MyRoutePredicateFactory() {
super(MyRoutePredicateFactory.Config.class);
}
// 支援短促的格式配置,引數為 Config 的屬性名,意味著配置檔案要配這個,也可以直接理解為讀取配置檔案的哪個屬性
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("level");
}
/**
* 自定義的 RoutePredicateFactory,請求頭的 token 必須要等於配置檔案的 token 屬性
*
* @param config 配置檔案中 predicates 部分
* @return Predicate
*/
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return serverWebExchange -> {
// 請求 url 必須要帶 level
String level = serverWebExchange.getRequest().getQueryParams().getFirst("level");
if (!StringUtils.hasText(level)) {
return false;
}
// 如果 level = 3 就透過(配置檔案配的3)
return level.equals(config.getLevel());
};
}
@Validated
public static class Config {
private String level;
public String getLevel() {
return level;
}
// 引數不能為空,不然啟動要報錯,可以定時的時候賦個空字串或者這裡加個註解判斷
public void setLevel(@NotNull String level) {
this.level = level;
}
}
}
配置檔案如下,為什麼是 My?因為自定義的判斷是 MyRoutePredicateFactory。My=3 是什麼?判斷配置的屬性 level(使用了短促配置,可以省略,也可以使用full配置)等於 3 就透過
routes:
- id: test_my_provider
uri: http://localhost:8081
predicates:
- Path=/test/** # 請求匹配規則
- My=3 # 自定義的判斷規則
#- name=My 這是 full 配置
# args:
# level: 3
測試,只有帶了 3 才會成功