{"id":43915,"date":"2024-12-01T10:15:03","date_gmt":"2024-12-01T02:15:03","guid":{"rendered":"https:\/\/fwq.ai\/blog\/43915\/"},"modified":"2024-12-01T10:15:03","modified_gmt":"2024-12-01T02:15:03","slug":"%e5%9f%ba%e4%ba%8eredis-zset%e5%ae%9e%e7%8e%b0%e6%bb%91%e5%8a%a8%e7%aa%97%e5%8f%a3%e5%af%b9%e7%9f%ad%e4%bf%a1%e8%bf%9b%e8%a1%8c%e9%98%b2%e5%88%b7%e9%99%90%e6%b5%81%e7%9a%84%e9%97%ae%e9%a2%98","status":"publish","type":"post","link":"https:\/\/fwq.ai\/blog\/43915\/","title":{"rendered":"\u57fa\u4e8eRedis\u00a0zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898"},"content":{"rendered":"<p><b><\/b> <\/p>\n<h1>\u57fa\u4e8eRedis&nbsp;zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898<\/h1>\n<p><span><i><\/i>0\u6d4f\u89c8<\/span><br \/>\n<span style=\"cursor: pointer\"><i><\/i>\u6536\u85cf<\/span> <\/p>\n<p>\u672c\u7bc7\u6587\u7ae0\u5411\u5927\u5bb6\u4ecb\u7ecd\u300a\u57fa\u4e8eRedis&nbsp;zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898\u300b\uff0c\u4e3b\u8981\u5305\u62ec\u9650\u6d41\u3001\u7a97\u53e3\u3001rediszset\u3001\u6ed1\u52a8\uff0c\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u8003\u4ef7\u503c\uff0c\u9700\u8981\u7684\u670b\u53cb\u53ef\u4ee5\u53c2\u8003\u4e00\u4e0b\u3002<\/p>\n<pre>public void checkCurrentWindowValue(String telNum) {\n        \n        String windowKey = CommonConstant.getNnSmsWindowKey(telNum);\n        \/\/\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u6233\n        long currentTime = System.currentTimeMillis();\n        \/\/1\u5c0f\u65f6\uff0c\u9ed8\u8ba4\u53ea\u80fd\u53d15\u6b21\uff0c\u53c2\u6570smsWindowMax\u505a\u6210\u53ef\u914d\u7f6e\u9879\uff0c\u914d\u7f6e\u5230Nacos\u914d\u7f6e\u4e2d\u5fc3\uff0c\u53ef\u4ee5\u52a8\u6001\u8c03\u6574\n        if (RedisUtil.hasKey(windowKey)) {\n            \/\/\u53c2\u6570smsWindowTime\u8868\u793a\u9650\u5236\u7684\u7a97\u53e3\u65f6\u95f4\n            \/\/\u8fd9\u91cc\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u4e0e\u9650\u5236\u7a97\u53e3\u65f6\u95f4\u4e4b\u95f4\u7684\u77ed\u4fe1\u53d1\u9001\u6b21\u6570\n            Optional\n   \n     optional = Optional.ofNullable(RedisUtil.zCount(windowKey, currentTime - smsWindowTime, currentTime));\n            if (optional.isPresent()) {\n                long count = optional.get();\n                if (count &gt;= smsWindowMax) {\n                    log.error(\"==========&gt;\u5f53\u524d\u53f7\u7801\uff1a{} \u77ed\u4fe1\u53d1\u9001\u592a\u9891\u7e41\uff0c{}\", telNum, count);\n                    throw new ServiceException(MidRetCode.umid_10060);\n                }\n            }\n        }\n        StringBuilder sb =new StringBuilder();\n        String windowEle = sb.append(telNum).append(\":\").append(currentTime).toString();\n        \/\/\u6dfb\u52a0\u5f53\u524d\u53d1\u9001\u5143\u7d20\u5230zSet\u4e2d(\u7531\u4e8e\u4fdd\u8bc1\u5143\u7d20\u552f\u4e00\uff0c\u8fd9\u91cc\u5c06\u5143\u7d20\u52a0\u4e0a\u4e86\u5f53\u524d\u65f6\u95f4\u6233)\n        RedisUtil.zAdd(windowKey, windowEle, currentTime);\n        \/\/\u8bbe\u7f6e2\u500d\u7a97\u53e3Key\uff1awindowKey \u7684\u8fc7\u671f\u65f6\u95f4\n        RedisUtil.expire(windowKey, smsWindowTime*2, TimeUnit.MILLISECONDS);\n    }\n   <\/pre>\n<p><strong><span style=\"color:#e74c3c\">\u8865\u5145\uff1a\u4e0b\u9762\u770b\u4e0b\u4ee5php\u8bed\u8a00\u4e3a\u4f8b\u57fa\u4e8eredis\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5f0f\u7684\u77ed\u4fe1\u53d1\u9001\u63a5\u53e3\u9650\u6d41<\/span><\/strong><\/p>\n<p>\u6ed1\u52a8\u7a97\u53e3\u77ed\u4fe1\u53d1\u9001\u9650\u6d41\u7b97\u6cd5<\/p>\n<p>1.\u6709\u4e24\u6761\u89c4\u5219<\/p>\n<p>\u57fa\u4e8eIP\u7684\u9650\u5236\u548c\u57fa\u4e8e\u624b\u673a\u53f7\u7684\u9650\u5236<\/p>\n<p>IP\u89c4\u5219:<\/p>\n<p>1\u5206\u949f\u9650\u52365<\/p>\n<p>10\u5206\u949f\u9650\u523630<\/p>\n<p>1\u5c0f\u65f6\u9650\u523650<\/p>\n<p>\u624b\u673a\u53f7\u89c4\u5219:<\/p>\n<p>1\u5206\u949f\u9650\u52361<\/p>\n<p>10\u5206\u949f\u9650\u52365<\/p>\n<p>1\u5c0f\u65f6\u9650\u523610<\/p>\n<p>2.\u6ed1\u52a8\u7a97\u53e3\u5c31\u662f\u968f\u7740\u65f6\u95f4\u7684\u6d41\u52a8 , \u8fdb\u884c\u52a8\u6001\u7684\u5220\u51cf\u533a\u95f4\u5185\u7684\u6570\u636e , \u9650\u5236\u65f6\u83b7\u53d6\u533a\u95f4\u5185\u7684\u6570\u636e<\/p>\n<p>\u6700\u4e3b\u8981\u7684\u662f\u7528\u5230\u4e86redis\u7684zRemRangeByScore\u6765\u8fdb\u884c\u5220\u9664\u533a\u95f4\u5916\u7684\u6570\u636e<\/p>\n<pre>\n   5,\n    600=&gt;30,\n    3600=&gt;50\n);\n\/\/\u624b\u673a\u53f7\u89c4\u5219\n$phoneRules=array(\n    60=&gt;1,\n    600=&gt;5,\n    3600=&gt;10\n);\n\n$r = checkLimits($ipRules,$_SERVER[\"REMOTE_ADDR\"],$_GET['tel']);\nvar_dump($r);\n\n$r = checkLimits($phoneRules,$_GET['tel'],$_GET['tel']);\nvar_dump($r);\n\nfunction checkLimits($rules,$key,$tel){\n    $redis = new Redis();\n    $redis-&gt;connect('115.159.28.111', 1991);\n    foreach($rules as $ruleTime=&gt;$rule) {\n        $redisKey=$key.\"_\".$ruleTime;\n        $score=time();\n        $member=$tel.'_'.$score;\n        $redis-&gt;multi();\n        $redis-&gt;zRemRangeByScore($redisKey, 0, $score - $ruleTime);\/\/\u79fb\u9664\u7a97\u53e3\u4ee5\u5916\u7684\u6570\u636e\n        $redis-&gt;zAdd($redisKey, $score, $member);\n        $redis-&gt;expire($redisKey, $ruleTime);\n        $redis-&gt;zRange($redisKey, 0, -1, true);\n        $members = $redis-&gt;exec();\n        if (empty($members[3])) {\n            break;\n        }\n        $nums=count($members[3]);\n        var_dump($nums);\n\n        if($nums&gt;$rule){\n            return false;\n        }\n    }\n    return true;\n}<\/pre>\n<p>\u4eca\u5929\u5173\u4e8e\u300a\u57fa\u4e8eRedis&nbsp;zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898\u300b\u7684\u5185\u5bb9\u4ecb\u7ecd\u5c31\u5230\u6b64\u7ed3\u675f\uff0c\u5982\u679c\u6709\u4ec0\u4e48\u7591\u95ee\u6216\u8005\u5efa\u8bae\uff0c\u53ef\u4ee5\u5728golang\u5b66\u4e60\u7f51\u516c\u4f17\u53f7\u4e0b\u591a\u591a\u56de\u590d\u4ea4\u6d41\uff1b\u6587\u4e2d\u82e5\u6709\u4e0d\u6b63\u4e4b\u5904\uff0c\u4e5f\u5e0c\u671b\u56de\u590d\u7559\u8a00\u4ee5\u544a\u77e5\uff01<\/p>\n<p>      \u7248\u672c\u58f0\u660e \u672c\u6587\u8f6c\u8f7d\u4e8e\uff1a\u811a\u672c\u4e4b\u5bb6 \u5982\u6709\u4fb5\u72af\uff0c\u8bf7\u8054\u7cfb \u5220\u9664  <\/p>\n<dl>\n<dt>\n <\/dt>\n<dd>\n   Redis+Lua\u811a\u672c\u5b9e\u73b0\u8ba1\u6570\u5668\u63a5\u53e3\u9632\u5237\u529f\u80fd(\u5347\u7ea7\u7248)\n <\/dd>\n<\/dl>\n<dl>\n<dt>\n <\/dt>\n<dd>\n   Spring+Redis+RabbitMQ\u5f00\u53d1\u9650\u6d41\u548c\u79d2\u6740\u9879\u76ee\u529f\u80fd\n <\/dd>\n<\/dl>\n","protected":false},"excerpt":{"rendered":"<p>\u57fa\u4e8eRedis&nbsp;zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898 0\u6d4f\u89c8 \u6536\u85cf \u672c\u7bc7\u6587\u7ae0\u5411\u5927\u5bb6\u4ecb\u7ecd\u300a\u57fa\u4e8eRedis&nbsp;zSet\u5b9e\u73b0\u6ed1\u52a8\u7a97\u53e3\u5bf9\u77ed\u4fe1\u8fdb\u884c\u9632\u5237\u9650\u6d41\u7684\u95ee\u9898\u300b\uff0c\u4e3b\u8981\u5305\u62ec\u9650\u6d41\u3001\u7a97\u53e3\u3001rediszset\u3001\u6ed1\u52a8\uff0c\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u8003\u4ef7\u503c\uff0c\u9700\u8981\u7684\u670b\u53cb\u53ef\u4ee5\u53c2\u8003\u4e00\u4e0b\u3002 public void checkCurrentWindowValue(String telNum) { String windowKey = CommonConstant.getNnSmsWindowKey(telNum); \/\/\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u6233 long currentTime = System.currentTimeMillis(); \/\/1\u5c0f\u65f6\uff0c\u9ed8\u8ba4\u53ea\u80fd\u53d15\u6b21\uff0c\u53c2\u6570smsWindowMax\u505a\u6210\u53ef\u914d\u7f6e\u9879\uff0c\u914d\u7f6e\u5230Nacos\u914d\u7f6e\u4e2d\u5fc3\uff0c\u53ef\u4ee5\u52a8\u6001\u8c03\u6574 if (RedisUtil.hasKey(windowKey)) { \/\/\u53c2\u6570smsWindowTime\u8868\u793a\u9650\u5236\u7684\u7a97\u53e3\u65f6\u95f4 \/\/\u8fd9\u91cc\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\u4e0e\u9650\u5236\u7a97\u53e3\u65f6\u95f4\u4e4b\u95f4\u7684\u77ed\u4fe1\u53d1\u9001\u6b21\u6570 Optional optional = Optional.ofNullable(RedisUtil.zCount(windowKey, currentTime &#8211; smsWindowTime, currentTime)); if (optional.isPresent()) { long count = optional.get(); if (count &gt;= smsWindowMax) { log.error(&#8220;==========&gt;\u5f53\u524d\u53f7\u7801\uff1a{} \u77ed\u4fe1\u53d1\u9001\u592a\u9891\u7e41\uff0c{}&#8221;, telNum, count); throw new ServiceException(MidRetCode.umid_10060); } } } StringBuilder [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-43915","post","type-post","status-publish","format-standard","hentry","category-os"],"_links":{"self":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/43915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/comments?post=43915"}],"version-history":[{"count":0,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/posts\/43915\/revisions"}],"wp:attachment":[{"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/media?parent=43915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/categories?post=43915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fwq.ai\/blog\/wp-json\/wp\/v2\/tags?post=43915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}