前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gateway 网关路由、断言、过滤

Gateway 网关路由、断言、过滤

作者头像
BUG弄潮儿
发布2021-06-25 19:59:39
1.2K0
发布2021-06-25 19:59:39
举报
文章被收录于专栏:JAVA乐园

0x01: 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 通讯框架。

详见:官网

  • 能干嘛?

反向代理、鉴权、流量控制、熔断、日志监控......

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

0x02:Gateway 的三大概念

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

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

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

0x03:工作流程

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 处理程序。该处理程序通过特定于请求的过滤器链来运行请求。 筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有 “前置“ 过滤器逻辑均被执行,然后发出代理请求,发出代理请求后,将运行“ 后置 ”过滤器逻辑。

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

0x04:两种配置方式

  • 配置文件方式

以访问「百度新闻网」为例,添加如下配置

代码语言:javascript
复制
server:
  port: 9527
spring:
  application:
    name: cloud-gateway9527
  cloud:
    gateway:
      routes:
        - id: news                        # 路由id
          uri: http://news.baidu.com    # 真实调用地址
          predicates:
            - Path=/guonei                # 断言,符合规则进行路由
代码语言:javascript
复制
浏览器虽然输入 localhost:9527/guonei,却会转发到指定的地址
  • 编码方式

新增配置文件

代码语言:javascript
复制
@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();
    }

效果:

0x05:动态路由

开启后,默认情况下 Gateway 会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

代码语言:javascript
复制
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/**

0x06:Predicate 的使用

  • 时间相关配置

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

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

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

代码语言:javascript
复制
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值的正则表达式规则】

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**
  - Cookie=id, [0-9

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

Header

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

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**
  - Header=h, [a-h]

Host

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

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**
  - Host=**.a.com,**.b.cn

Method

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

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**
  - Method=GET

Path

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

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**

Query

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

代码语言:javascript
复制
predicates:
  - Path=/payment/lb/**
  - Query=name, zhangsan

详见:官网

0x07:Filter 的使用

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

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

代码语言:javascript
复制
@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;
    }
}
代码语言:javascript
复制
source:https://www.cnblogs.com/songjilong/p/12774265.html
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BUG弄潮儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01: Gateway 简介
  • 0x02:Gateway 的三大概念
  • 0x03:工作流程
  • 0x04:两种配置方式
  • 0x05:动态路由
  • 0x06:Predicate 的使用
  • 0x07:Filter 的使用
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档