SpringCloud微服务API网关Gateway的使用和配置(二)过滤器

目录

  • 一、介绍
  • 二、filters属性配置
    • StripPrefix 去除路径
    • PrefixPath 添加路径
    • AddRequestHeader 添加请求头
    • AddRequestParameter 添加请求参数
    • AddResponseHeader 添加响应头
    • DedupeResponseHeader 去除重复响应头
    • 其他略
  • 三、RequestRateLimiter 网关限流过滤器
    • 3.1 常见的限流算法
      • 计数器算法
      • 漏桶算法
      • 令牌桶算法
    • 3.2 Gateway 中的限流
      • 添加Redis依赖
      • 配置
      • 自定义限流规则
      • 使用Jmter测试
  • 四、HystrixGatewayFilterFactory实现服务降级
  • 五、GlobalFilter 全局过滤器
  • 六、自定义路由过滤器
  • 源码

SpringCloud微服务API网关Gateway的使用和配置(一)路由转发、断言谓词:https://blog.csdn.net/DreamsArchitects/article/details/119330223

一、介绍

本章学习一下Gateway的过滤器的用法。

所有的过滤器都是GatewayFilter 的子类,也是工厂模式。和谓词(AbstractRoutePredicateFactory)是类似的。

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第1张图片

二、filters属性配置

AbstractGatewayFilterFactory下的子类:

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第2张图片

上面的XxxxxGatewayFilterFactory类的前缀就是filter的属性配置

StripPrefix 去除路径

          filters:
            - StripPrefix=1
            # StripPrefix完整配置
#            - name: StripPrefix
#               args:
#                 parts: 1

通过/来分割路径,去掉部分的路径,然后再调用chain.filter 请求转发微服务:
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第3张图片

PrefixPath 添加路径

在这里插入图片描述

          filters:
            - StripPrefix=1  # 去除第一个路径
            - PrefixPath=/storage # 请求路径添加前缀

AddRequestHeader 添加请求头

AddRequestHeader: 为我们的请求添加一个请求头

          filters:
            - StripPrefix=1 # 将请求中的第一个路径去掉 请求路径以/区分,一个/表示一个路径,如:/api/account  会变成/account
            #- PrefixPath=/brand # 为请求路径添加前缀/brand
            - AddRequestHeader=myheader,admin123
             # AddRequestHeader完整写法:
            - name: AddRequestHeader
              args:
                name: newheader
                value: admin456

例如:
我们在Account服务中定义一个接口:
接收请求头,并返回,然后我们在浏览器中访问网关请求路由转发到Account服务:

   @GetMapping("/findAllAndHeader")
    public ResultObject findAllAndHeader(@RequestHeader("myheader") String myheader,@RequestHeader("newheader") String newheader){
        System.out.println("myheader:"+myheader);
        System.out.println("newheader:"+newheader);
        return new ResultObject(true, StatusCode.OK, SystemConstants.QUERY_SUCCESS,myheader+","+newheader);
    }

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第4张图片

AddRequestParameter 添加请求参数

AddRequestParameter:添加一个请求参数

            # AddRequestParameter 添加请求参数
            - AddRequestParameter=name,lisi
            - name: AddRequestParameter
              args:
                name: age
                value: 22
    @GetMapping("/findAllAndHeader")
    public ResultObject findAllAndHeader(@RequestHeader("myheader") String myheader,@RequestHeader("newheader") String newheader,String name,Integer age){
        System.out.println("myheader:"+myheader);
        System.out.println("newheader:"+newheader);
        System.out.println("name:"+name);
        System.out.println("age:"+age);
        return new ResultObject(true, StatusCode.OK, SystemConstants.QUERY_SUCCESS,myheader+","+newheader+","+name+","+age);
    }

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第5张图片

AddResponseHeader 添加响应头

AddResponseHeader:添加一个响应头

DedupeResponseHeader 去除重复响应头

DedupeResponseHeader:对指定响应头去除重复

语法:DedupeResponseHeader=响应头名称 响应头参数,strategy
可选的strategy值:

  • PETAIN_FIRST 默认值,保留第一个
  • RETAIN_LAST 保留最后一个
  • RETAIN_UNIQUE 保留唯一的,出现重复的属性值,会保留一个,例如有两个My:aaa的属性,最后会保留一个。

其他略

其他不再一一演示

三、RequestRateLimiter 网关限流过滤器

3.1 常见的限流算法

计数器算法

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第6张图片

漏桶算法

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第7张图片

令牌桶算法

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第8张图片

3.2 Gateway 中的限流

RequestRateLimiter 是基于 RedisLua 脚本实现的令牌桶算法。

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第9张图片

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第10张图片

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第11张图片

由于还未导包,所以报红
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第12张图片

添加Redis依赖

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redisartifactId>
        dependency>
        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-pool2artifactId>
        dependency>

