springmvc implements website current limiting (HandlerInterceptorAdapter interceptor)

Helper class to store the number of visits per request
public class AccessCounts {  
  
    public static final String CALLPATH = "AccessCounts.CALLPATH";  
      
    private ConcurrentHashMap<Object, AtomicInteger> map = new ConcurrentHashMap<Object, AtomicInteger>();  
    private AccessCounts() {  
    }  
      
    private static class Instance {  
        static AccessCounts counts = new AccessCounts();  
    }  
      
    public static AccessCounts getInstance() {  
        return Instance.counts;  
    }  
      
    public int get(Object key) {  
        AtomicInteger counter = map.get(key);  
        if (counter == null) {  
            counter = new AtomicInteger(0);  
            map.put(key, counter);  
        }  
        return counter.intValue();  
    }  
      
    public int incrementAndGet(Object key) {  
        AtomicInteger counter = map.get(key);  
        if (counter == null) {  
            counter = new AtomicInteger(0);  
            map.put(key, counter);  
        }  
        return counter.incrementAndGet();  
    }  
      
    public int decrementAndGet(Object key) {  
        AtomicInteger counter = map.get(key);  
        if (counter == null) {  
            return 0;  
        }  
        return counter.decrementAndGet();  
    }  
      
    public String status(){  
        return map.toString();  
    }  
}  


interceptor
/**  
 *Current limiting blocker  
 **/  
public class InServiceAccessInterceptor extends HandlerInterceptorAdapter {  
  
    private static final Logger logger = Logger.getLogger (InServiceAccessInterceptor.class);  
  
    private ConcurrentHashMap<String, Integer> config = new ConcurrentHashMap<String, Integer>();  
      
    // setting  
    private int defaultLimit = 100;  
      
    private String configUrl = null;  
    private int loadInterval = 1, loadDelay=5;  
    private boolean valid;  
      
    public InServiceAccessInterceptor(int defaultLimit, String configUrl, int loadInterval, int loadDelay, boolean valid) {  
        this.defaultLimit = defaultLimit;  
        this.configUrl = configUrl;  
        this.loadInterval = loadInterval;  
        this.loadDelay = loadDelay;  
        this.valid = valid;  
        if(valid){  
            task();  
        }  
    }  
      
