这几篇将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做简单的限流,对限流有个第一印象