配置

          filters:
            - name:
              args:
                keyResolver: '#{@myResolver}' #使用Spring EL表达式 从容器中获取对象 '#{@beanName}'
                redis-rate-limiter.replenishRate: 1 # 生产令牌速度 每秒多少个令牌
                redis-rate-limiter.burstCapacity: 5 # 令牌桶容量

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第13张图片

在这里插入图片描述

自定义限流规则

根据IP限流:

@Component
public class MyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        InetSocketAddress remoteAddress = exchange.getRequest().getRemoteAddress();
        System.out.println("----remoteAddress : "+remoteAddress);
        InetAddress address = remoteAddress.getAddress();
        System.out.println("address : "+address);
        String hostAddress = address.getHostAddress();
        System.out.println("hostAddress : "+hostAddress);

        return Mono.just(hostAddress);
    }
}

使用Jmter测试

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第14张图片

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第15张图片

四、HystrixGatewayFilterFactory实现服务降级

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第16张图片

配置过滤器:

            - name: Hystrix
              args:
                name: fallback
                fallbackUri: forward:/gatewayHystrix #远程服务调用错误的时候  Gateway工程中的哪一个控制器逻辑,返回降级结果

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第17张图片

定义降级方法:
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第18张图片

@RestController
public class GatewayController {

    @GetMapping("/test")
    public Map testApi() throws InterruptedException {
        HashMap<String, String> map = new HashMap<>();
        map.put("code","0000");
        map.put("msg","success");
        map.put("api","/api/test");
        Thread.sleep(2000);
        return map;

    }

    @RequestMapping(value = "/gatewayHystrix",produces = "text/html;charset=UTF-8")
    public String hystrix(){
        System.out.println("执行Gateway降级方法");
        String body = "
服务器繁忙,请稍后再试!
"
; return body; } }

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第19张图片

五、GlobalFilter 全局过滤器

使用GlobalFilter实现统一的权限验证、日志记录等希望所有代理的项目都生效的内容都可以配置在全局过滤器中。

package com.lsh.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Date;

/**
 * @author :LiuShihao
 * @date :Created in 2021/7/23 4:47 下午
 * @desc :当请求与路由匹配时,过滤 Web 处理程序会将 的所有实例GlobalFilter和所有特定GatewayFilter于路由的实例添加到过滤器链中。
 * 这个组合过滤器链是按org.springframework.core.Ordered接口排序的,你可以通过实现getOrder()方法来设置。
 */
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override 
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //前置过滤
        URI uri = exchange.getRequest().getURI();
        log.info("Gateway Global Filter : "+uri+" ; date : "+new Date().toString());
        Mono<Void> filter = chain.filter(exchange);
        log.info("全局过滤器-后置过滤");

        //后置过滤

        return filter;
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第20张图片

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第21张图片

六、自定义路由过滤器

参考StripPrefixGatewayFilterFactory过滤器:
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第22张图片
新建一个XxxGatewayFilterFactory继承AbstractGatewayFilterFactory
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第23张图片

需要注意几点:
1.无参构造
在这里插入图片描述
2. Config内部类
一定要有get/set方法
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第24张图片
3.重写apply(Config config)方法
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第25张图片

4.重写shortcutFieldOrder()方法
SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第26张图片

源码:

package com.lsh.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * @author :LiuShihao
 * @date :Created in 2021/8/16 5:13 下午
 * @desc :自定义路由过滤器  参考StripPrefixGatewayFilterFactory
 */
@Component
public class RequestPathGatewayFilterFactory
        extends AbstractGatewayFilterFactory<RequestPathGatewayFilterFactory.Config> {

    public RequestPathGatewayFilterFactory() {
        super(Config.class);
    }

    //如果可以简化配置方案,当前方法返回简化配置参数命名列表
    // RequestPath=NameValue,PathValue
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name","path");
    }

    //过滤逻辑
    @Override
    public GatewayFilter apply(Config config) {
        //匿名内部类
        return new GatewayFilter() {
            //过滤方法
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                String path = exchange.getRequest().getPath().toString();
                System.out.println("路由过滤器:本次请求地址为:"+path+",配置的参数为:name:"+config.getName()+",path:"+config.getPath());
                //写在chain.filter(exchange)之前的前置过滤,之后的后置过滤
                Mono<Void> filter = chain.filter(exchange);

                return filter;
            }
        };
    }
    //内部类
    //当前过滤器需要使用的配置内容
     public static class Config{

        private String name;

        private String path;

        //Get / Set 方法
        public String getName() {
            return name;
        }

        public Config setName(String name) {
            this.name = name;
            return this;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }
    }
}

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第27张图片

SpringCloud微服务API网关Gateway的使用和配置(二)过滤器_第28张图片

源码

https://gitee.com/L1692312138/spring-cloud-alibaba

你可能感兴趣的:(SpringCloud,SpringBoot,过滤器,java,gateway,网关)