spring-cloud-starter-gateway进阶版

上一篇服务向eureka注册实现路由调用简单介绍了gateway的使用,解下来进行详细的介绍它的作用以及如何使用

先来认识下源码,基本属性如下

public class Route implements Ordered {
        /**
         *含义:id是路由的唯一标识符。它用于在整个网关配置中区分不同的路由规则。
         * 用途:在日志记录、配置管理和调试过程中非常有用。
         * 例如,当你想要查看特定路由的请求处理情况或者更新 / 删除某一特定路由配置时,可以通过id来定位该路由。
         */
        private final String id;
        /**
         *含义:uri表示路由的目标地址。这个地址可以是一个 HTTP/HTTPS 端点、一个服务发现名称(
         * 例如在使用服务发现组件时,像lb://service - name这种形式,其中lb表示负载均衡,
         * service - name是后端服务的名称)或者其他支持的协议端点。
         * 用途:当网关根据路由的predicate(断言)匹配到一个请求后,就会将该请求转发到这个uri所指定的目标地址进行后续处理。
         */
        private final URI uri;
        /**
         *含义:order用于定义路由的优先级顺序。Route实现了Ordered接口,order属性的值决定了路由在处理请求时的顺序。
         * 用途:当多个路由的predicate(断言)都匹配一个请求时,order值较小的路由将优先被应用。
         * 这对于处理具有重叠路径模式或者复杂路由规则的情况非常有用,比如有些请求可能同时满足多个路由规则,
         * 通过order可以明确先使用哪个路由规则来处理。
         */
        private final int order;
        /**
         *含义:AsyncPredicate<ServerWebExchange>类型的predicate是一个异步断言。
         * 它用于判断一个传入的ServerWebExchange(包含了请求和响应相关的上下文信息)是否满足该路由的条件。
         * 用途:例如,通过路径匹配、请求头检查等条件来决定一个请求是否应该被这个路由规则处理。
         * 如果predicate返回true,则表示请求符合该路由规则,网关会继续应用该路由的过滤器并将请求转发到uri指定的目标;
         * 如果predicate返回false,则该路由规则不处理这个请求。
         */
        private final AsyncPredicate<ServerWebExchange> predicate;
        /**
         *含义:List<GatewayFilter>类型的gatewayFilters是一个网关过滤器列表。
         * 这些过滤器可以在请求被路由到目标uri之前或之后对请求和响应进行各种处理。
         * 用途:比如添加请求头、修改请求参数、记录日志、进行安全认证等操作。
         * 过滤器可以串联起来,按照它们在列表中的顺序依次对请求和响应进行处理,从而实现复杂的请求 / 响应处理逻辑。
         */
        private final List<GatewayFilter> gatewayFilters;
        /**
         *含义:Map<String, Object>类型的metadata是一个用于存储路由相关元数据的属性。它可以包含任意自定义的键值对信息。
         * 用途:这些信息可以用于一些高级的路由配置或者与其他组件进行交互。
         * 例如,存储特定路由的版本信息、特定的配置参数(如是否启用某个特殊功能等)等。
         */
        private final Map<String, Object> metadata;
    }

 

上面的id其实就是起到个全局唯一的作用,uri就是具体的请求具体的服务路径,order就是路由的顺序,predicates就是请求具体服务里面的具体路径,gatewayFilters就是拦截器支撑请求前后的加工,metadata可以提供
额外的参数传递

 

比如properties配置文件中这种配置:

#路由ID没有固定规则,但要求唯一,建议配合服务名
spring.cloud.gateway.routes[1].id=payment_0001
#匹配后服务提供的路由地址
#spring.cloud.gateway.routes[1].uri=http://localhost:8002
#url协议需要使用lb表示启用Gateway的负载均衡  cloud-payment-server这个是服务注册到注册中心的名称,如果没有注册中心,就只能向上面的具体地址http://localhost:8002一样调用了
spring.cloud.gateway.routes[1].uri=lb://cloud-payment-server
#断言路径相匹配进行路由
spring.cloud.gateway.routes[1].predicates[0]=Path=/0000/payment/payment/lb/**
# 去掉前缀
spring.cloud.gateway.routes[1].filters[0]=StripPrefix=1
# 路径前面会加myprefix  加上/myprefix
#spring.cloud.gateway.routes[1].filters[1]=PrefixPath=/myprefix
#在这个时间之后生效
#spring.cloud.gateway.routes[1].predicates[0]=After=2021-01-28T20:20:44.157+08:00[Asia/Shanghai]

 当然了也可以改成yml里面的这种配置:

spring:
  cloud:
    gateway:
      routes:
        #路由ID没有固定规则,但要求唯一,建议配合服务名
        - id: payment_0001
#          uri=http://localhost:8002
          #url协议需要使用lb表示启用Gateway的负载均衡  cloud-payment-server这个是服务注册到注册中心的名称,如果没有注册中心,就只能向上面的具体地址http://localhost:8002一样调用了
          uri: lb://cloud-payment-server
          #断言路径相匹配进行路由
          predicates:
            - Path=/0000/payment/payment/lb/**
            #在这个时间之后生效
            - After=2021-01-28T20:20:44.157+08:00[Asia/Shanghai]
          # 去掉前缀
          filters:
            - StripPrefix=1
             # 路径前面会加myprefix  加上/myprefix
            - PrefixPath=/myprefix

 也可以使用代码的方式进行配置:

@Configuration
public class GateWayConfig {
    /**
     * 这里如果把配置好的路由放单独维护起来,也可以不放nacos配置中心,也可以放到自己的表里维护起来,然后读取路由集合
     * 注册到下面嘛
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("payment_0001",
                        r -> r.path("/0000/payment/payment/lb/**")
                                .filters(f -> f.stripPrefix(1)
//                                        .filter(prefixPathFilter("/myprefix"))
                                )
                                .uri("lb://cloud-payment-server"))
                .build();
    }
    
    private GatewayFilter prefixPathFilter(String prefix) {
        PrefixPathGatewayFilterFactory.Config config = new PrefixPathGatewayFilterFactory.Config();
        config.setPrefix(prefix);
        return new PrefixPathGatewayFilterFactory().apply(config);
    }
}

 


 

TIPS:这里别上来就抄老夫的代码,要注意细节,配置文件的方式转换成代码时,就得看源码了。

接下来介绍下Route的部分源码

 

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("payment_0001",
                        r -> r.path("/0000/payment/payment/lb/**")
                                .filters(f -> f.stripPrefix(1)
                                )
                                .uri("lb://cloud-payment-server"))
//                //如果有多个路由就可以 .route()里面上面类似
//                .route()
//                ......
                .build();
    }

 第一步:

 第二步:

 

 第三步:

 第四步:

第五步:

奇不奇怪,现在都没有看到外边定义的path,uri和filter在哪,先找个明显的看看

 第六步:

 第七步:

 第八步:
点击AbstractBuilder看看它的源码

 

其实在第二步,第三步就有Route.AsyncBuilder,只不过,建造者模式与抽象类的层层加码封装看起来没那么的直接罢了,这下知道设计模式的牛逼了吧,下一篇继续讲解网关的进阶版

 

posted @ 2024-12-30 22:23  余生请多指教ANT  阅读(77)  评论(0)    收藏  举报