getWay的简单使用

  • 网关介绍

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等

  • getWay 介绍

Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。
相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。
它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于
Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html
/#gateway-starter

  • 核心概念

  • 路由(route)
    路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组谓 词工厂、一组Filter
    组成。如果谓词为真,则说明请求的URL和配置的路由匹配。

  • 谓词(predicates)
    即java.util.function.Predicate , Spring Cloud Gateway使用Predicate实现路由的匹配条件。

  • 过滤器(Filter)
    SpringCloud Gateway中 的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应
    进行处理。
    【路由就是转发规则,谓词就是是否走这个路径的条件,过滤器可以为路由添加业务逻辑,修改
    请求以及响应】

  • 工作原理

  • 客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会
    被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
    过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻
    辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑。
    在这里插入图片描述

一环境搭建

网关引入依赖

getway不可以

 <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>test</scope> <!-- 特殊处理,不引入父工程依赖 -->
        </dependency>
    </dependencies>

添加配置文件

server:
  port: 13001
spring:
  application:
    name: msb-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          #默认值是false,如果设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
          #http://localhost:13001/msb-order/order/create
          #不建议打开,因为这样暴露了服务名称
          enabled: false
      #是否开启网关
      enabled: true
      routes:
        #路由ID全局唯一
        - id: msb-order-route
          #目标微服务的请求地址和端口
          uri: lb://msb-order
          predicates:
            - Path=/order/*

这里注意不要引入springmvc工程否则会报错如下
在这里插入图片描述
不建议开启通过微服务创建路由的功能,这样就把微服务名称暴露了
在这里插入图片描述
在这里插入图片描述
刚才能成功主要是
http://localhost:13001/msb-order/order/create 可以进行转化:
http://localhost:13001/msb-order/order/create可以替换为http://localhost:8001/order/create
然而此时的请求是转化不了的
http://localhost:13001/order/create
这是我们就需要我们的gateway 中的 route& predicates 建立映射
在这里插入图片描述

二路由谓词工厂(Route Predicate Factories)配置

1、路由配置的两种形式

1.1 路由到指定URL
  • 通配
spring:
 cloud:
  gateway:
   routes:
    - id: {唯一标识}
      uri: http://localhost:8001

表示访问 GATEWAY_URL/ == 会转发到http://localhost:8001/ ==
注:上面路由的配置必须和下面谓词(Predicate)配合使用才行

  • 精确匹配
spring:
 cloud:
  gateway:
  routes:
  -id: {唯一标识}
   uri: http://localhost:8001/
   predicates:
   - Path=/order/

表示访问 GATEWAY_URL/order/会转发到 http://localhost:8001/order/

1.2 路由到服务发现组件上的微服务

  • 通配
spring:
 cloud:
  gateway:
  routes:
  - id: {唯一标识}
    uri: lb://msb-order

表示访问 GATEWAY_URL/会转发到 msb-order 微服务的 /
注:上面路由的配置必须和下面谓词(Predicate)配合使用才行

  • 精确匹配
spring:
 cloud:
  gateway:
  routes:
  - id: {唯一标识}
   uri: lb://msb-order/
    predicates:
   - Path=/order/*

表示访问 GATEWAY_URL/order/ 会转发到 msb-order 微服务的 /order/

2.谓词工厂分类

官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayrequest-predicates-factories
网关项目启动日志:
在这里插入图片描述
在这里插入图片描述

3.谓词介绍和使用

3.1 Between路由断言工厂

关于时间的谓词技巧:时间可使用 System.out.println(ZonedDateTime.now()); 打印,然后即可看到时区。例如:
2023-06-01T11:16:53.291+08:00[Asia/Shanghai]
在这里插入图片描述

该断言工厂的参数是两个 UTC 格式的时间。其会将请求访问到 Gateway 的时间与这两个参数时间相比,若请求时间在这两个 两个时间之间可以正常请求

server:
  port: 13001
spring:
  application:
    name: msb-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          #默认值是false,如果设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
          #http://localhost:13001/msb-order/order/create
          #不建议打开,因为这样暴露了服务名称
          enabled: false
      #是否开启网关
      enabled: true
      routes:
        #路由ID全局唯一
        - id: msb-order-route
          #目标微服务的请求地址和端口
          uri: lb://msb-order
          predicates:
            - Path=/order/*
   #        - TimeBetween= 上午08:00,下午10:00
            - Between=2023-05-31T00:00:01+08:00[Asia/Shanghai], 2023-05-31T23:59:59+08:00[Asia/Shanghai]
           #Cookie配置
#            - Cookie=username, msb
#            - Header=X-Request-Id, \d+
#          # #请求某个接口在这个时间段是有效的

          filters:
#            - AddResponseHeader=X-Response-name, msb
            - PrintLog=sex,man

在这个时间范围内的请求,可以正常转发,不在这个时间范围内的请求,则 404
在这里插入图片描述
在这里插入图片描述

3.2 After路由断言工厂

该断言工厂的参数是一个 UTC 格式的时间。其会将请求访问到 Gateway 的时间与该参数时间相比,若请求时间在参数时间后面,则可以正常访问,否则404

在这里插入图片描述

3.3 Before路由断言工厂

该断言工厂的参数是一个 UTC 格式的时间。其会将请求访问到 Gateway 的时间与该参数时间相比,若请求时间在参数时间前面,则可以正常访问,否则404
在这里插入图片描述

3.4 Cookie路由断言工厂

该断言工厂中包含两个参数,分别是 cookie 的 key 与 value。当请求中携带了指定 key与 value 的 cookie 时,匹配对应的请求,否则 404 value值可以是具体的值,也可以是正则表达式
在这里插入图片描述

3.5 Header路由断言工厂

该断言工厂中包含两个参数,分别是请求头 header 的 key 与 value。当请求中携带了指定 key 与 value 的 header 时,正常转发,否则404 value可以是正则
在这里插入图片描述

3.6 Host路由断言工厂

该断言工厂中包含的参数是请求头中的 Host 属性。当请求中携带了指定的 Host 属性值时,匹配成功,断言为 true。
在这里插入图片描述

3.6 Weight路由断言工厂

谓词还有很多,Weight不长用,却很重要。
该断言工厂中包含两个参数,分别是用于表示组 group,与权重 weight。对于同一组中的多个 uri 地址,路由器会根据设置的权重,按比例将请求转发给相应的 uri。实现负载均衡。可以实现灰度发布功能。

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org        
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

group 组,权重根据组来计算
weight 权重值,是一个 Int 的值

四 自定义谓词

  • 配置文件中添加自定义的谓词
    在这里插入图片描述

  • 新建java类,接受配置文件的参数

@Data
public class TimeBetweenConfig {
    private LocalTime start;
    private LocalTime end;

}
  • 配置谓词工厂
    定义路由断言工厂TimeBetween + RoutePredicateFactory 结尾TimeBetweenRoutePredicateFactory继承AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
@Slf4j
@Component
public class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenConfig1> {

    public TimeBetweenRoutePredicateFactory() {
        super(TimeBetweenConfig1.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(TimeBetweenConfig1 config) {
        LocalTime start = config.getStart();
        LocalTime end = config.getEnd();
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                LocalTime now = LocalTime.now();
                //匹配规则,返回true则正常转发
                return now.isAfter(start) && now.isBefore(end);
            }
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("start","end");
    }
}

三过滤器工厂( GatewayFilter Factories)配置

SpringCloudGateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等
官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html
/#gatewayfilter-factories

1、内置过滤器

1.1 AddRequestHeader 过滤工厂
为原始请求添加名为 X-Request-Foo ,值为 Bar 的请求头。
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Ba
1.2AddRequestParameter 过滤工厂
 为原始请求添加请求参数 foo=bar
spring:
  cloud:
    gateway:
      routes:
       - id: add_request_parameter_route         
         uri: https://example.org
         filters:
         - AddRequestParameter=foo, bar

在这里插入图片描述

正常请求,两个参数
在这里插入图片描述
接受并打印参数,打印了新增的参数
在这里插入图片描述

1.3 AddResponseHeader 过滤工厂

添加名为 X-Response-foo ,值为 addHeader 的响应头

spring:
  cloud:
    gateway:
      routes:
       - id: add_request_parameter_route         
         uri: https://example.org
         filters:
         - AddRequestParameter=foo, bar
         - AddResponseHeader=X-Response-foo,addHeader

在这里插入图片描述

1.4DedupeResponseHeader 过滤工厂

== Spring Cloud Greenwich SR2提供的新特性,低于这个版本无法使用 ==

强烈建议阅读一下类org.springframework.cloud.gateway.filter.factory.
DedupeResponseHeaderGatewayFilterFactory上的注释,比官方文档写得还好

spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_FIRST

剔除重复的响应头。
举个例子:
我们在Gateway以及微服务上都设置了CORS(解决跨域)header,如果不做任何配置,请求 -> 网关 -> 微服务,获得的响应就是这样的:

Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://www.msbedu.com, https://www.msbedu.com

** 也就是Header重复了。要想把这两个Header去重,只需设置成如下即可。**

filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

也就是说,想要去重的Header如果有多个,用空格分隔即可;
去重策略:

RETAIN_FIRST: 默认值,保留第一个值
RETAIN_LAST: 保留最后一个值
RETAIN_UNIQUE: 保留所有唯一值,以它们第一次出现的顺序保留

1.5 PrefixPath过滤工厂

为匹配的路由添加前缀。例如:访问 ${GATEWAY_URL}/hello 会转发到 https://example.org /mypath/hello

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org         
        filters:
        - PrefixPath=/mypath
1.6 PreserveHostHeader 过滤工厂

如果不设置,那么名为 Host 的Header由Http Client控制;如果设置了,那么会设置一个请求属性。(preserveHostHeader=true),路由过滤器会检查从而去判断是否要发送原始的、名为Host的Header。

spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route        
      - uri: https://example.org         
      - filters:
      - PreserveHostHeader
1.7 RequestRateLimiter 过滤工厂
spring:
 cloud:
 gateway:
 routes:
 - id: requestratelimiter_route
 uri: https://example.org
 filters:
 - name: RequestRateLimiter
 args:
 redis-rate-limiter.replenishRate: 10
 redis-rate-limiter.burstCapacity: 20
1.8RedirectTo 过滤工厂
  • HTTP状态码应该是HTTP状态码300序列,例如301
  • URL必须是合法的URL,并且该值会作为名为 Location 的Header。

上面配置表达的意思是: ${GATEWAY_URL}/hello 会重定向到 https://ecme.org/hello ,并且携
带一个 Location:http://www.msb.com 的Header。

spring:
 cloud:
 gateway:
 routes:
 - id: prefixpath_route
 uri: https://example.org
 filters:
 # 配置成HTTP状态码, URL的形式
 - RedirectTo=302, http://www.msb.com
1.9 RemoveHopByHopHeadersFilter 过滤工厂

spring.cloud.gateway.filter.remove-hop-by-hop.headers: Connection,Keep-Alive
移除转发请求的Header,多个用 , 分隔。默认情况下,移除如下Header。这些Header是由 IETF 组
织规定的。

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
1.10 RemoveRequestHeader 过滤工厂

原始请求删除名为 X-Request-Foo 的请求头

spring:
 cloud:
 gateway:
 routes:
 - id: removerequestheader_route
 uri: https://example.org
 filters:
 - RemoveRequestHeader=X-Request-Foo
1.11 RemoveResponseHeader 过滤工厂

删除名为 X-Request-Foo 的响应头。

spring:
 cloud:
 gateway:
 routes:
 - id: removeresponseheader_route
 uri: https://example.org
 filters:
 - RemoveResponseHeader=X-Response-Foo
1.12 RewritePath 过滤工厂

重写请求路径。如上配置,访问 /foo/bar 会将路径改为 /bar 再转发,也就是会转发到 https://exa
mple.org/bar 。需要注意的是,由于YAML语法,需用 $\ 替换 $ 。

spring:
 cloud:
  gateway:
   routes:
    - id: rewritepath_route
      uri: https://example.org
      predicates:
      - Path=/foo/**
      filters:
      # 配置成原始路径正则, 重写后的路径的正则
      - RewritePath=/foo/(?<segment>.*), /$\{segment}
1.13 RewriteResponseHeader 过滤工厂

对部分参数进行替换,如手机号,证件号 加*

如果名为 X-Response-Foo 的响应头的内容是 /42?user=ford&password=omg!
what&flag=true,则会被修改为 /42?user=ford&password=***&flag=true。

spring:
 cloud:
 gateway:
 routes:
 - id: rewriteresponseheader_route
 uri: https://example.org
 filters:
 - RewriteResponseHeader=X-Response-Foo, password=[^&]+, password=***
1.14 SaveSession 过滤工厂

在转发到后端微服务请求之前,强制执行 WebSession::save 操作。用在那种像 Spring Session 延
迟数据存储(笔者注:数据不是立刻持久化)的,并希望在请求转发前确保session状态保存情况。
如果你将 Spring Secutiry于 Spring Session集成使用,并想确保安全信息都传到下游机器,你就需
要配置这个filter。

spring:
 cloud:
 gateway:
 routes:
 - id: save_session
 uri: https://example.org
 predicates:
 - Path=/foo/**
 filters:
 - SaveSession
1.15 SecureHeaders 过滤工厂

添加一系列起安全作用的响应头。Spring Cloud Gateway参考了这篇博客的建议:https://blog.
appcanary.com/2017/http-security-headers.html
默认会添加如下Header(包括值):

  • X-Xss-Protection:1; mode=block
  • Strict-Transport-Security:max-age=631138519
  • X-Frame-Options:DENY
  • X-Content-Type-Options:nosniff
  • Referrer-Policy:no-referrer
  • Content-Security-Policy:default-src ‘self’ https:; font-src ‘self’ https: data:; img-src ‘self’
    https: data:; object-src ‘none’; script-src https:; style-src ‘self’ https: ‘unsafe-inline’
  • X-Download-Options:noopen
  • X-Permitted-Cross-Domain-Policies:none
    如果你想修改这些Header的值,可使用如下配置:
    前缀:spring.cloud.gateway.filter.secure-headers
    上面的header对应的后缀:
  • xss-protection-header
  • strict-transport-security
  • frame-options
  • content-type-options
  • referrer-policy
  • content-security-policy
  • download-options
  • permitted-cross-domain-policies
    例如:spring.cloud.gateway.filter.secure-headers.xss-protection-header: 你想要的值
    如果想禁用某些Header,可使用如下配置:spring.cloud.gateway.filter.secure-headers.disable
    ,多个用 , 分隔。例如:spring.cloud.gateway.filter.secure-headers.disable=frame-options,
    download-options 。
1.16 SetPath 过滤工厂

采用路径 template参数,通过请求路径的片段的模板化,来达到操作修改路径的母的,运行多个路
径片段模板化。
如上配置,访问 ${GATEWAY_PATH}/foo/bar ,则对于后端微服务的路径会修改为 /bar 。

spring:
 cloud:
 gateway:
 routes:
 - id: setpath_route
 uri: https://example.org
 predicates:
 - Path=/foo/{segment}
 filters:
 - SetPath=/{segment}
1.18 SetStatus 过滤工厂

修改响应的状态码,值可以是数字,也可以是字符串。但一定要是Spring HttpStatus 枚举类中的
值。如上配置,两种方式都可以返回HTTP状态码401。

spring:
 cloud:
 gateway:
 routes:
 - id: setstatusstring_route
 uri: http://example.org
 filters:
 - SetStatus=BAD_REQUEST
 - id: setstatusint_route
 uri: http://example.org
 filters:
 - SetStatus=401
1.19 StripPrefix 过滤工厂

数字表示要截断的路径的数量。如上配置,如果请求的路径为 /name/bar/foo ,则路径会修改为 /f
oo ,也就是会截断2个路径。

spring:
 cloud:
 gateway:
 routes:
 - id: nameRoot
 uri: http://nameservice
 predicates:
 - Path=/name/**
 filters:
 - StripPrefix=2
1.20 Retry 过滤工厂

针对不同的响应做重试,可配置如下参数:

  • retries: 重试次数
  • statuses: 需要重试的状态码,取值在 org.springframework.http.HttpStatus 中
  • methods: 需要重试的请求方法,取值在 org.springframework.http.HttpMethod 中
  • series: HTTP状态码系列,取值在 org.springframework.http.HttpStatus.Series 中
spring:
 cloud:
 gateway:
 routes:
 - id: retry_test
 uri: http://localhost:8080/flakey
 predicates:
 - Host=*.retry.com
 filters:
 - name: Retry
 args:
 retries: 3
 statuses: BAD_GATEWAY
1.21 RequestSize 过滤工厂

为后端服务设置收到的最大请求包大小。如果请求大小超过设置的值,则返回 413 Payload Too
Large 。默认值是5M

spring:
 cloud:
 gateway:
 routes:
 - id: request_size_route
 uri: http://localhost:8080/upload
 predicates:
 - Path=/upload
 filters:
 - name: RequestSize
 args:
 # 单位字节
 maxSize: 5000000
1.22 默认过滤器工厂
spring:
 cloud:
 gateway:
 default-filters:
 - AddResponseHeader=X-Response-Default-Foo, Default-Bar
 - PrefixPath=/httpbin

四.自定义局部过滤器

4.1 过滤器生命周期

pre : Gateway转发请求之前
post : Gateway转发请求之后

4.2 自定义过滤器工厂的方式
  • 自定义过滤器工厂-方式1
    继承: AbstractGatewayFilterFactory

过滤器工厂的顶级接口是GatewayFilterFactory,我们可以直接继承它的两个抽象类来简化开发AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,这两个抽象类的区别就是前者接收一个参数(像StripPrefix和我们创建的这种),后者接收两个参数(像AddResponseHeader)
在这里插入图片描述
注意自定义拦截器的命名,以GatewayFilterFactory结尾,前面是拦截器名

  • 1.继承AbstractNameValueGatewayFilterFactory
    在这里插入图片描述
@Slf4j
@Component
public class ITestGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory{


    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //
        log.info("打印请求信息?:{}:{}",config.getName(),config.getValue());
                // 获取request就可以进行修改了
//           ServerHttpRequest modifiedRequest1 = exchange.getRequest().mutate().build();
                ServerHttpRequest request = exchange.getRequest().mutate().build();
              HttpMethod method =   request.getMethod();
              log.info(String.valueOf(method.getClass().getFields().length));
                ServerWebExchange modifiedExchange = exchange.mutate().request(request).build();
                return chain.filter(modifiedExchange);
            }
        };
    }
}

通过NameValueConfig config 的对象可以拿到拦截器的key value值,exchange 可以获取请求request相关的信息
在这里插入图片描述

  • 2.继承AbstractGatewayFilterFactory
    将ITest2GatewayFilterFactory继承父类AbstractGatewayFilterFactory并添加@Component注解
    代码结构:
    在这里插入图片描述
@Data
public class ITestFilterConfig {

    public String iTest;


}

在这里插入图片描述

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component
public class ITest2GatewayFilterFactory extends AbstractGatewayFilterFactory<ITestFilterConfig> {

    public ITest2GatewayFilterFactory() {
        super(ITestFilterConfig.class);
    }


    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("iTest");
    }


    @Override
    public GatewayFilter apply(ITestFilterConfig config) {
        return  (exchange, chain) -> {
            // http://localhost:10010/user/8?name=yh config.param ==> name
            //获取请求参数中param对应的参数名 的参数值
            ServerHttpRequest request = exchange.getRequest();
            log.info("打印请求信息?:{}:{}",config.getITest()+"99");
            if (request.getQueryParams().containsKey(config.iTest)){
                request.getQueryParams().get(config.iTest).forEach((v) -> {
                    System.out.print("--局部过滤器--获得参数 "+config.iTest+"="+ v);
                });
            }
            return chain.filter(exchange);//执行请求
        };

    }
}

怎么实现拿到所有配置参数待研究花掉部分没能进去
在这里插入图片描述

五自定义全局变量

  • 实现两个接口,交给框架管理
    DEMO,用来测试相同请求ip下访问次数
    主要实现类
@Slf4j
@Component
public class IPAddressStatisticsFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        InetSocketAddress host = exchange.getRequest().getHeaders().getHost();
        if (host == null || host.getHostName() == null) {
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
        }
        String hostName = host.getHostName();
        AtomicInteger count = IpCache.CACHE.getOrDefault(hostName, new AtomicInteger(0));
        count.incrementAndGet();
        IpCache.CACHE.put(hostName, count);
        log.info("IP地址:" + hostName + ",访问次数:" + count.intValue());
        return chain.filter(exchange);
    }

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

用于存放不同ip请求次数的map

//用于保存次数的缓存
public class IpCache {
    public static final Map<String, AtomicInteger> CACHE = new ConcurrentHashMap<>();
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值