Spring Cloud:Gateway(统一服务入口)

Api 网关

也是一种服务,就是通往后端的唯一入口,类似于整个微服务架构的门面,所有的外部客户端进行访问,都需要经过它来进行过滤和调度,类似于公司的前台

而Spring Cloud Gateway就是Api网关的一种具体实现

网关的核心功能

  • 权限控制:作为微服务的入口,对用户进行权限校验,校验失败则会进行拦截
  • 动态路由:一切的请求先经过网关,但是网关不处理业务,而是根据某种规则,把请求转发到某个微服务
  • 负载均衡:当路由的服务目标有多个时,还需要做负载均衡
  • 限流:请求流量过高时,按照网关中配置微服务能够接受的流量进行放行,避免服务压力过大

Spring Cloud Gateway的使用

实现需要先引入网关的依赖

复制代码
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

添加Gateway的路由配置

复制代码
server:
  port: 10030
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 123.57.4.74:8848
    gateway:
      routes: #网关配置
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/product/**
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

通过Api网关服务访问product-service服务和order-service服务

RoutePredicate Factories(路由断言工厂)

用于定义路由的匹配条件

Predicate

用于确定请求是否匹配某个路由的条件

接受一个参数,返回一个布尔类型,用于判断接受的请求参数是否满足条件

定义⼀个Predicate

判断请求参数s是否为空,为空为true

java 复制代码
public class StringPredicate implements Predicate<String> {
    @Override
    public boolean test(String s) {
        return s==null || s.isEmpty();
    }
}

使用

java 复制代码
    @Test
    public void test1(){
        Predicate<String> predicate=new StringPredicate();
        System.out.println(predicate.test("aa"));
        System.out.println(predicate.test(""));
    }

Predicate的其他写法

内置函数

java 复制代码
@Test
    public void test(){
        Predicate<String> predicate=new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s==null || s.isEmpty();
            }
        };
        System.out.println(predicate.test("aa"));
        System.out.println(predicate.test(""));
    }

lambda形式

java 复制代码
@Test
    public void test2(){
        Predicate<String> predicate= s-> s==null || s.isEmpty();
        System.out.println(predicate.test("aa"));
        System.out.println(predicate.test(""));
    }

其他方法

negate()求反

java 复制代码
@Test
    public void test3(){
        Predicate<String> predicate= s-> s==null || s.isEmpty();
        System.out.println(predicate.negate().test("aa"));
        System.out.println(predicate.negate().test(""));
    }

or()

java 复制代码
@Test
    public void test4(){
        Predicate<String> predicate= s-> "aa".equals(s);
        Predicate<String> predicate2= s-> "bb".equals(s);
        System.out.println(predicate.or(predicate).test("aa"));
        System.out.println(predicate.or(predicate).test(""));
    }

and()

java 复制代码
 @Test
    public void test5(){
        Predicate<String> predicate= s-> s!=null && s.isEmpty();
        Predicate<String> predicate2= s-> s!=null && s.chars().allMatch(Character::isDigit);
        System.out.println(predicate.and(predicate2).test("aa"));
        System.out.println(predicate.and(predicate2).test("123"));
    }

Spring Cloud Gateway默认提供了很多RoutePredicateFactory,这些Predicate会分别匹配HTTP请 求的不同属性,并且多个Predicate可以通过and逻辑进⾏组合

匹配指定如期之后的请求

匹配指定如期之前的请求

指定的Cookie和Header

及该cookie或者header值符合指定的正则表达式

具体详细看Route Predicate Factories :: Spring Cloud Gateway

GatewayFilter Factories(网关过滤工厂)

predicate决定了请求由哪一个路由处理,如果在请求处理前后需要加上一些逻辑,这就是Filter(过滤器)的作用范围了

Filter分为两种类型:Pre类型和Post类型

  • Pre类型过滤器:路由处理前执行(转发到后端服务之前执行),在Pre类型过滤器中可以做鉴权,限流的处理
  • Post类型过滤器:请求执行完成后,将结果返回给客户端之前执行

gateway可将把Filter可分为GatewayFilter和GlobalFilter

  • GatewayFilter只对一个路由起作用
  • GlobalFilter对所有的路由起作用

Spring Cloud Gateway提供了非常多的Filter

GatewayFilter Factories :: Spring Cloud Gateway

过滤器执⾏顺序

请求路由后,网关会把当前项目中的Gateway和GlobalFilter合并到一个过滤链中,并进行排序,一次执行过滤器

每个过滤器必须指定一个int类型的order值,默认值为0,表示该过滤的优先级,order值越小,优先级越高,排序越靠前

自定义过滤器

自定义Gateway Filter

java 复制代码
@Service
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {
    private static final Logger log = LoggerFactory.getLogger(CustomGatewayFilterFactory.class);

    public CustomGatewayFilterFactory() {
        super(CustomConfig.class);
    }

    @Override
    public GatewayFilter apply(CustomConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                log.info(" pre Filter,Config:{}",config);
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    log.info("post Filter");
                }));
            }
        };
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
java 复制代码
@Data
public class CustomConfig {
    private String name;
}

注:类名统⼀以GatewayFilterFactory结尾,因为默认情况下,过滤器的name会采⽤该定义类的前缀.这⾥的name=Custom(yml配置中使⽤)

then方法是请求执行之后处理的

getOrder是定义优先级,值越大,优先级越小

测试

自定义GlobalFilter

java 复制代码
@Component
@Slf4j
public class CustomGlobalFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("pre filter");
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            log.info("post filter");
        }));
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

测试

此时的order-service并没有定义Filter

全局过滤器定义成功

希望对大家有所帮助!!!!!

相关推荐
whz-emm7 小时前
vLLM加载lora
gateway
黑客影儿7 小时前
Java技术总监的成长之路(技术干货分享)
java·jvm·后端·程序人生·spring·tomcat·maven
Derek_Smart15 小时前
Java线程死亡螺旋:解析与预防策略
java·spring·性能优化
源码宝1 天前
【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
java·大数据·spring cloud·数据分析·源码·智慧工地·云平台
J_bean1 天前
Spring AI Alibaba 项目接入兼容 OpenAI API 的大模型
人工智能·spring·大模型·openai·spring ai·ai alibaba
2301_793086871 天前
SpringCloud 07 微服务网关
java·spring cloud·微服务
柳贯一(逆流河版)1 天前
Spring 三级缓存:破解循环依赖的底层密码
java·spring·缓存·bean的循环依赖
蚰蜒螟1 天前
Spring 和 Lettuce 源码分析 Redis 节点状态检查与失败重连的工作原理
java·redis·spring
duration~1 天前
SpringAI集成MCP
人工智能·后端·spring·ai
悟纤1 天前
Spring Boot 实用小技巧:多级缓存(Caffeine + Redis)- 第545篇
spring boot·后端·spring