首页 科技正文

浙江金华新闻:SpringCloud-Gateway 网关路由、断言、过滤

admin 科技 2020-04-26 43 0

Gateway 简介

是什么?

Spring Cloud 全家桶中有个很主要的组件:网关。在 1.x 版本中使用的是 Zuul 网关,然则到了 2.x,由于Zuul的升级不停跳票,Spring Cloud 自己研发了一套网关组件:Spring Cloud Gateway。

Spring Cloud Gateway基于 Spring Boot 2.x,Spring WebFlux 和 Project Reactor 构建,使用了 Webflux 中的 reactor-netty 响应式编程组件,底层使用了 Netty 通讯框架。

详见:官网

能干嘛?

反向署理

鉴权

流量控制

熔断

日志监控

......

网关在微服务架构中的位置

Gateway 的三大观点

Route(路由):路由是构建网关的基本模块,它由 ID、目的 URI、一系列的断言和过滤器组成,若是断言为 true 则匹配该路由

Predicate(断言)参考的是 Java8 中的 java.util.function.Predicate。开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),若是请求与断言相匹配则举行路由

Filter(过滤):指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由之前或之后对请求举行修改

事情流程

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.

翻译:客户端向 Spring Cloud Gateway 发出请求。若是网关处置程序映射确定请求与路由匹配,则将其发送到网关 Web 处置程序。该处置程序通过特定于请求的过滤器链来运行请求。 筛选器由虚线分开的原因是,筛选器可以在发送署理请求之前和之后运行逻辑。所有 “前置“ 过滤器逻辑均被执行,然后发出署理请求,发出署理请求后,将运行“ 后置 ”过滤器逻辑。

总结:路由转发 + 执行过滤器链

两种设置方式

设置文件方式

我们以接见「百度新闻网」为例,添加如下设置

server:
  port: 9527
spring:
  application:
    name: cloud-gateway9527
  cloud:
    gateway:
      routes:
        - id: news						# 路由id
          uri: http://news.baidu.com	# 真实挪用地址
          predicates:
            - Path=/guonei				# 断言,相符规则举行路由

浏览器虽然输入 localhost:9527/guonei,却会转发到指定的地址

Sunbet,进入申博Sunbet官网  第1张

编码方式

新增设置文件

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("news2", r -> r.path("/guoji").uri("http://news.baidu.com"))
                .build();
    }
}

效果:

Sunbet,进入申博Sunbet官网  第2张

动态路由

开启后,默认情况下 Gateway 会凭据注册中央注册的服务列表,以注册中央上微服务名为路径建立动态路由举行转发,从而实现动态路由的功效

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中央动态建立路由的功效,行使微服务名举行路由
      routes:
        - id: payment_routh1
          #uri: http://localhost:8001     #静态,写死了地址,只能挪用一个服务
          uri: lb://CLOUD-PAYMENT-SERVICE #动态,lb://微服务名
          predicates:
            - Path=/payment/get/**
        - id: payment_routh2
          #uri: http://localhost:8001
          uri: lb://CLOUD-PAYMENT-SERVICE
          predicates:
            - Path=/payment/lb/**

Predicate 的使用

时间相关设置

After:在指定时间之举行路由

Before:在指定时间之举行路由

Between:在指定时间之举行路由

predicates:
    - Path=/payment/lb/**
    #- After=2020-04-25T16:30:58.215+08:00[Asia/Shanghai]
    #- Before=2020-04-25T16:40:58.215+08:00[Asia/Shanghai]
    - Between=2020-04-25T16:35:58.215+08:00[Asia/Shanghai],2020-04-25T16:40:58.215+08:00[Asia/Shanghai]

上述设置的时间花样可以通过以下代码获得

@Test
public void test(){
    ZonedDateTime now = ZonedDateTime.now();
    System.out.println(now);
}

请求相关设置

Cookie

设置说明:【Cookie=cookie名, cookie值的正则表达式规则】

predicates:
  - Path=/payment/lb/**
  - Cookie=id, [0-9]

使用 curl 工具模拟携带 cookie 发送请求

Sunbet,进入申博Sunbet官网  第3张

Header

设置说明:【Header=header名, header值的正则表达式规则】

predicates:
  - Path=/payment/lb/**
  - Header=h, [a-h]

Sunbet,进入申博Sunbet官网  第4张

Host

设置说明:【Host=主机名(可设置多个,也可以使用通配符)】

predicates:
  - Path=/payment/lb/**
  - Host=**.a.com,**.b.cn

Sunbet,进入申博Sunbet官网  第5张

Method

设置说明:【Method=请求类型】

predicates:
  - Path=/payment/lb/**
  - Method=GET

Sunbet,进入申博Sunbet官网  第6张

Path

设置说明:【Path=请求路径】

predicates:
  - Path=/payment/lb/**

Sunbet,进入申博Sunbet官网  第7张

Query

设置说明:【Query=参数名,参数值】

predicates:
  - Path=/payment/lb/**
  - Query=name, zhangsan

Sunbet,进入申博Sunbet官网  第8张

详见:官网

Filter 的使用

  • 生命周期:pre、post
  • 种类:GatewayFilter、GlobalFilter

GatewayFilter 在官方文档有几十种!详细设置可参考 官网,这里主要先容自定义全局过滤器。

@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        //用户名为空时,给出错误响应
        if (username == null) {
            log.info("用户名为空,非法登录");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

Sunbet,进入申博Sunbet官网  第9张

Sunbet,进入申博Sunbet官网  第10张

获取完整代码

,

Sunbet

Sunbet秉承以客为先的理念,多年运营、专业团队、专注服务、值得信赖。

版权声明

本文仅代表作者观点,
不代表本站Sunbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论