spring cloud Gateway网关

        网关是将所有面向用户的服务接口统一管理的代理服务器,所有内部服务的远程调用都是在局域网内部,而网关是在公网中。

一、依赖

        通过访问网关调用项目中的服务,需要使用Eureka,网关服务器需要在Eureka服务注册它自己,本身也就是一个Eureka Client。

        远程调用服务自然也离不开熔断降级的保护机制,使用Hystrix

        网关是对所有访问的统一入口,面对恶意攻击,大量并发的情况,通常使用令牌桶机制来处理,令牌储存在redis中。

        

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR12</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>


 


二、基本配置

gateway解析自己配置时,- 代表了创建一个对象: 

        id: 路由名称

        uri:  调用的服务主机名

        predicates:代理地址 

                  代理本身只解析主机名ip端口号,和代理地址做拼接,需要手动将/abc去除。

                  Vue3中代理配置也一样:      

        Filter:

                因为所有Filter都以GatewayFilterFactory结尾,所有该结尾省略不写。

                - StripPrefix=1

                          //简写形式  name =StripPrefixGatewayFilterFactory,参数为1

                - name: RequestRateLimiter  //通用的写法

                  args:...

server:
  port: 9999
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
spring:
  redis:
    host: localhost
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false
          lower-case-service-id: true
      routes:
        - id: rateLimiter
          uri: lb://application-service
          predicates:
            - Path=/abc/**
          filters:
            - StripPrefix=1

 



三、令牌桶过滤器

        实现KeyResolver接口的resolve()方法

@Component
public class MyKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        String ip = exchange.getRequest()
                .getRemoteAddress()
                .getAddress()
                .getHostAddress();
        return Mono.just(ip);
    }
}
          filters:
            - StripPrefix=1

            - name: RequestRateLimiter
              args:
                keyResolver: '#{@myKeyResolver}' # 表达式, #{} 从容器找对象, @beanId
                redis-rate-limiter.replenishRate: 1 # 每秒令牌生成速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶容量上限


四、熔断降级过滤器

                配置HystrixGatewayFilterFactory对象,自定义降级的uri

          filters:
            - StripPrefix=1

            - name: RequestRateLimiter
              args:
                keyResolver: '#{@myKeyResolver}' # 表达式, #{} 从容器找对象, @beanId
                redis-rate-limiter.replenishRate: 1 # 每秒令牌生成速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶容量上限

            - name: Hystrix
              args:
                name: fallback # 随意定义的名称。相当于@HystrixCommand注解中的commandKey属性。
                fallbackUri: forward:/fallback # 如果转发


五、全局过滤器和自定义过滤器:

        全局过滤器:

                实现GlobalFilter的filter()方法

@Component
public class MyGlobalFilter implements GlobalFilter {
    /**
     * 过滤方法。
     * 实现上,只有唯一的要求。必须调用方法chain.filter(exchange),并把方法的返回值,返回。
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("前置全局过滤");
        Mono<Void> result = chain.filter(exchange);
        System.out.println("后置全局过滤");
        return result;
    }
}

         自定义过滤器:

                1.仿照其他Gateway提供的过滤器,创建一个LoggerFilterGatewayFilterFactory继承AbstractGatewayFilterFactory<LoggerFilterGatewayFilterFactory.Config>

@Component
public class LoggerFilterGatewayFilterFactory
        extends AbstractGatewayFilterFactory<LoggerFilterGatewayFilterFactory.Config> {

    /**
     * 建议提供2个构造方法。一个无参数。一个有参数,参数类型就是当前类型中的Config静态内部类的类对象类型。
     * 父类型,可以帮助解析配置文件,并创建Config对象。
     */
    public LoggerFilterGatewayFilterFactory(){
        this(Config.class);
    }

    public LoggerFilterGatewayFilterFactory(Class<Config> configClass){
        super(configClass);
    }

    /**
     * 如果需要简化配置方案。提供方法shortcutFieldOrder
     * 有当前方法,配置文件使用,可以简化配置为    LoggerFilter=abc
     * 没有当前方法,配置文件完整编写,内容是:
     *   name: LoggerFilter
     *   args:
     *     remark: abc
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("remark");
    }

    /**
     * 创建网关过滤器的方法。
     * @param config 就是配置文件中的内容,就是当前类型中的静态内部类对象。
     * @return 一般使用匿名内部类,创建GatewayFilter接口的实现对象。
     */
    @Override
    public GatewayFilter apply(Config config) {

        return new GatewayFilter() {
            /**
             * 过滤方法。要求必须调用chain.filter(exchange),并返回方法的返回结果
             * @param exchange
             * @param chain
             * @return
             */
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println("前置 - 日志过滤器 - config.remark = " + config.getRemark());
                Mono<Void> result = chain.filter(exchange);
                System.out.println("后置 - 日志过滤器 - config.remark = " + config.getRemark());

                return result;
            }
        };
    }

    /**
     * 定义静态内部类,作为配置对象
     * 定义的每个属性,都是用于在配置文件中配置的对应属性。
     * 必须提供getter和setter方法。
     */
    public static class Config{
        private String remark;

        public String getRemark() {
            return remark;
        }

        public void setRemark(String remark) {
            this.remark = remark;
        }
    }
}

        2.配置文件编写该自定义过滤器对象配置信息

          filters:
            - StripPrefix=1

            - name: RequestRateLimiter
              args:
                keyResolver: '#{@myKeyResolver}' # 表达式, #{} 从容器找对象, @beanId
                redis-rate-limiter.replenishRate: 1 # 每秒令牌生成速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶容量上限

            - name: Hystrix
              args:
                name: fallback # 随意定义的名称。相当于@HystrixCommand注解中的commandKey属性。
                fallbackUri: forward:/fallback # 如果转发

            - name: LoggerFilter
              args:
                remark: fullyTestGatewayFilter

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值