84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
暂时不考虑 ip,什么的限制,只考虑 手机号限制,
ip
如何用redis做到限制,一个手机号,1分钟内最多发一条,一天内最多10条
redis
各位大神有什么好方案,先谢!(崇拜脸)
业精于勤,荒于嬉;行成于思,毁于随。
需要两个缓存
key名称 phone-busy,缓存1分钟
key名称 phone-send-count,缓存1天,每成功发送一条+1
发送的时候流程如下:
判断phone-busy是否存在,存在直接报错“发送过快”。
判断phone-send-count是否存在,存在则继续检测是否等于10,存在且等于10报错“您今天不能发送短信了”
发送短信
写入phone-busy,有效期1分钟
写入phone-send-count+1,有效期当天23:59:59的时间戳-当前时间戳
用手机号+分钟,手机号+天做为key分别限制一分钟和一天内发送短信的数量
1分钟内最多发一条,用分钟和手机号为key:min:201701041750:13888888888一天内最多10条,用日期和手机号号为key:day:20170104:13888888888
min:201701041750:13888888888
day:20170104:13888888888
//php demo function check($phone){ if($redis->exists('min:'.date('YmdHi').':'.$phone) || $redis->get('day:'.date('YmdHi').':'.$phone) > 10){ reutrn false; } $redis->set('min:'.date('YmdHi').':'.$phone,1); $redis->incr('day:'.date('Ymd').':'.$phone); return true; } // 这样按分钟生成的key比较多,可以把手机号对应的分钟放`set`内
写一段伪代码如下:
String sendFrequencyKeyPrefix = "send_frequency_"; String dailySendLimitKeyPrefix = "daily_send_limit_"; public function sendMessage(String phoneNumber, String message){ if(redis.get((sendFrequencyKeyPrefix + phoneNumber))) { return false; } int dailySendTotal = int(redis.get((dailySendLimitKeyPrefix + phoneNumber))); if(dailySendTotal >= 10) { return false; } // send message here redis.set((sendFrequencyKeyPrefix + $phoneNumber), "", 60); redis.set((dailySendLimitKeyPrefix + $phoneNumber), dailySendTotal + 1, 3600*24); return true; }
大概意思就是这样了,可以将一分钟,一天的发送限制做成配置文件,灵活多变。
1月5日修改;
这里@Lowky 朋友提醒了一个问题,就是每天这个限制,到底是一天还是24小时,因为这两个概念是不一样的。这里楼主要的应该是每天限制10条,每天凌晨限制放开。每分钟应该就不考虑这个了。code修改如下:
String sendFrequencyKeyPrefix = "send_frequency_"; public function sendMessage(String phoneNumber, String message){ String dailySendLimitKeyPrefix = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); if(redis.get((sendFrequencyKeyPrefix + phoneNumber))) { return false; } int dailySendTotal = int(redis.get((dailySendLimitKeyPrefix + phoneNumber))); if(dailySendTotal >= 10) { return false; } // send message here redis.set((sendFrequencyKeyPrefix + $phoneNumber), "", 60); redis.set((dailySendLimitKeyPrefix + $phoneNumber), dailySendTotal + 1, 3600*24); return true; }
第一个问题,设置过期时间就可以实现了,只要手机号存在于Redis,就是说明没到1分钟第二个问题,每次发送的时候更改一下计数器,将计数器过期时间设为一天
简单说明:
你要有两个key
一个1分钟过期的key
一个24h过期的key
按照短信业务来处理,都是按照有效时长,不按照0点结算。
需要两个缓存
key名称 phone-busy,缓存1分钟
key名称 phone-send-count,缓存1天,每成功发送一条+1
发送的时候流程如下:
判断phone-busy是否存在,存在直接报错“发送过快”。
判断phone-send-count是否存在,存在则继续检测是否等于10,存在且等于10报错“您今天不能发送短信了”
发送短信
写入phone-busy,有效期1分钟
写入phone-send-count+1,有效期当天23:59:59的时间戳-当前时间戳
用手机号+分钟,手机号+天做为key分别限制一分钟和一天内发送短信的数量
1分钟内最多发一条,用分钟和手机号为key:
min:201701041750:13888888888
一天内最多10条,用日期和手机号号为key:
day:20170104:13888888888
写一段伪代码如下:
大概意思就是这样了,可以将一分钟,一天的发送限制做成配置文件,灵活多变。
1月5日修改;
这里@Lowky 朋友提醒了一个问题,就是每天这个限制,到底是一天还是24小时,因为这两个概念是不一样的。这里楼主要的应该是每天限制10条,每天凌晨限制放开。每分钟应该就不考虑这个了。code修改如下:
第一个问题,设置过期时间就可以实现了,只要手机号存在于Redis,就是说明没到1分钟
第二个问题,每次发送的时候更改一下计数器,将计数器过期时间设为一天
简单说明:
你要有两个key
一个1分钟过期的key
一个24h过期的key
按照短信业务来处理,都是按照有效时长,不按照0点结算。