关于Springcloud Gateway的使用 小结

本文详细介绍了SpringCloud Gateway的功能和用途,包括作为API网关的角色,实现反向代理、鉴权、流量控制和熔断等。文章重点讲解了Gateway的重要概念,如路由、断言和过滤器,并通过实例展示了如何配置路由映射、动态路由、各种Predicate的使用以及过滤器的实现,包括自定义过滤器。此外,还提供了GitHub上的代码案例供读者参考。

目录

1. Gateway概述

1.1 简介

1.2 用途

2. Gateway重要概念

3. Gateway案例

3.1 路由映射

3.2 路由两种配置方式

3.3 动态路由

3.4 Predicate的使用

3.4.1 After Route Predicate

3.4.2 Before Route Predicate

3.4.3 Between Route Predicate

3.4.4 Cookie Route Predicate

3.4.5 Header Route Predicate

3.4.6 Host Route Predicate

3.4.7 Method Route Predicate

3.4.8 Path Route Predicate

3.4.9 Query  Route Predicate

3.5 Filter的使用

3.5.1 GatewayFilter

3.5.2 自定义过滤器


1. Gateway概述

1.1 简介

Spring Cloud Gateway 是Spring Cloud的一个全新的API网关项目,替换了Zuul1。Gateway可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,实现路由转发、负载均衡、熔断等功能,并且Gateway还内置了限流过滤器,实现了限流的功能。Gateway基于Spring 5、Spring boot 2和Reactor构建,使用Netty作为运行时环境,比较完美的支持异步非阻塞编程。Netty使用非阻塞的IO,线程处理模型建立在主从Reactors多线程模型上。其中Boss Group轮询到新连接后与Client建立连接,生成NioSocketChannel,将channel绑定到Worker;Worker Group轮询并处理Read、Write事件。

1.2 用途

1) 反向代理。

2) 鉴权。

3) 流量控制。

4) 熔断。

5) 日志监控。

2. Gateway重要概念

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

2) Predicate(断言):可以匹配HTTP请求中的所有内容(例如请求头和请求参数),如果请求与断言相匹配则进行路由。

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

3. Gateway案例

以下案例代码的Github地址

三个modules分别是:cloud-eureka-server7001,cloud-gateway-gateway9527,cloud-provider-hystrix-payment8001,cloud-provider-hystrix-payment8002。

3.1 路由映射

1) 当前cloud-provider-hystrix-payment8001的接口(/payment/hystrix/ok/{id}):

@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id) {
	String result = paymentService.paymentInfo_OK(id);
	 log.info("*****result: " + result);
	return result;
}

测试结果: 

2) cloud-gateway-gateway9527的路由映射核心配置(注意缩进):

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称进行路由
      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
          uri: http://localhost:8001
          predicates:
            - Path=/payment/hystrix/** # 断言,路径相匹配的进行路由
        - id: payment_route2
          uri: http://localhost:8001
          predicates:
            - Path=/payment/lb/** #断言,路径相匹配的进行路由

 测试结果:

3.2 路由两种配置方式

1) 第一种方式就是3.1提及到的yml配置方式(推荐)。

2) 第二种方式就是通过配置Bean(RouteLocator),当访问地址 http://localhost:9527/guonei时会自动转发到地址(http://news.baidu.com/guonei) :

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
	RouteLocatorBuilder.Builder routes = builder.routes();
	routes.route("path_route_eiletxie",
			r -> r.path("/guonei")
					.uri("http://news.baidu.com/guonei")).build();
	return routes.build();
}

测试结果:

3.3 动态路由

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

2) cloud-gateway-gateway9527的application.yml加上:

- id: payment_route3
  uri: lb://cloud-provider-hystrix-payment
  predicates:
	- Path=/payment/circuit/** # 断言,路径相匹配的进行路由

: 

  • 不能和前面两个Route的Path有重合,否则会先匹配前面的Route。
  • lb://serviceName是springcloud gateway在微服务中自动为我们创建的负载均衡uri(uri的协议为lb,表示启用Gateway的负载均衡功能)。

3) 启动cloud-eureka-server7001,然后启动cloud-provider-hystrix-payment8001, cloud-provider-hystrix-payment8002。

测试结果(8001/8002两个端口的切换):

 

3.4 Predicate的使用

Route Predicate Factories,简单来说,Predicate就是为了实现一组匹配原则,让请求过来找到对应的Route进行处理。

3.4.1 After Route Predicate

设置当前时间再加1小时进行测试,当测试请求的时间小于设定时间时就会报错,必须在 AFTER 某个时间以后请求才有效。

- id: payment_route01
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/** 
  - After=2020-03-12T16:44:15.064+08:00[Asia/Shanghai]

3.4.2 Before Route Predicate

 设置当前时间再加1小时进行测试,当测试请求的时间小于设定时间时就会报错,必须在 AFTER 某个时间以后请求才有效。

- id: payment_route02
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Before=2020-03-12T16:44:15.064+08:00[Asia/Shanghai]

3.4.3 Between Route Predicate

- id: payment_route03
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Between=2020-03-12T16:44:15.064+08:00[Asia/Shanghai], 2021-03-12T16:44:15.064+08:00[Asia/Shanghai]

3.4.4 Cookie Route Predicate

curl http://localhost:9527/payment/hystrix/ok/31 --cookie "username=bastriver"
- id: payment_route04
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  #- After=2020-03-12T15:44:15.064+08:00[Asia/Shanghai]
  - Cookie=username,bastriver

3.4.5 Header Route Predicate

curl http://localhost:9527/payment/hystrix/ok/31 -H "X-Request-Id:100"
- id: payment_route05
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Header=X-Request-Id,\d+ #请求头要有 X-Request-Id属性并且值为整数的正则表达式

3.4.6 Host Route Predicate

curl http://localhost:9527/payment/hystrix/ok/31 -H "Host:bastriver.atguigu.com"
- id: payment_route06
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Host=**.atguigu.com

3.4.7 Method Route Predicate

- id: payment_route08
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Method=GET

3.4.8 Path Route Predicate

- id: payment_route08
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**

3.4.9 Query  Route Predicate

curl http://localhost:9527/payment/hystrix/ok/31?username=31
- id: payment_route09
  uri: lb://cloud-payment-service
  predicates:
  - Path=/payment/hystrix/**
  - Query=username, \d+ # 要有参数名username并且值还要是正整数才能路由

3.5 Filter的使用

GatewayFilter Factories,总体上分为两类:GatewayFilter和GlobalFilter。

3.5.1 GatewayFilter

以AddRequestHeader为例,GatewayFilter Factory会在匹配的请求头加上一对请求头,名为X-Request-red 值为blue。

 - id: payment_route10 
   uri: http://localhost:8001
   predicates:
	 - Path=/payment/hystrix/**
   filters:
	 - AddRequestHeader=X-Request-red, blue

3.5.2 自定义过滤器

为了实现全局日志记录和全局日志记录,通常需要自定义全局GlobalFilter。

1) 添加MyLogGatewayFilter(增加了Query参数的匹配,如果不包含uname就不能通过请求)。

@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono< Void > filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("****** come in MyLogGateWayFilter: " + new Date());

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname == null) {
            log.info("*****用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 加载过滤器的顺序,数字越小,优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

2) 测试结果(localhost:9527/payment/hystrix/ok/1?uname=z3):

附:

1) Spring Cloud Gateway官网

2) demo中集成了Hystrix,如果需要了解相关的内容可以参考:关于Springcloud Hystrix的总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值