Interface current limiting through counters

If the interface may have sudden access, but you are worried that the system will crash due to the large amount of access, you need to limit the number of concurrent requests for the interface. The corresponding threshold can be set for the corresponding interface, if the threshold is exceeded, the request will be rejected or queued.

 

1. Use the classes under the concurrent package that comes with java to limit the current. The sample code is as follows:

	private static final AtomicLong atomic = new AtomicLong(0);
	
	public static void limitByAtomic(String hello)throws Exception{		
		try{
			if(atomic.incrementAndGet() > 2){
				// reject the request
			}			
			// handle the request			
		}finally{
			atomic.decrementAndGet();
		}	
	}

 

2. Use guava's Cache to limit the current. The sample code is as follows:

	public static void limitByCounter(String hello)throws Exception{
		LoadingCache<Long, AtomicLong> counter =
				CacheBuilder.newBuilder()
				.expireAfterWrite(2, TimeUnit.SECONDS)
				.build(new CacheLoader<Long, AtomicLong>(){
					@Override
					public AtomicLong load(Long seconds) throws Exception {
						return new AtomicLong(0);
					}					
				});
		
		long limit = 1000;

		while(true){
			long currentSeconds = System.currentTimeMillis() / 1000;
			if(counter.get(currentSeconds).incrementAndGet() > limit){
				// reject the request
				continue;
			}
			// handle business
		}				
	}

 

The following is a simplified version of the overrun counter implemented by Guava's Cache

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

/**
 * Guava counter tool class
 *
 * @author lh
 * @version 2.0
 * @since 2017-06-22
 *
 */
public class GuavaCounterUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(GuavaCounterUtil.class);

	private static final LoadingCache<String, AtomicLong> counter = CacheBuilder.newBuilder()
			.expireAfterWrite(2, TimeUnit.SECONDS)//Clear every two seconds
			.build(new CacheLoader<String, AtomicLong>() {
				@Override
				public AtomicLong load(String seconds) throws Exception {
					return new AtomicLong(0);
				}
			});

	/**
	 * Whether the request exceeds the limit
	 *
	 * @param uri
	 * Request address (interface address or other identifiable characters)
	 * @param limit
	 * The number of requests per second limit
	 * @return
	 */
	public static final boolean overLimit(String uri, long limit) {

		long currentSeconds = System.currentTimeMillis() / 1000;
		try {
			return counter.get(uri + currentSeconds).incrementAndGet() > limit;
		} catch (ExecutionException e) {
			LOGGER.warn(e.getMessage(), e);
		}
		return false;
	}

}

 

Guess you like

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