Рубрики
Uncategorized

Ограниченная частота работы redis

Автор оригинала: David Wong.

В последнее время я увлекся развитием бизнеса и не могу освободиться. Я давно не обновлял свой блог. Я планирую поделиться практическими решениями или лучшими дизайнерскими идеями в некоторых бизнес-сценариях в последующем содержании блога. Не то чтобы я раньше тратил много времени на сортировку соответствующего контента по теме (сдерживая большие шаги). Содержание последующего блога может быть не таким богатым, но сделайте более подробный или углубленный анализ по какому-либо вопросу, насколько это возможно, посредством непрерывного обмена и самовосстановления, испытайте осадки и улучшите частоту обмена блогами.

сцена

Сцена 1
The message function is limited to 10 comments within 30 seconds. If the number of comments exceeds the limit, no more comments are allowed. The following prompt is given: too frequent
Сцена 2
The function of liking is limited. You can only like 10 times in 10 seconds. If you exceed the number, you can't like again. You can't operate for 1 hour. Prompt: too frequently, you can't operate for 1 hour.
Сцена 3
Upload the record function. It is limited to upload only 100 times a day. If the number is exceeded, it is not allowed to upload again, and the prompt is: go online beyond today

Суть вывода средств

В процессе развития бизнеса мы постоянно участвуем в разработке схем различных бизнес-сценариев, и легко столкнуться с очень похожими сценариями, но текущие бизнес – модули отличаются. По сути, суть этих требований заключается в решении одной и той же проблемы. Сталкиваясь с такими сценариями, нам необходимо проанализировать и выявить существенные проблемы требований в соответствии с нашим собственным опытом, чтобы достичь одного прохода. Используйте это решение, чтобы сделать ваше собственное решение более ценным, которое может отличаться от того, являетесь ли вы инженером души или сильнейшим королем CP (копипаст).

Проанализировав три вышеперечисленных бизнес-сценария, мы можем обнаружить, что существует схожая логика, которая называется проблемой того же рода. Теперь мы собираемся изолировать эту проблему, разработать общее решение и нарисовать ту же логическую блок-схему:

Анализируя вышеприведенные сценарии спроса, мы можем извлечь условия, в которых они все нуждаются:

  • Объекты с ограниченным доступом: пользователи
  • Ограничить действия (комментарии, лайки, записи,…)
  • Временной диапазон Х секунд
  • Ограничьте количество операндов в y раз
  • Запретить время работы Z после превышения (секунды/определенное время)
  • Не работайте после превышения и своевременно

(минимальная единица измерения времени-секунды: дни/часы/минуты могут быть преобразованы в секунды, и за секунды можно решить больше сценариев)

Если функция разделена на общую функцию, это примерно так:

php
/**
 *Frequency limit
 *@ param string $action action action
 *@ param int $userid the user ID that initiated the operation
 *@ param int $time time range X seconds
 *@ param int $number limit y operands
 *@ param array $expire exceeds the seal time Z ['type '= > 1,' TTL '= > expiration time / sec], ['type' = > 2, 'TTL' = > specific expiration time stamp] one of two options
 * @return bool
 * @throws \Exception
 */
public static function frequencyLimit(string $action, int $userId, int $time, int $number, $expire = [])
{
    //Todo controls the frequency and releases the failure according to the time range of user operation
}

Реализация решения

В функции нам нужно сохранить операцию и время, инициированные пользователем, а также накопленное время, и очистить срок действия. Если в настоящее время мы полагаемся на MySQL для хранения данных, об этом больно думать. Вот и главный герой: ред наконец-то выходит на сцену. На основе функции redis, атомарной операции incr и механизма истечения срока действия поддержки ключей. Преимущество в эффективности хранения данных в памяти может быть относительно простым. Гибкий и эффективный для достижения поставленной цели.

Вот простой код для реализации общей функции:

 1,' TTL '= > expiration time / sec], ['type' = > 2, 'TTL' = > specific expiration time stamp] one of two options
 * @return bool
 * @throws \Exception
 */
public function frequencyLimit(string $action, int $userId, int $time, int $number, $expire = [])
{
    if (empty($action) || $userId <= 0 || $time <= 0 || $number <= 0) {
        Throw new \ exception ('illegal parameter ');
    }
    $key = 'act:limit:' . $action . ':' . $userId;
    $r = RedisClient::connect();
    //Get current cumulative times
    $current = intval($r->get($key));
    if ($current >= $number) return false;
    //Accumulate and return the latest value
    $current = $r->incr($key);
    //For the first accumulation, set the effective time to control the operation frequency
    if ($current === 1) $r->expire($key, $time);
    //Pass before exceeding the limit
    if ($current < $number) return true;
    //After the expiration time is exceeded, reset the expiration time as needed $current = = = $number, judge and guarantee to reset only once.
    $type = empty($expire['type']) ? 0 : intval($expire['type']);
    $ttl = empty($expire['ttl']) ? 0 : intval($expire['ttl']);
    if ($current === $number && $ttl > 0 && in_array($type, [1, 2])) {
        if ($type === 1) $r->expire($key, $ttl);
        if ($type === 2) $r->expireAt($key, $ttl);
    }
    return false;
}
// scenario 1

/**
 *Comment restrictions
 * @param int $userId
 * @return bool|string
 */
public function doComment(int $userId)
{
    try {
        $pass = FrequencyLimit::doHandle('comment', $userId, 30, 10);
        If (! $pass) return 'is too frequent';
        //Todo comment logic
        return true;
    } catch (\Exception $e) {
        return $e->getMessage();
    }
}

// scenario 2
/**
 *Like limit
 * @param int $userId
 * @return bool|string
 */
public function doLike(int $userId)
{
    try {
        $pass = FrequencyLimit::doHandle('like', $userId, 10, 10, ['type' => 1, 'ttl' => 1 * 60 * 60]);
        If (! $pass) return 'is too frequent, operation is forbidden for 1 hour';
        //Todo likes logic
        return true;
    } catch (\Exception $e) {
        return $e->getMessage();
    }
}

// scenario 3

/**
 *Upload restrictions
 * @param int $userId
 * @return bool|string
 */
public function doUpload(int $userId)
{
    try {
        $expire = strtotime(date('Y-m-d', strtotime(+1 . 'days')));
        $pass = FrequencyLimit::doHandle('upload', $userId, 1 * 24 * 60 * 60, 100, ['type' => 2, 'ttl' => $expire]);
        If (! $pass) return 'is beyond today's online';
        //Todo upload logic
        return true;
    } catch (\Exception $e) {
        return $e->getMessage();
    }
}

// scenario N

Код может быть дополнительно абстрагирован в соответствии со сложностью вашего проекта этой общей схемы, например, абстрагирование в класс функций с ограниченной частотой и т.д.

резюме

  • Анализируйте схожие бизнес-сценарии, выявляйте существенные проблемы и разрабатывайте общие решения
  • Сделайте решение более ценным и станьте одухотворенным разработчиком
  • Освойте redis и в полной мере используйте его возможности и преимущества

Впервые запущен на GitHub. Добро пожаловать в звезду.

Оригинал: “https://developpaper.com/limited-operation-frequency-of-redis/”