redis实现高并发计数


本文摘自PHP中文网,作者尚,侵删。

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

1

2

3

4

5

6

7

8

9

10

11

/**

 * 是否拒绝服务

 * @return

 */

private boolean denialOfService(String userId){

    long count=JedisUtil.setIncr(DateUtil.getDate()+"&"+userId+"&"+"queryCarViolation", 86400);

    if(count<=10){

        return false;

    }

    return true;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

      /**

    * 查询违章

    * @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工具类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

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入门教程栏目。

以上就是redis实现高并发计数的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

Redis可以采用什么方式实现限流

连接Redis需要密码吗

Redis单线程为什么快

怎么查看Redis版本

Redis有多少个库

Redis安装新手教程(win10)

通过Redis实现服务器崩溃宕机的数据恢复

Redis在哪里配置缓存清理策略

10个Redis使用技巧

Redis集群需要设置哨兵吗

更多相关阅读请进入《Redis》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...