美文网首页
spring cloud gateway

spring cloud gateway

作者: 走在冷风中吧 | 来源:发表于2020-02-25 11:04 被阅读0次

客户端访问服务器资源时, 通过网关访问服务器资源, 网关主要有过滤, 鉴权,日志记录, 路由,限流等的功能, 其中过滤器的作用与Spring过滤器功能相通.
Spring Cloud Gateway是spring cloud团队基于Spring5.0, SpringBoot2.0等技术开发的, 本身也是一个微服务, 需要注册到Eureka中心.

网关作用关系图

使用网关的优点:

  1. 安全, 只有网关对外暴露, 微服务可以隐藏于内网, 通过防火墙进行保护
  2. 易于监控, 可以在网关收集监控数据并将其推送到外部系统进行分析
  3. 易于认证, 可以在网关进行认证后再转发到微服务器, 无需再微服务中认证
  4. 减少了客户端和微服务之间的交互次数
  5. 易于统一授权

搭建网关微服务, 实现路由分发:

  1. 创建SpringBoot工程gateway_server, 选择Eureka客户端和gateway两个starter
image.png
  1. 在application.yml进行配置, 主要进行路由的配置,
    这里采用lb协议, 通过服务的应用名称在Eureka注册中心获取到地址和端口号, 并且自动启用负载均衡进行访问
#声明注册中心地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka

spring:
  #配置应用名称
  application:
    name: gateway-server
  #配置路由分发
  cloud:
    gateway:
      # 路由si(集合)
      routes:
        # id唯一标识
        - id: user-service-route
          # 路由服务地址 采用lb协议, 实现动态地址获取, 采用lb协议时会自动使用负载均衡访问
          uri: lb://provider-service
          # 断言, 对于/user/*路径的地址会路由到provider-service服务中去
          predicates:
            - Path=/user/**
          filter: 
            # 配置真正地址中转时路由地址去掉断言的一个参数
            - StripPrefix= 1 

  1. 增加过滤器: gateway自带几十种过滤器, 具体可查看官网gatewayfilter_factories
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar
        - AddRequestParameter=foo, bar

request的header会增加X-Request-Foo:Bar字段
request的请求字段会增加foo=bar参数

过滤器的类型有两种, 以上为局部过滤器, 还有全局过滤器, 作用在所有路由上

spring:
  cloud:
    gateway:
    # 配置全局默认过滤器
      default-filters:
        # 往响应过滤器中加入信息
        - AddResponseHeader=i-info, Foo

配置网关的跨域问题:

spring:
  application:
    name: sysgateway
  cloud:
    gateway:
      #解决跨域问题
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
              - GET
              - POST
              - PUT
              - DELETE
请求和响应的过滤器链执行顺序
  1. 在gate-server自定义全局过滤器, 实现GlobalFilter接口, Ordered接口用来指定filter的执行顺序. 重启服务器即可生效. 注意这个类要用component注解CIA会被spring容器加载.
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    /**
     * 设置全局的filter, 比如进行身份的认证
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //这里假装进行身份验证
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (StringUtil.isNullOrEmpty(token)){
            //拦截
            return exchange.getResponse().setComplete();
        }
        //放行
        return chain.filter(exchange);
    }


    /**
     * 设置filter的执行顺讯
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

网关的限流:

​ 我们之前说过,网关可以做很多的事情,比如,限流,当我们的系统 被频繁的请求的时候,就有可能 将系统压垮,所以 为了解决这个问题,需要在每一个微服务中做限流操作,但是如果有了网关,那么就可以在网关系统做限流,因为所有的请求都需要先通过网关系统才能路由到微服务中。

令牌桶算法

令牌桶算法是常见的限流算法之一, 大致描述如下:

  1. 所有的请求在处理之前都需要拿到一个令牌才能做被处理, 业务处理完后会将令牌删除
  2. 根据限流的大小, 按照一定的速率往桶里添加令牌
  3. 桶设置最大的令牌限额, 当达到最大值时, 新到的令牌会被丢弃或者拒绝
  4. 桶有最低令牌限额, 当达到最小值时, 业务处理完成后的令牌不会被删除, 以此保证足够的令牌

使用redis中的Ratelimter令牌桶算法实现网关的限流
需求:每个ip地址1秒内只能发送1次请求,多出来的请求返回429错误。

代码实现:

  1. 引入redis的RateLimter限流算法来实现
<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>
  1. 在GatewayApplication中定义KeyResolver对象, 用于指定使用id作为限流条件
    @Bean
    public KeyResolver ipKeyResolver(){
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
            }
        };
    }
  1. 在application.yml中设置限流规则和redis服务器地址
       filters:
        - StripPrefix= 1
        - name: RequestRateLimiter #请求数限流 名字不能随便写 
          args:
            key-resolver: "#{@ipKeyResolver}"
            redis-rate-limiter.replenishRate: 1
            redis-rate-limiter.burstCapacity: 1

  redis:
    host: 192.168.225.128
    port: 6379

解释:

  • burstCapacity:令牌桶总容量。
  • replenishRate:令牌桶每秒填充平均速率。
  • key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

如上配置表示: 一秒内允许一个请求通过, 令牌桶的速度也是一秒内添加一个令牌
通过在replenishRate和中设置相同的值来实现稳定的速率burstCapacity。设置burstCapacity高于时,可以允许临时突发replenishRate。在这种情况下,需要在突发之间允许速率限制器一段时间(根据replenishRate),因为2次连续突发将导致请求被丢弃(HTTP 429 - Too Many Requests

相关文章

网友评论

      本文标题:spring cloud gateway

      本文链接:https://www.haomeiwen.com/subject/bedzqhtx.html