官网地址:https://docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html/
1.网关入门 helloword
网关不依赖start-web
导入的pom:
<!--gateway-->
<dependency><groupIdorg.springframework.cloud</groupId><artifactIdspring-cloud-starter-gateway</artifactId><exclusions><exclusion><groupIdorg.springframework.boot</groupId><artifactIdspring-boot-starter-web</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupIdcom.alibaba.cloud</groupId><artifactIdspring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 指标监控健康检查的actuator,网关是响应式编程删除掉spring-boot-starter-web dependency-->
<dependency><groupIdorg.springframework.boot</groupId><artifactIdspring-boot-starter-actuator</artifactId>
</dependency>
<!--lombok-->
<dependency><groupIdorg.projectlombok</groupId><artifactIdlombok</artifactId><version1.18.28</version><scopeprovided</scope>
配置文件:
server:port: 8085spring:application:name: gateway-servicecloud:gateway:routes:#路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名- id: order-service#匹配后提供服务的路由地址uri: http://localhost:8081/#uri: http://cloud-payment-service #匹配后提供服务的路由地址# 断言,路径相匹配的进行路由predicates:- Path=/order/getOrder
直接访问网关服务+网关端口-》
http://localhost:8085/order/getOrder
最后服务转发到8081服务对应的接口上
2.使用服务名的方式调用网关
正常我们会使用服务名的方式进行服务间的调用
不会使用端口号的形式,不然端口号的变更很难维护
变更配置文件
引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
变更配置文件
server:port: 8085spring:application:name: gateway-servicecloud:gateway:routes:#路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名- id: order-service#匹配后提供服务的路由地址uri: lb://order-service#uri: http://cloud-payment-service #匹配后提供服务的路由地址# 断言,路径相匹配的进行路由predicates:- Path=/order/getOrder
3.常用的内置Route Predicate
是什么?
Spring Cloud Gateway包含许多内置的路由谓词工厂。 所有这些谓词都匹配HTTP请求的不同属性。 您可以使用逻辑 and
语句来联合组合多个路由谓词工厂。
在gateway服务启动的时候会看到这样的日志
After,before....
Gateway 启动的时候会加载默认的谓词工厂
1.Predicate之After
配置文件变更:
server:port: 8085spring:application:name: gateway-servicecloud:gateway:routes:#路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名- id: order-service#匹配后提供服务的路由地址uri: lb://order-service#uri: http://cloud-payment-service #匹配后提供服务的路由地址# 断言,路径相匹配的进行路由predicates:- Path=/order/getOrder- After=2023-07-07T22:14:00.583857100+08:00[Asia/Shanghai]
局部变更
- After=2023-07-07T22:14:00.583857100+08:00[Asia/Shanghai]
after用于限定请求的处理时间,只有在指定时间之后的请求才会被匹配并路由。给出的配置:
生成时间的方式:
public class DateUtil {public static void main(String[] args) {System.out.println(ZonedDateTime.now());}
}
结果:2024-07-07T22:09:45.583857100+08:00[Asia/Shanghai]
应用场景:
举个例子:抢茅台,设置茅台开始抢购的时间
只有到该时间之后接口才会有效,否则一直404
4.Predicate之Cookie
包含cookie且值匹配
-
Cookie=username,zhangsan
配置如下:
server:port: 8085spring:application:name: gateway-servicecloud:gateway:routes:#路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名- id: order-service#匹配后提供服务的路由地址uri: lb://order-service#uri: http://cloud-payment-service #匹配后提供服务的路由地址# 断言,路径相匹配的进行路由predicates:- Path=/order/getOrder- After=2024-07-07T22:14:00.583857100+08:00[Asia/Shanghai]#- Before=2023-07-08T21:09:00.583857100+08:00[Asia/Shanghai]- Cookie=username,zhangsan
精确匹配,匹配不到404
4.Predicate之Header
配置如下
predicates:- Path=/order/getOrder- After=2024-07-07T22:14:00.583857100+08:00[Asia/Shanghai]#- Before=2023-07-08T21:09:00.583857100+08:00[Asia/Shanghai]- Cookie=username,zhangsan#- Header=X-Request-Id=123456 \d+ #请求头要有X-Request-Id且值正整数的正表达式
如果输入的是字符串404
- Host=**.css.com
请求头包含任意值后缀是css.com的域名
4.Predicate之Query Route 谓词工厂
指定请求里必须包含参数,允许正则表达式
-
- Query=username,\d+ 要有参数名username并且必须是整数
-
- RemoteAddr=192.168.124.1/24 # 外部访问我的ip限制,最大跨度不超过32,目前是1-24-
-
- Method=
4.自定义predicate
gateway的谓词断言和原生的写法很类似,照葫芦画瓢,参考源码。
新建一个自定义的路由断言工厂,格式和源码格式一样
参考After谓词 源码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.cloud.gateway.handler.predicate;import jakarta.validation.constraints.NotNull;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import org.springframework.web.server.ServerWebExchange;public class AfterRoutePredicateFactory extends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {public static final String DATETIME_KEY = "datetime";public AfterRoutePredicateFactory() {super(AfterRoutePredicateFactory.Config.class);}public List<String> shortcutFieldOrder() {return Collections.singletonList("datetime");}public Predicate<ServerWebExchange> apply(AfterRoutePredicateFactory.Config config) {return new GatewayPredicate() {public boolean test(ServerWebExchange serverWebExchange) {ZonedDateTime now = ZonedDateTime.now();return now.isAfter(config.getDatetime());}public Object getConfig() {return config;}public String toString() {return String.format("After: %s", config.getDatetime());}};}public static class Config {@NotNullprivate ZonedDateTime datetime;public Config() {}public ZonedDateTime getDatetime() {return this.datetime;}public void setDatetime(ZonedDateTime datetime) {this.datetime = datetime;}}
}
Config 内部类对应yaml文件里的配置,咱们在配置After的时候使用的是
-
After=time.....
这里要变更成我们自己的pridicate这里的配置就可以按照我们自己定义的规则配置。
gateway支持两种配置方式
-
1.Shortcut Configuration
-
2.Fully Expanded Arguments
方式一最简单
比如
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- Cookie=mycookie,mycookievalue
方式二
写法参考下面这种方式
Args key value
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- name: Cookieargs:name: mycookieregexp: mycookievalue
官网地址:docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html
假设业务场景:
有这样一个业务场景,请求参数里面必须包含一个参数为userType的参数,该参数代表着用户的会员等级,只有会员等级为gold的才可以访问。
代码实现
package com.css.tom.mypridicate;import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.util.function.Predicate;/*** @author weiwensi* @version 1.0-SNAPSHOT* @since 2024/7/8 21:49*/
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {public MyRoutePredicateFactory() {super(MyRoutePredicateFactory.Config.class);}@Overridepublic Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {//serverWebExchange 这个参数 相当于servlet的request@Overridepublic boolean test(ServerWebExchange serverWebExchange) {String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");if (userType == null) {return false;}//如果说参数存在,就和Config进行比较if(userType.equalsIgnoreCase(config.getUserType())){return true;}return false;}};}//这个Config类就是我们的路断言规则,很重要public class Config {@Setter@Getterprivate String userType; //对应会员等级 /钻石,金牌,银牌}
}
配置文件配置(Fully方式)
- name: Myargs:userType: diamond
如果使用shortcut的方式自定义实现代码里参考After的
public List<String> shortcutFieldOrder() {return Collections.singletonList("datetime");}
增加如下代码:
public List<String> shortcutFieldOrder() {return Collections.singletonList("userType");}
完整代码:
package com.css.tom.mypridicate;import lombok.Getter;
import lombok.Setter;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;/*** @author weiwensi* @version 1.0-SNAPSHOT* @since 2024/7/8 21:49*/
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {public MyRoutePredicateFactory() {super(MyRoutePredicateFactory.Config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("userType");}@Overridepublic Predicate<ServerWebExchange> apply(MyRoutePredicateFactory.Config config) {return new Predicate<ServerWebExchange>() {//serverWebExchange 这个参数 相当于servlet的request@Overridepublic boolean test(ServerWebExchange serverWebExchange) {String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");if (userType == null) {return false;}//如果说参数存在,就和Config进行比较if(userType.equalsIgnoreCase(config.getUserType())){return true;}return false;}};}//这个Config类就是我们的路断言规则,很重要public class Config {@Setter@Getterprivate String userType; //对应会员等级 /钻石,金牌,银牌}
}
5.gateway过滤器
类型
-
全局默认过滤器 Global Filters
-
单一内置过滤器 GatewayFilter
-
自定义过滤器
官网地址:docs.spring.io/spring-cloud-gateway/docs/current/reference/html#global-filters
gateway内置过滤器
docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
38个 分组
-
RequestHeader 相关组
-
请求参数 Requestparameter 相关组
-
回应头 ResponseHeader 相关组
-
前缀和路径相关组
-
其他
配置文件配置