这几篇将API安全的 流控、认证、审计、授权 简单的过一遍,对这些概念先有个初步印象。后边还会详细讲解。

本篇说API安全之流控~第一印象。

一、概念

流控,流量控制,只放系统能处理的请求的数量过去,处于api安全链路的第一关。

为什么要做流控?保证系统的可用性,防止大流量把系统给压死。流控的位置做在认证、审计、授权等整个安全机制的最前边,提前控制流量,避免其他无用的资源浪费。

如果没有流控放在第一道档线,攻击者弄一堆肉鸡,发起DDOS攻击,即使你后边的认证、审计、授权 做得再好,也可能把你的服务压死。

比如系统每秒只能处理500个请求,那么每秒就放500个请求过去,多了的请求直接拒绝掉,这样的话系统不会被压死。实际中的流控是非常复杂的,不是简单地设个数就完了。

二,流控做在哪?

实际开发中限流可以在很多地方做的, 比如:

1,在负载均衡上做,

2,在反向代理上做,

在负载均衡或反向代理层面上做限流,实际上一般是针对真个集群做的限流。比如你一个用户服务,实际部署的时候可能是四个机器或者八个机器的集群,在负载均衡或反向代理层面做的集群就是真对整个集群做的限流,整个集群能撑多少流量,做个限流。

3,在自己的应用代码上做。

只针对单个应用的节点做的流控,跟反向代理、负载均衡做的限流不是一个维度的,如果能配的话,把两边都配上,他们并不冲突。后边会介绍通过框架控制集群的流量。

三,使用Guava做简单的限流

在pom引入最新的guava依赖

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>28.1-jre</version>
</dependency>

项目:

写一个限流的过滤器:

package com.nb.security.filter;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 继承 OncePerRequestFilter 保证过滤器里的逻辑在一个请求里只会被过滤一次
 * 在SpringBoot里,任何实现了Filter接口的类,SpringBoot会自动把它加到web应用的过滤器链里,只要声名为Component就行了
 */
@Order(1)//执行顺序
@Component
public class RateLimitFilter extends OncePerRequestFilter {//


    //每秒1个请求的限流器
    private RateLimiter rateLimiter = RateLimiter.create(1);

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        System.err.println("++++流控++++");

        if (rateLimiter.tryAcquire()) {
            //如果没达到限流阈值,放行
            filterChain.doFilter(request, response);
        } else {
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());//429请过过多
            response.getWriter().write("too many request!");
            response.getWriter().flush();
            return ;
        }
    }
}

调用用户查询接口,使劲刷新,就返回429

这个是个简单的例子, 实际中的流控,比这个要复杂的多,比如可以根据用户来限流,VIP用户每秒500请求,普通用户每秒50请求,这样大量请求过来了,VIP用户没什么感觉可以正常访问,普通用户就被拒绝了。

代码:https://github.com/lhy1234/springcloud-security/tree/master/nb-user-api

++++++++++++++++++++++++分割线++++++++++++++++++++++++

小结:

1,流控概念:流量控制

2,流控位置:负载均衡、反向代理、应用逻辑

3,guava做简单的限流,对限流有个第一印象

 

 

12-24 11:59