redis实现高并发计数

redis实现高并发计数

业务需求中经常有需要用到计数器的场景:譬如一个手机号一天限制发送5条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。使用redis的Incr自增命令可以轻松实现以上需求。以一个接口一天限制调用次数为例:

	/** 	 * 是否拒绝服务 	 * @return 	 */ 	private boolean denialOfService(String userId){ 		long count=JedisUtil.setIncr(DateUtil.getDate()+"&amp;"+userId+"&amp;"+"queryCarViolation", 86400); 		if(count<pre class="brush:php;toolbar:false">       /** 	 * 查询违章 	 * @param plateNumber车牌 	 * @param vin 车架号 	 * @param engineNo发动机 	 * @param request 	 * @param response 	 * @throws Exception 	 */ 	@RequestMapping("/queryCarViolationList.json") 	@AuthorizationApi 	public void queryCarViolationList(@CurrentToken Token token,String plateNumber,String vin,         String engineNo,HttpServletRequest request,HttpServletResponse response) throws Exception { 	    String userId=token.getUserId();             //超过限制,拦截请求       if(denialOfService(userId)){ 		  apiData(request, response, ReqJson.error(CarError.ONLY_5_TIMES_A_DAY_CAN_BE_FOUND)); 		  return; 	    } 		//没超过限制,业务逻辑……  }

每次调用接口之前,先获得下计数器自增后的值,如果小于限制,放行,执行后面的代码。如果大于限制,则拦截掉。

JedisUtil工具类:

public class JedisUtil { 	protected final static Logger logger = Logger.getLogger(JedisUtil.class); 	private static  JedisPool jedisPool; 	 	@Autowired(required = true) 	public void setJedisPool(JedisPool jedisPool) { 		JedisUtil.jedisPool = jedisPool; 	} 	/** 	 * 对某个键的值自增 	 * @author liboyi 	 * @param key 键 	 * @param cacheSeconds 超时时间,0为不超时 	 * @return 	 */ 	public static long setIncr(String key, int cacheSeconds) { 		long result = 0; 		Jedis jedis = null; 		try { 			jedis = jedisPool.getResource(); 			result =jedis.incr(key); 			if (cacheSeconds != 0) { 			 jedis.expire(key, cacheSeconds); 			} 			logger.debug("set "+ key + " = " + result); 		} catch (Exception e) { 			logger.warn("set "+ key + " = " + result); 		} finally { 			jedisPool.returnResource(jedis); 		} 		return result; 	} }	

更多redis知识请关注redis入门教程栏目。

以上就是

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享