Bootstrap

「微服务网关实战三」详细理解 SCG 路由、断言与过滤器

又来给大家更文了。

本篇带给大家的是 SpringCloudGateway (下文简称 SCG)的各种断言与过滤器的讲解,由于在上一篇文章中我们已经使用过了断言与过滤器,但是一直没有对其进行大篇幅叙述,这可能会导致部分读者并不知道网关都具有哪些内置功能,所以本篇就是为了带大家全面的认识一下各种各样的断言以及过滤器,让大家在使用 SCG 做项目的时候更加明白:哪些功能需要自己做,哪些功能框架已经自带,避免重复造轮子,减少开发成本。

先赞后看,养成习惯,相信我的文章一定会让大家有所收获,废话不多说,开始了~

1. 路由

在使用 SCG 时,你要记住它的基本使用单位是路由,不是断言,也不是过滤器,断言和过滤器都只是路由的组成部分,所有的请求都是进入到路由中,然后根据路由的规则进行处理的。

在第一篇的时候,我曾经用过 SCG 官网的一张架构图,你可以用它再来做一个理解:

你可以将这张图看作 SCG 的一个路由,根据路由的断言它可以找到要请求的服务,然后在请求这个服务之前会先经过这个路由上的一堆过滤器,最终才是到达目标服务。

然而一个 SCG 肯定会有多个路由,而且很多情况下这些路由断言是有可能重复的,比如 /a 和 /** 这两个断言其实是重复的,这个时候我们还需要一个东西来标识谁在前,谁在后,那么路由里面除了断言和过滤器之外肯定还会有一个权重的概念,用它来处理断言重复情况下的优先级问题。

扯了这么多,我们已经知道一个路由必备的几个东西:断言、过滤器、代理服务、权重,那么接下来我们就看看 SCG 对于路由这个模型定义的数据结构 - RouteDefinition 吧:

/**
 * @author Spencer Gibb
 */
@Validated
public class RouteDefinition {
​
    // 唯一id
    private String id;
​
    @NotEmpty
    @Valid
    // 断言
    private List<PredicateDefinition> predicates = new ArrayList<>();
​
    @Valid
    // 过滤器
    private List<FilterDefinition> filters = new ArrayList<>();
​
    @NotNull
    // 代理服务
    private URI uri;
​
    // 元数据
    private Map<String, Object> metadata = new HashMap<>();
​
    // 权重
    private int order = 0;
​
}
​
复制代码

基本上和我们列举的分毫不差,就是多了一个用于区分路由的id,毕竟路由信息也是存储在内存中的一个 Map,如果没有一个唯一标识那是不行的,而且还多了一个 metadata,用于标识路由元数据,这个东西我们一般用不到,所以也不必关心。

我们在配置路由的时候其实就是配置这些数据,我们来看一下上篇文章中的一个例子:

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route((r) -> r.path("/user/**").uri("lb://user-api"))
            .route((r) -> r.path("/order/**").uri("lb://order-api"))
            .build();
}
复制代码

很明显这个配置 Bean 使用了建造者模式,这里的每一个 router 方法的参数里面装着的都是一个路由,但是可以发现我们在使用的时候并没有配置 id、过滤器和权重,这是因为在你不填的情况下它会默认帮你生成一个 UUID,而权重则默认是0,至于过滤器是真的非必填项,你通过上面的 RouteDefinition 也可以看出&#x

;