1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| package com.caiyi.financial.nirvana.loan.filter;
import com.google.common.util.concurrent.RateLimiter; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
@WebFilter public class RateLimiterFilter implements Filter { private static Logger logger = LoggerFactory.getLogger(PrivilegeFilter.class);
static Map<String, RateLimiter> limiterMap = new ConcurrentHashMap<>();
@Override public void init(FilterConfig filterConfig) throws ServletException {
}
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String ip = getRemoteHost(httpServletRequest); RateLimiter limiterIp = limiterMap.get(ip); if (limiterIp == null) { limiterIp = RateLimiter.create(16.0); limiterMap.put(ip, limiterIp); logger.debug("IP个数:{}", limiterMap.size()); } else { limiterWithReturn(limiterIp, httpServletRequest, response); } }
@Override public void destroy() {
}
@SuppressWarnings("useless") private void limiterWithBlock(RateLimiter limiter, ServletRequest requestWrapper, ServletResponse servletResponse) { logger.info("实际接口访问频率:{}次/秒", limiter.acquire()); }
private void limiterWithReturn(RateLimiter limiter, HttpServletRequest request, ServletResponse servletResponse) throws IOException, ServletException { if (!limiter.tryAcquire()) { logger.warn("接口超频:{},rate:{},ip地址:{}", request.getRequestURI(), limiter.getRate(), getRemoteHost(request)); request.getRequestDispatcher("/error").forward(request, servletResponse); } }
public static String getRemoteHost(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; } }
|