Ich war in letzter Zeit besessen von der Geschäftsentwicklung und habe meinen Blog eine Weile nicht aktualisiert. Ich habe vor, in Zukunft einige praktische Lösungen in Geschäftsszenarien oder bessere Designideen aufzunehmen Das Teilen von Blog-Beiträgen ist nicht so, als würde man vorher viel Zeit damit verbringen, verwandte Inhalte zu einem Thema zu sortieren (wenn man den ultimativen Trick zurückhält). Der Inhalt des nachfolgenden Artikels ist möglicherweise nicht so umfangreich, kann aber in einem Punkt detaillierter sein so viel wie möglich oder eingehendere Analyse durch kontinuierliches Teilen und Selbstüberprüfung, Sammeln von Erfahrungen bei gleichzeitiger Erhöhung der Häufigkeit des Blog-Teilens
Szenario
Szenario 1
留言功能限制,30秒 内只能评论 10次,超出次数不让能再评论,并提示:过于频繁
Szenario 2
点赞功能限制,10秒 内只能点赞 10次,超出次数后不能再点赞,并禁止操作 1个小时,提示:过于频繁,被禁止操作1小时
Szene 3
上传记录功能,限制一天只能上传 100次,超出次数不让能再上传,并提示:超出今日上线
Abstraktion vom Wesentlichen
Im Prozess der Geschäftsentwicklung sind wir ständig an der Gestaltung verschiedener Geschäftsszenarien beteiligt, und Es ist oft leicht, auf sehr ähnliche Lösungsszenarien zu stoßen, aber die Geschäftsmodule, zu denen sie derzeit gehören, sind tatsächlich unterschiedlich. Der Kern dieser Anforderungen besteht darin, das gleiche Problem zu lösen Die Anforderungen basieren auf unserer eigenen Erfahrungsanalyse und implementieren eine universelle Lösung, die Ihre Lösungen wertvoller macht. Dies kann den Unterschied zwischen Ihnen als Ingenieur mit Seele oder dem stärksten CP-König (Kopieren und Einfügen) ausmachen.
Bei der Analyse der oben genannten drei Geschäftsszenarien können wir feststellen, dass sie eine ähnliche Logik haben und sie als ähnliche Probleme bezeichnen. Jetzt werden wir dieses Problem isolieren, eine allgemeine Lösung entwerfen und das gleiche Logikflussdiagramm skizzieren:
Durch die Analyse der oben genannten Nachfrageszenarien können wir die Bedingungen extrahieren, die sie alle benötigen:
Eingeschränkte Objekte: Benutzereingeschränkte Vorgänge (Kommentare, Likes), Aufzeichnung, ...) Die Anzahl der Operationen innerhalb des Zeitbereichs
(最小时间单位用秒:天/小时/分钟都可换算成秒,用秒可以解决更多的场景)
<?php/** * 频率限制 * @param string $action 操作动作 * @param int $userId 发起操作的用户ID * @param int $time 时间范围X秒内 * @param int $number 限制操作数Y次 * @param array $expire 超出封印时间Z ['type'=>1,'ttl'=>过期时间/秒] ['type'=>2,'ttl'=>具体过期时间戳] 二选一 * @return bool * @throws \Exception */public static function frequencyLimit(string $action, int $userId, int $time, int $number, $expire = []){ // todo 根据用户操作动作时间范围,进行频率的控制和失效释放}
Die Die Funktion muss die vom Benutzer initiierten Vorgänge sowie die kumulative Anzahl an Speichervorgängen ausführen und den Ablauf bereinigen. Wenn wir uns zu diesem Zeitpunkt auf MySQL verlassen, wird es ziemlich schmerzhaft sein, darüber nachzudenken Der Protagonist hier: Basierend auf den Eigenschaften von Redis können der Ablaufmechanismus und der Schlüssel den Zweck relativ einfach, flexibel und effizient unterstützen.
Hier ist ein Code, der einfach eine allgemeine Funktion implementiert:
<?php/** * 频率限制 * @param string $action 操作动作 * @param int $userId 发起操作的用户ID * @param int $time 时间范围X秒内 * @param int $number 限制操作数Y次 * @param array $expire 超出封印时间Z ['type'=>1,'ttl'=>过期时间/秒] ['type'=>2,'ttl'=>具体过期时间戳] 二选一 * @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('非法参数'); } $key = 'act:limit:' . $action . ':' . $userId; $r = RedisClient::connect(); //获取当前累计次数 $current = intval($r->get($key)); if ($current >= $number) return false; //累计并返回最新值 $current = $r->incr($key); //第一次累加,设置控制操作频率的有效时间 if ($current === 1) $r->expire($key, $time); //未超出限制次数先放过 if ($current < $number) return true; //超出后根据需要重新设置过期失效时间 $current === $number 判断保证只重新设置一次 $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; }//场景1/** * 评论限制 * @param int $userId * @return bool|string */public function doComment(int $userId){ try { $pass = FrequencyLimit::doHandle('comment', $userId, 30, 10); if (!$pass) return '过于频繁'; // todo 评论逻辑 return true; } catch (\Exception $e) { return $e->getMessage(); } }//场景2/** * 点赞限制 * @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 '过于频繁,被禁止操作1小时'; // todo 点赞逻辑 return true; } catch (\Exception $e) { return $e->getMessage(); } }//场景3/** * 上传限制 * @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 '超出今日上线'; // todo 上传逻辑 return true; } catch (\Exception $e) { return $e->getMessage(); } }//场景N
编码上可以根据你设计这个通用方案的复杂度进行进一步抽象,如抽象成频率限制的功能类等
Zusammenfassung
Ähnliche Geschäftsszenarien analysieren, wesentliche Probleme entdecken und allgemeine Lösungen entwerfen
Machen Lösungen wertvoller machen und ein Entwickler mit Seele sein
Beherrschen Sie Redis und nutzen Sie seine Funktionen und Vorteile voll aus
Weitere technische Artikel zu Redis finden Sie unter
Redis-TutorialKolumne zum Lernen!
Das obige ist der detaillierte Inhalt vonRedis ist die tatsächliche Häufigkeit von Kampfeinsätzen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!