栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringCloud Gateway

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringCloud Gateway

1 SpringCloud Gateway简介

Gateway 是基于Spirng5.0,Spring Boot2.0等技术的网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

Gateway是基于WebFlux框架实现的,而==WebFlux底层使用了高性能的通信框架Netty==。

Gateway不仅提供统一路由方式,并且基于Filter链的方式提供了网关基本的功能:安全、监控、限流等。

和Zuul主要的区别在于底层通信框架

1.1 三大术语

Filter(过滤器)

可以拦截和修改请求,并且对上游的响应进行二次处理,GatewayFilter,可以在请求之前或者之后执行业务逻辑

Route(路由)

一个路由由id(自定义路由id,必须唯一)、目标url(目标服务地址)、一组断言和一组过滤器组成

Predicate(断言)

可以使用断言来匹配HTTP请求,支持多种方式:Path、Query、Method、Header等,必须遵循key=value的形式

1.2 Gateway处理流程

客户端从浏览器向Gateway发起请求,由DispatcherServlet负责调度,遍历Handler Mapping找到匹配的,将请求发送到WebHandler,Handler通过过滤器链将请求发送到实际处理业务逻辑的服务。

虚线分开是因为过滤器可能在发送代理请求之前pre,或者之后post执行业务逻辑,

Filter在pre过滤器中可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在post类型过滤器中可以响应内容、响应头修改等。

2 路由配置

id、uri、predicates

