利用Redis实现高并发计数器

利用Redis实现高并发计数器业务需求中经常有需要用到计数器的场景:譬如一个手机号一天限制发送5条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。使用Redis的Incr自增命令可以轻松实现以上需求。以一个接口一天限制调用次数为例: /** *是否拒绝服务 *@return */ privatebooleandenialOfService(StringuserId){ longc…

大家好,又见面了,我是你们的朋友全栈君。

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

	/**
	 * 是否拒绝服务
	 * @return
	 */
	private boolean denialOfService(String userId){
		long count=JedisUtil.setIncr(DateUtil.getDate()+"&"+userId+"&"+"queryCarViolation", 86400);
		if(count<=10){
			return false;
		}
		return true;
	}
       /**
	 * 查询违章
	 * @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 (result<=1 && 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;
	}
}	
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141991.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 宝塔分销源码_云进销存ERP开发教程

    宝塔分销源码_云进销存ERP开发教程大家好啊,我是测评君,欢迎来到web测评。本期给大家带来一套电商ERP进销存系统源码。运行环境服务器宝塔面板PHP5.6Mysql5.6LinuxCentos7以上文字教程下载源码,宝塔添加一个站点,创建一个数据库,导入数据库文件目录下的taoydm.sql修改数据库链接文件application\config\database.php(记得不要用记事本修改,否则可能会出现验证码显示不了问题,建议用Notepad++)压缩codes目录下的源码上传到宝塔新建网站的根目录后解压缩默认后

    2022年9月20日
    3
  • 分子模拟软件amber_分子模拟周刊: 第 23 期

    分子模拟软件amber_分子模拟周刊: 第 23 期■2020-06-1221:34:10每周杂记:谢谢记得父亲突然联系我,说,我初中的班主任让我发一张照片,同时写一段自我介绍用来给他们现在的学生做榜样.这让我大感意外.这些老师都已经近30年未见过面了,竟还记得我?再说,以我现在这样的境况,用来给人做榜样是不是有点难堪?其实这个老师并不是我初中时候的班主任,是我的语文老师.他人长得很高大,声音洪亮,性格粗线条…

    2022年5月26日
    156
  • ICMP报文类型

    ICMP报文类型日常开发中,我们经常会碰到查询网络是否畅通以及域名对应IP地址等小需求,这时候用的最多的应该就是ping命令了。那你知道ping命令是怎么工作的吗?今天,我们就来一起认识下ping命令及其对应的ICMP协议。ICMP协议ICMP全称InternetControlMessageProtocol,指互联网控制报文协议。网络本身是不可靠的,数据包在传输过程中,可能会发生很多突发事件并导致数据传输失败。而网络层的IP协议是一个无连接的协议,它不会处理网络层的故障,因此,我

    2022年4月30日
    50
  • 关于allow_url_fopen的设置与服务器的安全

    关于allow_url_fopen的设置与服务器的安全allow_url_fopen与安全以及PHPlibcurl  allow_url_fopen=ON常常会给服务器和管理员带来麻烦,但是经常性(至少我这样认为)的我们需要远程读取某个东西,如果设置allow_url_fopen=OFF将其关闭,我们就没有办法远程读取。  幸好我们有一个很好的PHP模块–curl。下面我就以一个例子说说我用curl远程读取的方法:  第一,allow_url_fopen=ON的情况下:<?php$str=file_get_contents(“http:

    2022年7月16日
    17
  • qmake的使用

    qmake的使用前言在linux环境下进行程序开发时,经常需要使用makefile管理编译代码,特别是一些大型工程,而makefile工具语法晦涩深入研究较为困难,好在有很多工具可以自动生成makefile,qmake就是其中的一种。qmake特点为不同的平台的开发项目创建makefile。可以供给任何一个软件项目使用,而不用管它是不是用Qt写的,尽管它包含了为支持Qt开发所拥有的额外的特征。…

    2022年5月19日
    169

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号