搜尋

首頁  >  問答  >  主體

Redis 如何限制簡訊發送

暫時不考慮 ip,什麼的限制,只考慮 手機號碼限制,

如何用redis做到限制,一個手機號,1分鐘內最多發一條,一天內最多10條

各位大神有什麼好方案,先謝! (崇拜臉)

迷茫迷茫2772 天前942

全部回覆(6)我來回復

  • 漂亮男人

    漂亮男人2017-04-27 09:05:05

    需要兩個快取

    1. key名稱 phone-busy,快取1分鐘

    2. key名稱 phone-send-count,快取1天,每成功發送一條+1

    發送的時候流程如下:

    1. 判斷phone-busy是否存在,存在直接報錯「發送過快」。

    2. 判斷phone-send-count是否存在,存在則繼續檢測是否等於10,存在且等於10報錯「您今天不能發送簡訊了」

    3. 發送簡訊

    4. 寫入phone-busy,有效期限1分鐘

    5. 寫入phone-send-count+1,有效期限當天23:59:59的時間戳-當前時間戳

    回覆
    0
  • PHPz

    PHPz2017-04-27 09:05:05

    用手機號碼+分鐘,手機號碼+天做為key分別限制一分鐘和一天內發送短信的數量

    回覆
    0
  • 我想大声告诉你

    我想大声告诉你2017-04-27 09:05:05

    1分鐘內最多發一條,用分鐘和手機號碼為key:min:201701041750:13888888888
    一天内最多10条,用日期和手机号号为key: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`内

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-27 09:05:05

    寫一段偽代碼如下:

    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;
    }

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-27 09:05:05

    第一個問題,設定過期時間就可以實現了,只要手機號碼存在於Redis,就是說明沒到1分鐘
    第二個問題,每次發送的時候更改一下計數器,將計數器過期時間設為一天

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-27 09:05:05

    簡單說明:

    1. 你要有兩個key

    2. 一個1分鐘過期的key

    3. 一個24h過期的key

    依照簡訊業務來處理,都是依照有效時長,不依照0點結算。

    回覆
    0
  • 取消回覆