Gateway

  • 一、Gateway简介
  • 二、配置`api-gateway`
  • 路由相关配置解释
  • 三、断言
  • 八种不同类型的断言
  • 四、过滤器
  • 内置局部过滤器
  • 内置局部过滤器的使用
  • 内置全局过滤器


一、Gateway简介

在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?

如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。

网关 微服务调用微服务 springsecurity 微服务网关gateway简书_微服务


这样的架构,会存在着诸多的问题:

  • 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
  • 认证复杂,每个服务都需要独立认证。
  • 存在跨域请求,在一定场景下处理相对复杂。

上面的这些问题可以借助API网关来解决。所谓的API网关,就是指系统的统一入口。它封装了应用程序的内部结构,为客户端提供统一服务。

一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等等。

添加上API网关之后,系统的架构图变成了如下所示:

网关 微服务调用微服务 springsecurity 微服务网关gateway简书_客户端_02


Spring Cloud Gateway旨在为微服务架构提供一种简单有效的统一的API路由管理方式。 它不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控和限流。

二、配置api-gateway

通过浏览器访问api网关,然后通过网关将请求转发到用户微服务

网关 微服务调用微服务 springsecurity 微服务网关gateway简书_客户端_03


① 创建一个api-gateway的模块,导入相关依赖

<dependencies>
        <!--引入gateway网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        
        <!--nacos服务发现依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

nacos主要用户拉取服务列表

② 创建引导类

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

@添加配置文件

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: user-service-route # 当前路由的标识, 要求唯一
          uri: lb://user-service # 请求要转发到的地址
          predicates: # 断言(就是路由转发要满足的条件)
            - Path=/user/** # 当请求路径满足Path指定的规则时,才进行路由转发

路由相关配置解释

路由(Route) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:
id,路由标识符,区别于其他 Route。
uri,路由指向的目的地 uri,即客户端请求最终被转发到的微服务。
predicate,断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。
filter,过滤器用于修改请求和响应信息。

④ 启动项目,并通过网关去访问用户微服务

网关 微服务调用微服务 springsecurity 微服务网关gateway简书_正则表达式_04

三、断言

断言:用于进行条件判断(也就是在什么条件下才能进行路由转发),只有断言都返回真,才会真正的执行路由。

八种不同类型的断言

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配。具体如下

基于Datetime类型的断言:

# AfterRoutePredicateFactory:   接收一个日期参数,判断请求日期是否晚于指定日期
# BeforeRoutePredicateFactory:  接收一个日期参数,判断请求日期是否早于指定日期
# BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内
- After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]

基于远程地址的断言:

# RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24

基于Cookie的断言:

# CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- Cookie=chocolate, ch.

基于Header的断言:

# HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。
- Header=X-Request-Id, \d+

基于Host的断言:

# HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。
- Host=**.testhost.org

基于Method请求方法的断言:

# MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。
- Method=GET

基于Path请求路径的断言:

# PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
- Path=/foo/{segment}

基于Query请求参数的断言:

# QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
- Query=baz, ba.

四、过滤器

Gateway的过滤器会对请求或响应进行拦截,完成一些通用操作。
Gateway中, Filter生效位置有两个:

  1. PRE: 这种过滤器在请求被路由之前调用,可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等
    2. POST:这种过滤器在路由到微服务以后执行,可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等

GatewayFilter作用范围可分为两种:

  1. GatewayFilter:应用到单个路由或者一个分组的路由上
  2. GlobalFilter:应用到所有的路由上

内置局部过滤器

局部过滤器是针对单个路由的过滤器。在SpringCloud Gateway中内置了很多不同类型的网关路由过滤器。具体如下:

过滤器工厂

作用

参数

AddRequestHeader

为原始请求添加Header

Header的名称及值

AddRequestParameter

为原始请求添加请求参数

参数名称及值

AddResponseHeader

为原始响应添加Header

Header的名称及值

DedupeResponseHeader

剔除响应头中重复的值

需要去重的Header名称及去重策略

Hystrix

为路由引入Hystrix的断路器保护

HystrixCommand的名称

FallbackHeaders

为fallbackUri的请求头中添加具体的异常信息

Header的名称

PrefixPath

为原始请求路径添加前缀

前缀路径

PreserveHostHeader

为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host


RequestRateLimiter

用于对请求限流,限流算法为令牌桶

keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus

RedirectTo

将原始请求重定向到指定的URL

http状态码及重定向的url

RemoveHopByHopHeadersFilter

为原始请求删除IETF组织规定的一系列Header

默认就会启用,可以通过配置指定仅删除哪些Header

RemoveRequestHeader

为原始请求删除某个Header

Header名称

RemoveResponseHeader

为原始响应删除某个Header

Header名称

RewritePath

重写原始的请求路径

原始路径正则表达式以及重写后路径的正则表达式

RewriteResponseHeader

重写原始响应中的某个Header

Header名称,值的正则表达式,重写后的值

SaveSession

在转发请求之前,强制执行WebSession::save操作


secureHeaders

为原始响应添加一系列起安全作用的响应头

无,支持修改这些安全响应头的值

SetPath

修改原始的请求路径

修改后的路径

SetResponseHeader

修改原始响应中某个Header的值

Header名称,修改后的值

SetStatus

修改原始响应的状态码

HTTP 状态码,可以是数字,也可以是字符串

StripPrefix

用于截断原始请求的路径

使用数字表示要截断的路径的数量

Retry

针对不同的响应进行重试

retries、statuses、methods、series

RequestSize

设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large

请求包大小,单位为字节,默认值为5M

ModifyRequestBody

在转发请求之前修改原始请求体内容

修改后的请求体内容

ModifyResponseBody

修改原始响应体的内容

修改后的响应体内容

内置局部过滤器的使用

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: user-service-route # 当前路由的标识, 要求唯一
          uri: lb://user-service # 请求要转发到的地址
          predicates: # 断言(就是路由转发要满足的条件)
            - Path=/user/** # 当请求路径满足Path指定的规则时,才进行路由转发
          filters:
            - SetStatus=2000 # 修改返回状态

内置全局过滤器

全局过滤器作用于所有路由无需配置。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。

SpringCloud Gateway内部也是通过一系列的内置全局过滤器对整个路由转发进行处理如下:

网关 微服务调用微服务 springsecurity 微服务网关gateway简书_java_05