    //before the actual handler will be executed  
    @Override  
    public boolean preHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler) throws Exception {  
        if(valid){  
            if(handler instanceof HandlerMethod){  
                HandlerMethod handlerMethod = (HandlerMethod) handler;  
                String callpath = handlerMethod.getMethod().getDeclaringClass().getSimpleName()+"."+handlerMethod.getMethod().getName();  
                System.out.println(callpath);  
                int counter = AccessCounts.getInstance().get(callpath);  
                boolean limit = limit(callpath, counter);  
                if (limit) {  
                    throw new IllegalAccessException("Flowing Limit." + callpath + "=" +counter );  
                }  
                MDC.put(AccessCounts.CALLPATH, callpath);  
                AccessCounts.getInstance().incrementAndGet(callpath);  
            }  
        }  
        return true;  
    }  
      
    //after the handler is executed  
    @Override  
    public void postHandle(HttpServletRequest request,  
            HttpServletResponse response, Object handler,  
            ModelAndView modelAndView) throws Exception {  
        if(valid){  
            Object callpath = MDC.get(AccessCounts.CALLPATH);  
            if (null != callpath) {  
                AccessCounts.getInstance().decrementAndGet( callpath);  
            }  
            MDC.remove(AccessCounts.CALLPATH);  
        }  
    }  
      
    @Override  
    public void afterCompletion(HttpServletRequest request,  
            HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
        // TODO Auto-generated method stub  
          
    }  
      
    private boolean limit(String callpath, int counter) {  
  
        Integer obj = config.get(callpath);  
        int limit = defaultLimit;  
        if (obj != null) {  
            limit = obj.intValue();  
        }  
        if (logger.isDebugEnabled() ) {  
            logger.debug("check callpath:" + callpath + " limit:" + limit);  
        }  
        if (counter >= limit) {  
            logger.warn("the call[" + callpath + "] is over limit:" + limit + " counter:" + counter);  
            return true;  
        }  
        return false;  
    }  
  
    public static String sendGet(String url, String param) {  
        String result = "";  
        BufferedReader in = null;  
        try {  
            String urlNameString = url + (param == null ? "" : "?" + param);  
            URL realUrl = new URL(urlNameString);  
            // open the connection to the URL  
            URLConnection connection = realUrl.openConnection();  
            // Set common request attributes  
            connection.setRequestProperty("accept", "*/*");  
            connection.setRequestProperty("connection", "Keep-Alive");  
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
            // establish the actual connection  
            connection.connect();  
            // Get all response header fields  
            /*Map<String, List<String>> map = connection.getHeaderFields();  
            for (String key : map.keySet()) {  
                System.out.println(key + "--->" + map.get(key));  
            }*/  
            // Define the BufferedReader input stream to read the response from the URL  
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));  
            String line;  
            while ((line = in.readLine()) != null) {  
                result += line;  
            }  
        } catch (Exception e) {  
            logger.error("request url fail="+url, e);  
        }  
        // use finally block to close the input stream  
        finally {  
            try {  
                if (in != null) {  
                    in.close();  
                }  
            } catch (Exception e) {  
            }  
        }  
        return result;  
    }  
      
    public void task() {  
        TimerTask task = new TimerTask() {    
            @Override    
            public void run() {   
                if (null == configUrl ) return;  
                String text = sendGet(configUrl, null);  
                logger.info("load config:" + text );  
                if ( null == text || "".equals(text.trim())) return;  
                  
                text = text.replaceAll("[\\{\\}\"\n]", "");  
                config.clear();  
                for (String line : text.split(",")) {  
                    String fields[] = line.split(":");  
                    if ( fields.length < 2) continue;  
                    try {  
                        config.put(fields[0].trim(), Integer.valueOf(fields[1].trim()));  
                    } catch (Exception e) {  
                        logger.error("load config fail.", e);  
                    }  
                }  
            }  
        };  
        Timer timer = new Timer ();    
        long delay = 1000 * loadDelay;    
        long intevalPeriod = 1000 * loadInterval;    
        // schedules the task to be run in an interval    
        logger.info("Task setting  delay:" + delay + "  intevalPeriod:" + intevalPeriod);  
        timer.scheduleAtFixedRate(task, delay, intevalPeriod);   
          
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                while (true) {  
                    try {  
                        Thread.sleep(60*1000);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace ();  
                    }  
                    System.out.println("AccessCounts status:" + AccessCounts.getInstance().status());  
                }  
            }  
        }).start();  
  
    }  
      
  
}  


xml placement
<mvc:interceptors>  
        <mvc:interceptor>  
            <mvc:mapping path="/**" />  
            <beans:bean class="xxx.xxx.xxx.intercept.InServiceAccessInterceptor">  
                <beans:constructor-arg index="0" value="1000" /> <!-- defaultLimit default setting-->  
                <beans:constructor-arg index="1" value="http://localhost/web.limit" /> <!-- configUrl    -->  
                <beans:constructor-arg index="2" value="60" /> <!-- loadInterval unit : second -->  
                <beans:constructor-arg index="3" value="5" /> <!-- loadDelay unit : second -->  
                <beans:constructor-arg index="4" value="false" /> <!-- valid  true: used -->  
            </beans:bean>  
        </mvc:interceptor>  
</mvc:interceptors>  


http://localhost/web.limit文件
{"IndexController.index":500,
"ProductController.searchProducts":500
}

http://blog.csdn.net/soleave/article/details/50388549
http://blog.csdn.net/ye_sheng/article/details/48395663
http://www.cnblogs.com/sunp823/p/5601396.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326396954&siteId=291194637