您当前的位置:首页 > 计算机 > 编程开发 > Spring Cloud

Gateway服务网关

时间:12-10来源:作者:点击数:

1. 简介

Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式,统一访问接口。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。它是基于Nttey的响应式开发模式。

2 核心概念

1. 路由(route) 路由是网关最基础的部分,路由信息由一个ID、一个目的URL、一组断言工厂和一 
   组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。 
2. 断言(predicates) Java8中的断言函数,Spring Cloud Gateway中的断言函数输入类型是
   Spring5.0框架中的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去
   定义匹配来自Http Request中的任何信息,比如请求头和参数等。 
3. 过滤器(filter) 一个标准的Spring webFilter,Spring Cloud Gateway中的Filter分为
   两种类型,分别是Gateway Filter和Global Filter。过滤器Filter可以对请求和响应进行处理。 

如:

spring:
  cloud:
    gateway:
      routes:
        - id: product_router      #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://PRODUCT       #匹配后提供服务的路由地址 实现请求负载均衡处理
          predicates:             # 断言,路径相匹配的进行路由
            - Path=/product/**
			- Method=GET
          filters:                #过滤规则
            - AddRequestHeader=User-Name, chenyn
            - AddRequestParameter=color, blue

3 案例:

在这里插入图片描述

各微服务端口号:

在这里插入图片描述

分类微服务(服务消费者)存在方法:

    @Autowired
    private ProductClient productClient;  //远程调用商品微服务product接口

    @GetMapping("/category")
    public String category(){
        log.info("分类微服务");
        String result = productClient.product();
        return result;
    }

商品微服务(服务提供者)存在方法:

 @GetMapping("/list")
    public String list(HttpServletRequest request,String color){
        log.info("商品列表服务");
        return "list ok当前提供服务端口:"+port;
    }

    @GetMapping("/product")
    public String product() throws InterruptedException {
        log.info("进入商品服务.....");
        return  "product ok,当前提供服务端口:"+port;
    }

分别测试两个独立的微服务是否可以访问:

测试服务消费者接口

在这里插入图片描述

测试服务消提供者接口

在这里插入图片描述

现在添加网关微服务,进行配置yml

在这里插入图片描述
server:
  port: 7979
spring:
  application:
    name: GATEWAY
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: product_router           #路由对象唯一标识
          uri: http://localhost:8788   #用来类别服务地址  http://localhost:8788/list
          predicates:                  #断言 用来配置路由规则
            - Path=/product

        - id: category_router         #路由对象唯一标识
          uri: http://localhost:8787  #用来类别服务地址  http://localhost:8787/list
          predicates:                 #断言 用来配置路由规则
            - Path=/category

测试访问通过网关请求:

在这里插入图片描述
在这里插入图片描述

网关路由解析规则:

当我们访问http://localhost:7979/product时 网关微服务就会在routes列表当中查找有没有 和*/product* 匹配的Path路由规则

在这里插入图片描述

以上网关的配置一定是存在问题的,比如:

