Gateway组件的使用

107 阅读10分钟

Gateway组件

demo地址

gitee.com/w--kk/gatew…

Gateway网关组件

  1. 什么是网关  Gateway (ServiceGateway)  服务网关
    网关统一服务入口,可方便实现对平台众多服务接口进行管控

image.png

  1. 网关作用
    a. 网关统一所有微服务入口
    b. 网关可以实现请求路由转发(router dispatcher),以及请求过程负载均衡
    c. 访问服务的身份认证、防报文重放与防数据算改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,其至基于API调用的计量或者计费等等

  2. springcloud提供网关组件
    a. netflix zuull.x(效率)  zuul2.x(近两年)
    b. spring cloud gateway 组件 (Flux 异步非阻塞IO模型)  BIO Blocking IO

  3. springcloud gateway
    gateway: 动态路由  服务统一管理 请求过滤
    gateway = 路由转发(router) + 请求过滤(filter)

  4. Gateway网关使用
    a. 开发独立springboot应用
    b. 引入网关依赖
    c. 配置编写

什么是服务网关

  1. 说明
  • 网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。
  • 网关 = 路由转发 + 过滤器
    路由转发:接收一切外界请求,转发到后端的微服务上去;
    在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成
  1. 为什么需要网关
  • 1.网关可以实现服务的统一管理
  • 2.网关可以解决微服务中通用代码的冗余问题 (如权限控制,流量监控,限流等)
  1. 网关组件在微服务中架构

image.png

服务网关组件

zuul 1.x 2.x(netflix 组件)

Zuul is the front door for all requests from devices and web sites to the backend of the Netflixstreaming application. As an edge service application, Zuul is built to enable dynamic routing,monitoring, resiliency and security.

  1. 原文翻译
  • github.com/Netflix/zuu…
  • zul是从设备和网站到Netflix流媒体应用程序后端的所有请求的前门。作为一个边缘服务应用程序,zul被构建为支持动态路由、监视、弹性和安全性。
  1. zuul版本说明
  • 目前zuul组件已经从1.0更新到2.0,但是作为springcloud官方不再推荐使用zuul2.0,但是依然支持zuul2.
  1. springcloud 官方集成zuul文档

gateway (spring)

This project provides a library for building an API Gateway on top of Spring MVC. Spring CloudGateway aims to provide a simple, yet effective way to route to APls and provide cross cuttingconcerns to them such as: security, monitoring/metrics, and resiliency.

  1. 原文翻译
  • spring.io/projects/sp…
  • 这个项目提供了一个在springmvc之上构建API网关的库。springcloudgateway旨在提供一种简单而有效的方法来路由到api,并为api提供横切关注点,比如:安全性、监控/度量和弹性。
  1. 特性
  • 基于springboot2.x 和 spring webFlux 和 Reactor 构建 响应式异步非阻塞IO模型
  • 动态路由
  • 请求过滤

gateway组件的使用

1. 开发网关动态路由

  1. 翻译
  • 网关配置有两种方式一种是快捷方式 (Java代码编写网关),一种是完全展开方式(配置文件方式)[推荐]

网关必须注册到服务注册中心,因为网关也需要实现负载均衡,一个集群有多个节点,不知道需要往哪个节点转发,需要去服务注册中心拉取服务。

  1. 创建项目引入网关依赖
<!--引入gateway网关依赖-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 快捷方式配置路由
    网关配置文件强烈建议用yml
spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: category_router #路由对象唯一标识 ,加-代表路由列表的第一个元素
          uri: http://localhost:9999/ # 指定路由服务的地址
          predicates:
            - Path=/user/**					  # 指定路由规则

        - id: product_route
          uri: http://localhost:9998/
          predicates:
            - Path=/product/**
server:
  port: 8989
  1. 启动gateway网关项目
    报错: image.png 解决: image.png image.png
  • 直接启动报错:

  • 在启动日志中发现,gateway为了效率使用webflux进行异步非阻塞模型的实现,因此和原来的web包冲突,去掉原来的web即可。
    注意:去掉项目springboot-starter-web存在冲突

  • 再次启动成功启动

  1. 测试网关路由转发

网关配置细节

  1. 网关 gateway组件(spring) netflix zuul1.X ===> zuul2.x
    gateway 使用webflux 底层使用异步非阻塞IO模型

  2. 网关在微服务架构作用
    a. 统一所有微服务总入口
    b. 实现请求负载均衡
    c. 过滤处理(鉴权 日志流量统计 数据防篡改)
    总结: 网关 gateway = 路由 router + filter(过滤)

  3. 网关第一配置 a. 配置文件方式配置网关 推荐 完全展开方式

server:
  port: 8011
spring:
  application:
    name: GATEWAY
  cloud:
    consul:
      host: localhost
      post: 8500
    gateway:
      routes:
        - id: category_router #路由对象唯一标识
          uri: http://localhost:8086 #用来类别服务地址  http://localhost:8086/category
          predicates:  #断言 用来配置路由规则
            - Path=/category/**

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

b. java代码方式配置网关 注意:java配置优先于配置文件

java方式配置路由

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("order_route", r -> r.path("/order/**")
                        .uri("http://localhost:9997"))
                .build();
    }
}

2. 查看网关路由规则列表

通过网关提供web路径查看路由详细规则
a. http://localhost:8002/actuator/gateway/routes
b. 查看网关路由规则详细路径必须在网关配置文件中暴露当前路径

management:
  endpoints:
    web:
      exposure:
        include: "*"

image.png

网关路由解析规则

image.png

Path规则可以写一个,写多个,支持通配符配置,可以用逗号隔开 image.png

通配符加个总类别

image.png

说明
gateway提供路由访问规则列表的web界面,但是默认是关闭的, 如果想要查看服务路由规则可以在配置文件中开启

management:
  endpoints:
    web:
      exposure:
        include: "*"   #开启所有web端点暴露
- 访问路由管理列表地址
- http://localhost:8002/actuator/gateway/routes

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

问题:现有网关配置方式在uri的属性中路径直接写死为服务的某一个节点, 这样没有办法实现请求的负载均衡

如何配置网关转发实现负载均衡  Ribbon组件  负均衡客户端组件

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

  2. 动态路由以及负载均衡转发配置

    spring:
       application:
         name: gateway
       cloud:
         consul:
           host: localhost
           port: 8500
         gateway:
           routes:
             - id: user_route
                   #uri: http://localhost:9999/
               uri: lb://users	# lb代表转发后台服务使用负载均衡,users代表服务注册中心上的服务名
               predicates:
                 - Path=/user/**
    
             - id: product_route
                   #uri: http://localhost:9998/
                   uri: lb://products          # lb(loadbalance)代表负载均衡转发路由
                   predicates:
                     - Path=/product/**
          discovery:
             locator:
               enabled: true  #开启根据服务名动态获取路由		
    

网关细节

  1. 断言 predicate  过滤filter
  2. 网关 gateway
    网关 gateway = 断言predicate (前置filter) + 过滤(后置filter)
    断言:当请求到达网关时, 网关前置处理 ,满足断言放心请求,不满足断言立即返回
    过滤: 当请求满足断言的所有条件之后, 会向后端服务转发, 在向后端服务转发之前会经过一些过滤
  3. 网关断言使用 Route Predicate Factories
    image.png image.png
  4. 网关过滤使用 GatewayFilter Factories

测试

测试指定cookie断言,可以用curl工具进行演示。
Cookie=name,wkk #携带指定cookie请求才能访问 注意:必须配合curl工具使用 image.png curl http://localhost:8003/product/list --cookie "name=wkk" image.png

Header=X-Request-Id,\d+ #基于请求头中的指定属性的正则匹配路由(这里全是整数) image.png curl http://localhost:8003/product/list -H "X-Request-Id:11"

用Postman测试 image.png

4. 常用路由predicate (断言,验证)

image.png

  1. Gateway支持多种方式的predicate
  1. 使用predicate
spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: user_route
          #uri: http://localhost:9999/
          uri: lb://users
          predicates:
            - Path=/user/**
            - After=2020-07-21T11:39:33.993+08:00[Asia/Shanghai]
            - Cookie=username,[A-Za-z0-9]+
            -  Header=X-Request-Id, \d+

5. 常用的Filter以及自定义filter

  1. 原文翻译
  • 官网: cloud.spring.io/spring-clou…

  • 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由筛选器的作用域是特定路由。springcloud gateway包括许多内置的GatewayFilter工厂。

  1. 作用
  • 当我们有很多个服务时,比如下图中的user-service、order-service、product-service等服务,客户端请求各个服务的Api时,每个服务都需要做相同的事情,比如鉴权、限流、日志输出等。

image.png

image.png

  1. 使用内置过滤器
  • AddRequestHeader=X-Request-red, blue 增加请求头的filter
  • AddRequestParameter=red, blue 增加请求参数的filterr
  • AddResponseHeader=X-Response-Red, AAA 增加响应头filter
  • PrefixPath=/emp 增加前缀的filter
  • StripPrefix=2 去掉前缀的filter

内置filter

gateway filter 过滤

  1. 内置filter
    a. AddRequestHeader Filter   - AddRequestHeader=X-Request-red,blue  用来给路由对象的所有请加入指定请求头信息
    b. AddRequestparameter Filter   -AddRequestparameter=color,blue 用来给路由对象的所有转发请求加入指定请求参数
    c. AddResponseHeader Filter   - AddResponseHeader=X-Response-Red,Blue 用来路由对象的所有转发请求的响应加入指定头信息
    d. PrefixPath Filter   - PrefixPath=/mypath 用来给路由对象的所有转发请求的url加入指定前缀信息
    如:浏览器访问网关地址 /list 前缀路径/mypath  转发到后端服务地址:uri + 前缀路径 + 地址栏路径 ===> uri+/mypath/list
    e. StripPrefix Filter   - StripPrefix=n(2)    用来给路由对象的所有转发请求的url去掉指定n个前缀
    如: 浏览器访问网关地址: /product/list   strippefix=1===> /list   后端接口:list
  2. 自定义全局filter所有请求都要经过全局filter之后再转发到后端服务

测试

  • AddRequestHeader=User-Name, wkk 用来给路由对象的所有请求加入指定请求头信息 image.png image.png image.png

  • AddRequestParameter=color, blue 用来给路由对象的所有转发请求加入指定请求参数 image.png image.png image.png

  • AddResponseHeader=X-Response-Red, Blue 用来路由对象的所有转发请求的响应加入指定头信息 image.png image.png

  • PrefixPath=/mypath 用来给路由对象的所有转发请求的url加入指定前缀信息
    如:浏览器访问网关地址 /list 前缀路径/mypath  转发到后端服务地址:uri + 前缀路径 + 地址栏路径 ===> uri+/mypath/list

image.png

  • StripPrefix=n(2)   用来给路由对象的所有转发请求的url去掉指定n个前缀
    如: 浏览器访问网关地址: /product/list   strippefix=1===> /list   后端接口:list image.png

全局filter(自定义filter)

自定义全局filter所有请求都要经过全局filter之后再转发到后端服务
使用自定义filter

@Configuration
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("进入自定义的filter");
        if(exchange.getRequest().getQueryParams().get("username")!=null){
            log.info("用户身份信息合法,放行请求继续执行!!!");
            return chain.filter(exchange);
        }
        log.info("非法用户,拒绝访问!!!");
       return exchange.getResponse().setComplete();
    }
    
    //order 排序  int数字:用来指定filter执行顺序  默认顺序按照自然数字进行排序  -1 在所有filter执行之前执行
    @Override
    public int getOrder() {
        return -1;
    }
}

image.png

查看网关路由规则列表

通过网关提供web路径查看路由详细规则
a. http://localhost:8002/actuator/gateway/routes
b. 查看网关路由规则详细路径必须在网关配置文件中暴露当前路径

management:
  endpoints:
    web:
      exposure:
        include: "*"

image.png

引用 编程不良人