springcloud-新一代网关Gateway02(七)

 Gateway配置动态路由

  1. 默认情况下Gateway会根据注册中心的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发, 从而实现动态路由的功能.
  2. 修改yml文件
    • 需要注意的是uri的协议为lb, 表示启用Gateway的负载均衡功能.
    • lb://serviceName是SpringCloud Gateway在微服务中为我们创建的负载均衡uri
      server:
        port: 9527
      
      spring:
        application:
          name: cloud-gateway
        cloud:
          gateway:
            discovery:
              locator:
                enabled: true #开启从注册中心动态创建路由的功能, 利用微服务名进行路由
            rout es:
              - id: payment_routh  #路由的ID, 没有固定规则但要求唯一, 建议配合服务名
                uri: lb://cloud-payment-service #匹配后提供服务的路由地址
                predicates:
                  - Path=/payment/get/** #断言, 路径相匹配的进行路由.
      
              - id: payment_routh2
                uri: lb://cloud-payment-service
                predicates:
                  - Path=/payment/lb/**
      
      
      eureka:
        instance:
          hostname: cloud-gateway-service
        client:
          service-url:
            register-with-eureka: true
            fetch-registry: true
            defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  3. 测试
    • 启动7001+8001/8002+9527: http://localhost:9527/payment/lb

Predicate的使用

  • 概述
    • 当我们启动Gateway9527网关的时候

  1.  SpringCloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分.
    • 它包括许多内置的Route Predicate工厂, 所有这些Predicate都与HTTP请求的不同属性匹配, 多个Route Predicate工厂可以进行组合.
  2. SpringClooud Gateway创建Route对象时, 使用RoutePredicateFactory创建Predicate对象, Predicate对象可以赋值给Route, SpringCloud Gateway包含许多内置的Route Predicate Factories.
  3. 所有这些谓词都匹配HTTP请求的不同属性, 多种谓词工厂可以组合, 并通过逻辑and.
  • 常用的Route Predicate
  1. After Route Predicate
    • 在设定的时间之后, 该lb请求访问才有效果.
        predicates:
          - Path=/payment/lb/**
          - After=2020-07-02T17:18:55.216+08:00[Asia/Shanghai]
    • 如何获取这种时间格式 - 使用ZonedDateTime日期类
      public static void main(String[] args) {
      
              ZonedDateTime zbj = ZonedDateTime.now(); //默认时区
              System.out.println(zbj);
      
              //2020-07-02T17:18:55.216+08:00[Asia/Shanghai]
          }
  2. Before Route Predicate
    • 在设定的时间之前, 该lb请求访问才有效果
        predicates:
          - Path=/payment/lb/**
          - Before=2020-08-02T17:18:55.216+08:00[Asia/Shanghai]
  3. Between Route Predicate
    • 在设定的时间之间, 该lb请求访问才有效果
        predicates:
          - Path=/payment/lb/**
          - Between=2020-08-08T10:59:34.102+08:00[Asia/Shanghai], 2020-09-08T10:59:34.102+08:00[Asia/Shanghai]
  4. Cookie Route Prerdicate
    • 需要两个参数, 一个是Cookie name, 另一个是正则表达式.
    • 路由规则会通过Cookie name值和正则表达式去匹配, 如果匹配上才执行路由, 没有匹配则不执行.
        predicates:
          - Path=/payment/lb/**
          - Cookie=username, aakk
    • 测试
      • 不带Cookie访问: curl http://localhost:9527/payment/lb
      • 带Cookie访问
  5. Header Route Predicate
    • 两个参数, 一个是属性名称, 一个是正则表达式
    • 只有请求头满足上述参数配置时该请求才能访问.
        predicates:
          - Path=/payment/lb/**
          - Header=X-Request-Id, \d+ #请求头要由X-Request-Id的属性, 值为整数
    • 测试: curl http://localhost:9527/payment/lb -H "X-Request-Id: 123"
  6. Host Route Predicate
    • 接收一组参数, 一组匹配的域名列表, 这个模板是一个ant分隔的模板, 用逗号做分隔符.
    • 通过参数中的主机地址作为匹配规则
        predicates:
          - Path=/payment/lb/**
          - Host=**.somehost.org, **.anotherhost.org
    • 测试: curl http://localhost:9527/payment/lb -H "Host: aakk.somehost.org"
  7. Method Route Predicate 
    • 填写请求方法.
    • 只有满足才能访问
        predicates:
          - Path=/payment/lb/**
          - Method=GET
  8. Path Route Predicate
      predicates:
        - Path=/payment/lb/**
  9. Query Route Predicate
    • 带查询条件的.
        predicates:
          - Path=/payment/lb/**
          - Query=username, \d+ #要有参数名username并且值还必须时整数才能访问
    • 测试: http://localhost:9527/payment/lb?username=11

Filter的使用

  • 是什么
  1. 路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应, 路由过滤器只能指定路由进行使用.
  2. Spring Cloud Gateway内置了多种路由过滤器, 他们都由Gateway的工厂类来产生.
  • Gateway Filter
  1. 生命周期
    • pre: 在业务逻辑之前
    • post: 在业务逻辑之后
  2. 种类
    • 单一过滤器: GatewayFilter
    • 全局过滤器: GlobalFilter
  • 常用的Gateway Filter
  1. 单一过滤器31种.
  2. 全局过滤器10种.
  • 自定义GlobalFilter
  1. 要实现两个接口GlobalFilter, Ordered
  2. 作用
    • 全局日志记录
    • 统一网关鉴权等.
  3. 演示
    • 在配置类中添加GlobalFilter方法
      @Slf4j
      @Configuration
      public class GatewayConfig {
      
          @Bean
          @Order(0) //优先级
          public GlobalFilter myGlobalFilter() {
              return (exchange, chain) -> {
                  log.info("****come in MyLogGatewayFilter" + new Date());
                  String uname = exchange.getRequest().getQueryParams().getFirst("uname");
                  if(uname == null) {
                      log.info("*****用户名为null, 非法用户");
                      exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                      return exchange.getResponse().setComplete();
                  }
                  return chain.filter(exchange);
              };
          }
      }
  4. 测试
    • http://localhost:9527/payment/lb  ->  该网页无法正常运作
    • http://localhost:9527/payment/lb?uname=111   ->   可以正确显示
posted @ 2020-07-02 19:46  yellowstreak  阅读(217)  评论(0编辑  收藏  举报