以上我们只是访问一个路径(/product)进行转发(转发到http://localhost:8788上)

而实际的微服务当中不可能存在一个访问路径,比如案例当中的商品微服务还存在一个list方法,这个时候我们又怎么让网关帮助我们转发呢?

配置如下:

在这里插入图片描述

测试访问:

在这里插入图片描述

以上还是存在一个问题;如果商品微服务当中存在多个服务路径,那我们就需要在网关配置文件当中配置多个路由规则,就像上面增加的list路径。

而gateway网关支持我们使用通配的方式去匹配路由规则

在这里插入图片描述

测试:

在这里插入图片描述

以上可以发现路由规则这块 我们可以配置一个,多个以及 通配的方式进行路由配置

4.配置路由服务负载均衡

现有路由配置方式,都是基于服务地址写死的路由转发,能不能根据服务名称进行路由转发同时实现负载均衡的呢?

在这里插入图片描述

uri : uri以 lb: //开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称

5 网关断言和过滤

其实在springcloud设计网关的时候,他其实将网关划分了

断言和过滤器

在这里插入图片描述

网关gateway = 断言(predicate) + 过滤(filter)

断言(predicate):当请求到达网关,网关在转发请求之前做的一些处理 满足断言放行请求,不满足断言立即返回。

过滤(filter):当请求满足断言的所有条件之后,会向后端服务转发,在向后端服务转发之前会经过一系列过滤处理。

在这里插入图片描述

以上我们配置的网关配置是没有加任何的过滤的,我们只配置了断言,只要断言一过,就拿着路径直接请求后端服务。其实还有一个过滤配置。

无论是断言还是过滤,springcloud都给我们配置了大量的断言工厂和过滤工厂

网关断言使用 Route Predicate Factories

在这里插入图片描述
1 - Path=/product/**    :路径断言,路径匹配成功时候转发到后台服务   作用如以上案例
2 - After=2017-01-20T17:42:47.789-07:00[America/Denver](区域时间):代表该路由规则必须在指定时间之后才能生效

案例如下:

在这里插入图片描述

在2021-06-13 21:29:22之前访问:

在这里插入图片描述

在2021-06-13 21:29:22之后访问:

在这里插入图片描述
3 - Before=2021-06-13T21:40:22.124+08:00[Asia/Shanghai]  (区域时间):代表该路由规则必须在指定时间之前才能生效
4  - Between=2021-04-20T10:23:22.124+08:00[Asia/Shanghai],2021-04-20T10:25:22.124+08:00[Asia/Shanghai](区域时间):代表该路由规则必须在指定时间之间才能生效
5 - Cookie=name,chenyn   携带指定cookie才能访问 key为name  value为chenyn
6 - Header=X-Request-Id,\d+  请求必须含有指定的请求头X-Request-Id
7 - Method=GET  限定指定的请求方式为get请求方式

网关过滤使用 GatewayFilter Factories

1 - AddRequestHeader=User-Name, chenyn    #用来给路由对象的所有请求加入指定的请求头信息
在这里插入图片描述

案例:

访问消费者方法:

 @GetMapping("/list")
    public String list(HttpServletRequest request){
        String header = request.getHeader("User-Name");
        System.out.println("获取请求头信息: "+header);
        log.info("商品列表服务");
        return "list ok当前提供服务端口:"+port;
    }

测试:

在这里插入图片描述
在这里插入图片描述
2 - AddRequestParameter=color, blue      #用来给路由对象的所有转发请求加入指定的请求参数

案例:

访问消费者方法:

  @GetMapping("/list")
    public String list(HttpServletRequest request,String color){
        String header = request.getHeader("User-Name");
        System.out.println("获取对应请求参数 color: "+color);
        System.out.println("获取请求头信息: "+header);
        log.info("商品列表服务");
        return "list ok当前提供服务端口:"+port;
    }

测试:

在这里插入图片描述
在这里插入图片描述
 3 - PrefixPath=/product      #用来给路由对象的所有转发请求的url加入指定的前缀信息

案例:

在这里插入图片描述

测试:

在这里插入图片描述

等等…

以上是springcloud提供的内置过滤器,我们也可以自定义全局过滤器,所有请求都要经过全局的filter之后再转发到后端服务

在这里插入图片描述
/**
 * 自定义网关全局filter
 */
@Configuration
public class CustomerGlobalFilter  implements GlobalFilter, Ordered {

    //类似javaweb doFilter
    //exchange : 交换   request response   封装了 request response
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //httprequest对象
        ServerHttpRequest request = exchange.getRequest();
        //httpresponse对象
        ServerHttpResponse response = exchange.getResponse();
        System.out.println("经过全局Filter处理.......");
        Mono<Void> filter = chain.filter(exchange);//放心filter继续向后执行
        System.out.println("响应回来Filter处理......");
        return filter;
    }

    //order 排序  int数字:用来指定filter执行顺序  默认顺序按照自然数字进行排序  -1 在所有filter执行之前执行
    @Override
    public int getOrder() {
        return -1;
    }
}

测试:

在这里插入图片描述
在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门