Google的Guava是JDK补充的一个神器,值得好好学习。
一般Web系统的访问限制都可以用容器本身来实现,比如tomcat就可以在connector上面配置connection数目的限制,servlet thread限制。
有时候系统复杂后希望对不同服务提供不同的RateLimiter,例如对数据库操作要求比较大的速率小些,在内存可以处理的速率大写,还有可能对集群提供rate limiter服务。
如何限速是一个公共话题,相关的算法和实现都有一大堆,有兴趣可以看看Calvin的springside4 wiki关于这个章节的描述,写的非常棒。
这里记录下实践过程中系统如何使用RateLimiter来限制所有spring访问的访问速率,简单版,没有注入化ratelimiter需要的输入参数。
1. 定义Filter
public class RateLimiterFilter implements Filter {
private static Logger logger = Logger.getLogger(RateLimiterFilter.class);
private RateLimiter limiter = null;
public void init(FilterConfig config) throws ServletException {
limiter = RateLimiter.create(100); //100 request per second
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if(limiter.tryAcquire()) {
if(logger.isTraceEnabled()){
logger.trace("get access: ");
}
chain.doFilter(request, response)
} else {
logger.info("system limitation reached!");
req.getRequestDispatcher("/WEB-INF/jsp/error/429.jsp").forward(req,res);
}
}
}
2. 修改Web.xml
<filter>
<filter-name>ratelimiter</filter-name>
<filter-class>RateLimiterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ratelimiter</filter-name>
<servlet-name>springmvc</servlet-name>
</filter-mapping>
3. Maven中引入RateLimiter包
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
大功告成!
时间: 2024-10-06 14:57:37