訪問次數控制實現思路

對某些資源要控制訪問次數,通常的思路統計時間段訪問達到限制次數,這種時段是固定的,好比說1分鐘的時間段,有多是這樣的: java

12:01至12:02
12:02至12:03
12:03至12:04
....
這樣統計出來的數據,嚴格來講是不太正確的。其實,我所理解時間段是沒有固定的開始和結束點,這兩點應該是隨着時間不斷前進的。可是,基於這種時間段實現很是困難。不過能夠把大的時間段分割成小的時間段,  這樣統計出來的數據相對正確。代碼以下:
post

@Test
	public void testCounter(){
		
		while(true){
			
			accessControl("post/message",1000, 10 , 200);//1000ms訪問次數不能超過200次   
			
		}
		
		
		
	}
	
	/**
	 *  precision越高越精確
	 * 
	 * 單位 毫秒   
	 * @param path  
	 * @param interval  時間段
	 * @param precision  精確度 
	 * @param control 最大訪問次數
	 */
	private  void  accessControl(String path  , long interval , long  precision , int control ){
		
		
		long now  = System.currentTimeMillis()  ;
		
		
		long pow  =  (now / precision)  *  precision ;
		
		String key  =  path+"_"+pow ;
		
		boolean keyExists = client.keyExists(key ) ;
		
		
		
		if(keyExists){
			client.incr(key, 1l);
		}else{
			Date expire  = new Date(now + interval);
			client.set(key	, "1" , expire ) ;
		}
		
		
		int keySize  = (int)(interval/precision) ;
		
		String [] keys  = new String[keySize] ;
		
		
		for(int i = 1 ; i <= keySize ; i++ ){
			keys[i-1] = path+"_"+(  pow - i * precision) ;
		}
		
		Map<String, Object> multi = client.getMulti(keys) ;
		
		int num = 0 ;
		
		
		for(Object value  : multi.values() ){
			if(value != null ){
				num += Integer.valueOf(String.valueOf(value))  ;
			}
		}
		
		
		if(control <= num ){
			throw new RuntimeException("訪問次數過多");
		}
		
		
	}
相關文章
相關標籤/搜索