2.1 配置文件
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Path=/nacos-provider/**
          filters:
            - StripPrefix=1
        - id: consumer
          uri: lb://nacos-consumer
          predicates:
            - Path=/nacos-consumer/**
          filters:
            - StripPrefix=1

id:唯一的路由id

uri:转到的目标服务地址

predicates:路由条件,接收一个参数,返回一个boolean结果,有多种默认的方法供使用

filters:过滤器

2.2 基于代码配置
@Configuration
public class CustomRouteRule {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        return builder
                .routes()
                .route("custom_id",r -> r.path("/nacos-provider/**")
                        .filters(f->f.stripPrefix(1))
                .uri("lb://nacos-provider"))
                .build();
    }
}
3 路由匹配规则

Gateway的predicates功能很强大,通过WebFlux的handlermapping作为底层匹配路由转发,多个predicate可以组合使用

3.1 断言

predicate接受一个参数,返回一个boolean结果,包含多种默认方法将predicate组合成其他复杂逻辑

转发规则:

规则实例说明
Path-Path=/test/,/rule/当请求路径为test、rule开头时,转发请求
Before-Before=2021-01-20T17:42:47.789-07:00[America/Denver]在某个时间之前的请求会被转发
After-After=2021-01-20T17:42:47.789-07:00[America/Denver]在某个时间之后的请求会被转发
Between-Between=-Before=2021-01-20T17:42:47.789-07:00[America/Denver],-Before=2021-04-20T17:42:47.789-07:00[America/Denver]在时间段内请求会被转发
cookie-cookie=cookieName,pattern第一个参数cookie的名字,第二个参数是正则表达式,满足条件转发
Header-Header=X-Request-Id,d+请求头中携带参数X-Request-Id或者满足d+的请求会被转发
Host-Host=www.aaa.com当主机名为www.aaa.com的时候会被转发
Method- Method=GET只有GET请求会被转发,还可以是POST,PUT等方式
Query- Query=name请求参数中含有name字段才会被转发

1. 通过请求参数匹配

spring:
  cloud:
    gateway:
      routes: 
        - id: nacos-provider
          uri: lb://nacos-provider
          predicates:
            - Query=name
      # 请求中含有name字段的会被抓饭

#===============
spring:
  cloud:
    gateway:
      routes: 
        - id: nacos-provider
          uri: lb://nacos-provider
          predicates:
            - Query=name,z.
 # 请求参数中有name字段,并且是以z开头的请求会被转发           
 

2. 通过Header匹配

Header Predicate接受两个参数,一个header中舒敏名称,一个正则表达式

spring:
  cloud:
    gateway:
      routes: 
        - id: nacos-provider
          uri: lb://nacos-provider
          predicates:
            - Header=X-Request-age,d+

# curl http://localhost:10001/nacos-provider -H "X-Request-age:22"

3. 通过cookie匹配

接受两个参数,一个是cookie name,一个是正则表达式

spring:
  cloud:
    gateway:
      routes: 
        - id: provider
          uri: lb://provider
          predicates:
            - cookie=sessionId,aaa
            
# curl http://localhost:10001/provider --cookie "sessionId=aaa"

4. 通过Host匹配

Host Predicate接受一组参数,一组匹配的域名列表,这个模板是一个ant分隔的模板,用 . 隔开,通过参数中的主机地址作为匹配规则

spring:
  cloud:
    gateway:
      routes: 
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Host=**.baidu.com
            
# curl http://localhost:10001/nacos-provider -H "Host:www.baidu.com"
# curl http://localhost:10001/nacos-provider -H "Host:test.baidu.com"

5. 通过请求方式匹配

POST、GET 、PUT、 DELETE

spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Method=GET
            
# curl http://localhost:10001/provider

6. 通过请求路径匹配

spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Path=/provider/**
            
# curl http://localhost:10001/provider/feign

7. 通过IP地址匹配

接受IPV4 或 IPV6 字符串列表,最小为1

spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - RemoteAddr=172.168.1.1/24

8. 组合使用

当多个predicate在同一个路由时,请求需要同时满足才能被匹配,当一个请求满足多个路由时,第一个匹配成功的转发

spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Host=**.baidu.com
            - Path=/provider/**
            - Method=GET
            - Header=X-Request-age,d+
            - Query=name,z.
            - Query=name
            - cookie=cookieName,coki
3.2 过滤器规则

当配置多个Filter时,优先定义的会被调用,剩余的filter不会生效

1. 过滤器规则

过滤规则实例说明
PrefixPath- PrefixPath=/provider请求路径千加上provider
RewritePath- RewritePath=/provider/,/nacos-provider/test访问/provider请求会被转发到/nacos-provider/test上
SetPath- Setpath=/provider/{path}通过模板设置路径,转发的规则会在路径前增加provider,{path}标识原请求路径
RedirectTo重定向
RemoveRequestHeader去掉某个请求头

2. PrefixPath

# 对所有请求路径增加  前缀  hello
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - PrefixPath=/hello

3. RedirectTo

# 重定向  包含重定向地址和返回码
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - RedirectTo=404,http://abc.com

4. RemoveRequestHeader

# 去掉某个请求头信息 X-Request-Id
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - RemoveRequestHeader=X-Request-Id

5. RemoveResponseHeader

#  去掉某个回执响应头信息  X-Request-param
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - RemoveResponseHeader=X-Request-param

6. RemoveRequestParameter

# 去掉某个请求参数   请求参数name
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - RemoveRequestParameter=name

7. RewritePath

# 改写路径   /where/...   改写为  /hello/...
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - RewritePath=/where(?/?.*),/hello(?/?.*)

8. SetPath

# 设置请求路径   与Rewritepath类似
# 将/xxx/hello   请求 设置为   /hello 请求
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          predicates:
            - Path=/provider/{segment}
          filters:
            - SetPath=/{segment}

9. SetRequestHeader

# 设置请求头
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - SetRequestHeader=X-Request-Hello,Name

10. SetStatus

# 设置状态码
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - SetStatus=404

11. StripPrefix

# 跳过指定路径,过滤掉路径前几个
# /a/b/hello   -->  /hello
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - StripPrefix=2

12. RequestSize

# 请求大小  超过限制会返回413
spring:
  cloud:
    gateway:
      routes:
        - id: provider
          uri: lb://nacos-provider
          filters:
            - name: RequestSize
              args:
                maxSize: 10000000

13. Default-filters

# 对所有请求添加过滤器
spring:
  cloud:
    gateway:
      default-filters: 
        - PrefixPath=/hello
3.3 过滤器分类

生命周期分类

生命周期作用
pre路由调用之前利用过滤器实现身份验证、在集群中选择请求转发的微服务等
post在微服务执行以后,可以用来为响应添加header、收集统计信息和指标,将响应发送给客户端

过滤器类型分类

过滤器类型影响范围
GatewayFilter应用到单个路由
GlobalFilter应用到所有路由

全局过滤器一般用的较多,可以用来定义一些黑名单校验、限流功能等:

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

    private static List blackList = new ArrayList<>();

    static {
        blackList.add("0:0:0:0:0:0:0:1");  // 模拟本机地址
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取客户端ip,判断是否在黑名单中,在就拒绝访问,不在就放行
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 从request中获取客户端ip
        String clientIp = request.getRemoteAddress().getHostString();
        // 比较
        if (blackList.contains(clientIp)) {
            // 拒绝访问
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            log.info("IP: "+clientIp+"  在黑名单中,拒绝访问");
            String msg = "请求被禁止!";
            DataBuffer wrap = response.bufferFactory().wrap(msg.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(wrap));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;   // 数值越小,优先级越高
    }
}
4 跨域请求
spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations: 
          '[/**]':
            allowed-origins: "*"
            allowed-headers: "*"
            allowed-credentials: true
            allowed-methods:
              - GET
              - POST
              - DELETE
              - OPTION
              - PUT
5 Gateway高可用

网关是一个核心的部件,如果挂掉,所有的请求就无法路由,因此需要实现gateway高可用

实现:启动多个gateway实例来实现gateway高可用,在gateway上的上游使用Nginx做代理,实现负载均衡

# 配置多个Gateway
upstream gateway{
	server 127.0.0.1:10001
	server 127.0.0.1:20001
}
location / {
	proxy_pass http://gateway;
}
*]':
            allowed-origins: "*"
            allowed-headers: "*"
            allowed-credentials: true
            allowed-methods:
              - GET
              - POST
              - DELETE
              - OPTION
              - PUT
5 Gateway高可用

网关是一个核心的部件,如果挂掉,所有的请求就无法路由,因此需要实现gateway高可用

实现:启动多个gateway实例来实现gateway高可用,在gateway上的上游使用Nginx做代理,实现负载均衡

# 配置多个Gateway
upstream gateway{
	server 127.0.0.1:10001
	server 127.0.0.1:20001
}
location / {
	proxy_pass http://gateway;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/755791.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号