{"id":1213,"date":"2025-07-18T10:11:22","date_gmt":"2025-07-18T02:11:22","guid":{"rendered":"https:\/\/eve2333.top\/?p=1213"},"modified":"2025-07-18T10:11:23","modified_gmt":"2025-07-18T02:11:23","slug":"saas%e7%9f%ad%e9%93%be%e6%8e%a5%e7%b3%bb%e7%bb%9f-%e6%96%b0%e6%89%8b%e4%bb%8e%e9%9b%b6%e5%ad%a6%e4%b9%a0-10-%e5%8a%9f%e8%83%bd%e6%89%a9%e5%b1%95","status":"publish","type":"post","link":"https:\/\/eve2333.top\/?p=1213","title":{"rendered":"SaaS\u77ed\u94fe\u63a5\u7cfb\u7edf-\u65b0\u624b\u4ece\u96f6\u5b66\u4e60 10. \u529f\u80fd\u6269\u5c55"},"content":{"rendered":"\n<p>&nbsp;\u8fd9\u91cc\u6211\u8fd0\u884cvue\u6587\u4ef6\uff0c\u641e\u5f97\u6211\u597d\u9ebb\u70e6\uff0c\u6211\u9009\u5728idea\u4e00\u6b21\u6027\u628a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code>node-sass<\/code>\u7f16\u8bd1\u5931\u8d25<\/td><td>\u66ff\u6362\u4e3a<code>sass<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u7136\u540einstall\u548crun dev\uff08\u4e0d\u662fserve\uff09\u5c31\u90fd\u6210\u529f\u4e86&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c01\u8282\uff1a\u77ed\u94fe\u63a5\u521b\u5efa\u65f6\u6307\u5b9a\u9ed8\u8ba4\u57df\u540d<\/h2>\n\n\n\n<p>&nbsp;\u8fd9\u8282\u8bfe\u6765\u8ddf\u5927\u5bb6\u8bf4\u4e00\u4e0b\uff0c\u77ed\u94fe\u63a5\u521b\u5efa\u7684\u65f6\u5019\uff0c\u5b83\u600e\u4e48\u5e2e\u52a9\u6211\u4eec\u6709\u6548\u7684\u53bb\u63d0\u5347\u6211\u4eec\u7684\u8bbf\u95ee\u6548\u7387\u3002\u8fd9\u4e2a\u4e0d\u662f\u4ee3\u7801\u6027\u80fd\u4e0a\u7684\u63d0\u4ea4\uff0c\u662f\u6211\u4eec\u4e00\u4e2a\u65e5\u5e38\u4f7f\u7528\u7684\u63d0\u4ea4\uff0c\u8fd9\u662f\u6211\u4eec\u7684\u8f6f\u4ef6\u9875\u9762\uff0c\u5e94\u8be5\u4e5f\u662f\u7b2c\u4e00\u6b21\u548c\u5927\u5bb6\u89c1\u9762\u5c31\u5982\u679c\u8bf4\uff0c\u4f60\u662f\u8ddf\u7740\u4ece0~1\u4e0b\u6765\u7684\u8bdd\uff0c\u53cd\u5f39\u7684\u8bdd\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u53bb\u521b\u5efa\u5b83\uff0c\u7136\u540e\u6211\u4eec\u8fd9\u8fb9\u9009\u62e9\u672b\u65e5\u5206\u7ec4\uff0c\u7136\u540e\u70b9\u51fb\u521b\u5efa\uff0c\u521b\u5efa\u7684\u8bdd\u5927\u5bb6\u4f1a\u53d1\u73b0\u4e00\u4e2a\u4e8b\u60c5\uff0c\u6211\u4eec\u521b\u5efa\u91cc\u9762\u5bf9\u5427\uff0c\u662f\u524d\u7aef\u7ed9\u6211\u4eec\u4f20\u7684\u529f\u80fd\uff0c\u7136\u540e\u8fd9\u4e2a\u662f\u6700\u65e9\u4e4b\u524d\u8ddf\u524d\u7aef\u7ea6\u5b9a\u7684\uff0c\u7136\u540e\u4f46\u662f\u5728\u540e\u9762\u6765\u770b\u7684\u8bdd\u4f1a\u6709\u4e00\u4e9b\u95ee\u9898\uff0c\u5c31\u662f\u6211\u4eec\u81ea\u5df1\u5728\u914d\u540e\u7684\u65f6\u5019\u5bf9\u5427\uff1f\u4f60\u4e0d\u53ef\u80fd\u6bcf\u6b21\u90fd\u8981\u6539\u524d\u7aef\u5bf9\u5427\uff1f\u90a3\u6837\u4f1a\u5f88\u65b9\u4fbf\uff0c\u8fd9\u6837\u7684\u8bdd\u6211\u4eec\u662f\u4e0d\u662f\u4e0d\u662f\u53ef\u8bf7\u524d\u7aef\u5c31\u662f\u524d\u7aef\u4e0d\u4f20\u9ed8\u8ba4\u7684\u5200\u95e8\uff0c\u7136\u540e\u8fd9\u4e2a\u5200\u95e8\u7136\u540e\u5728\u6211\u4eec\u540e\u7aef\u91cc\u9762\u53bb\u914d\u7f6e\u7136\u540e\u8fd9\u6837\u7684\u8bdd\u662f\u4e0d\u662f\u4f1a\u66f4\u5408\u7406\u4e00\u4e9b\uff0c\u5bf9\u4e0d\u5bf9\uff1f<\/p>\n\n\n\n<p>\u7136\u540e\u6211\u4eec\u9996\u5148\u5982\u679c\u8bf4\u3002\u5982\u679c\u8bf4\u6211\u4eec\u8981\u52a0\u4e00\u4e2a\u9ed8\u8ba4\u914d\u7f6e\u7684\u8bdd\uff0c\u80af\u5b9a\u662f\u52a0\u5230\u914d\u7f6e\u6587\u4ef6\u91cc\u9762\u7684\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u8fd9\u8fb9\u4ece\u8bbe\u7acb\u548c\u8ddf\u914d\u7f6e\u4e0b\u52a0\u4e00\u4e2a\u76d7\u7248MV N\uff0c\u7136\u540e\u4e0b\u9762\u518d\u52a0\u4e00\u4e2a\u9ed8\u8ba4\u8fd9\u4e2a\u5355\u8bcd\uff0c\u6211\u9ed8\u8ba4\uff0c\u7136\u540e\u6211\u4eec\u53bb\u8f93\u5165\u6211\u4eec\u54ea\u91cc\u4e86\uff0c\u662f\u8f93\u6211\u4eechouse\u7684\u540d\u989d\u5bf9\u4e0d\u5bf9\uff1fN URL\u70b9nk\u5bf9\u5427\uff1f\u8fd9\u6837\u7684\u8bdd\u5c31\u53ef\u4ee5\u4e86\uff0c\u6211\u4eec\u628a\u7ed9\u5b83\u89e3\u6790\u8fc7\u6765\u3002\u7136\u540e\u5728\u8fd9\u91cc\u9762\u90fd\u6ca1\u6709\u3002\u7136\u540e\u53ef\u4ee5\u7684shot\u3002Shot\u7acb\u523bdefault\u3002\u8fd9\u5c31\u662f\u6211\u4eec\u7684\u4e00\u4e2a\u9ed8\u8ba4\u7684\u57df\u540d\uff0c\u7136\u540e\u5728\u8fd9\u91cc\u9762\u6211\u4eec\u53bb\u7ed9\u4ed6\u91cd\u5efa\u51fa\u6765\u3002&nbsp;<\/p>\n\n\n\n<p>Ok\u8fd9\u6837\u5c31\u53ef\u4ee5\u4e86\uff0c\u7136\u540e\u6211\u4eec\u91cd\u542f\u4e00\u4e0b\u770b\u770b\u6548\u679c\uff0c\u8ba9\u6211\u4eec\u5237\u65b0\u4e00\u4e0b\u3002\u6211\u4eec\u8fd8\u662f\u62ff\u7740\u6211\u4eec\u6362\u4e00\u6362\uff0c\u5177\u5907 ok\uff0c\u7136\u540e\u623f\u95f4\u7136\u540e\u8fd9\u8fb9\u521b\u5efa\u7684\u8bdd\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u5b83\u73b0\u5728\u5728\u521b\u5efa\u7684\u6211\u4eec\u914d\u7f6e\u7684\u539a\u7684\u91cc\u9762\u7684\u57df\u540d\u4e86\uff0c\u4f46\u662f\u8fd9\u4e2a\u65f6\u5019\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\u5c31\u662f\u7ed9\u5927\u5bb6\u7136\u540e\u76f4\u63a5\u590d\u5236\u4ed6\u8df3\u8fc7\u6765\u7684\u5bf9\u5427\uff1f\u662f\u8df3\u8fc7\u4e0d\u8fc7\u6765\u7684\u8bdd\uff0c\u4f60\u8d70HTTP\u5b83\u9ed8\u8ba4\u662f80\u7aef\u53e3\uff0c\u4f46\u662f\u6211\u4eec\u771f\u6b63\u77ed\u94fe\u63a5\u4e2d\u53f0\u5b83\u7684\u57df\u540d\u7684\u5bf9\u5427\uff1f&nbsp;<\/p>\n\n\n\n<p>\u662f801, \u8fd9\u6837\u7684\u8bdd\u624d\u53ef\u4ee5\u53ef\u80fd\u7ec6\u5fc3\u7684\u5c0f\u4f19\u4f34\u5c31\u8bf4\u4e86\u4e00\u4ef6\u4e8b\u60c5\uff0c\u600e\u4e48\u624d\u80fd\u591f\u66f4\u52a0\u9ad8\u6548\u7684\u53bb\u8282\u7701\uff0c\u6211\u4eec\u6bcf\u6b21\u53bb\u52a0\u7684\u6b65\u9aa4\u5f88\u7b80\u5355\uff0c\u5728\u8fd9\u91cc\u52a0\u4e0a801\u4e4b\u524d\u5e94\u8be5\u65e9\u505a\u7684\uff0c\u6709\u53ef\u80fd\u5927\u5bb6\u770b\u6211\u4e4b\u524d\u5f55\u4e86\u90a3\u4e48\u591a\u671f\u76d1\u63a7\u7684\u89c6\u9891\u5bf9\u5427\uff1f\u6bcf\u6b21\u90fd\u8981\u52a0\u7aef\u53e3\uff0c\u53ef\u80fd\u5927\u5bb6\u90fd\u8981\u6bd4\u6211\u66f4\u7740\u6025\u3002&nbsp;<\/p>\n\n\n\n<p>Ok\u6211\u4eec\u518d\u6765\u521b\u5efa\u4e00\u4e2a ok\u8fd9\u6837\u76f4\u63a5\u70b9\u662f\u4e0d\u662f\u5c31\u8df3\u8fc7\u6765\u4e86\uff0c\u5bf9\u4e0d\u5bf9\uff1f\u914d\u7f6e\u8ba9\u5b83\u653e\u7740\u3002\u6211\u60f3\u60f3\u4ed6\u8fd9\u4e2a\u914d\u7f6e\u600e\u4e48\u53ef\u80fd\u653e\u5462\uff1f\u4ed68001\u662f\u6253\u5230\u8fd9\u91cc\u6765\u7684\u3002\u6211\u60f3\u60f3\u3002\u7136\u540e8001\uff0c\u8fd9\u91cc\u4e5f\u662f8001\u6ca1\u95ee\u9898\u3002\u6211\u4eec\u8df3\u8f6c\u8fd9\u91cc\u8fd8\u9700\u8981\u52a0\u4e00\u4e2a\u6b65\u9aa4\uff0c\u6211\u4eec\u8fd9\u8fb9\u83b7\u53d6\u4e86\u601d\u8def\uff0c\u6211\u8fd9\u4e2a\u4e1c\u897f\uff0c\u7136\u540e\u6211\u4eec\u8fd9\u8fb9\u4e5f\u8981\u53bb\u83b7\u53d6\u5b83\u7684part\u3002\u4ec0\u4e48\u597d\u7684\uff1f201. \u4e0d\u884c\uff0c\u7b2c\u4e8c\u8fd9\u80af\u5b9a\u662f\u56f4\u653b\u4e86\u3002\u70b9\u4e00\u4e2a\u3002\u6709\u7684\u3002\u7136\u540e\u8fd9\u4e2a\u6807\u51c6\u4e00\u76f4\u5e94\u8be5\u662f\u90fd\u4e0d\u80fd\u76d6\u7ae0\uff0c\u6211\u5c31\u6b7b\u6389\u4e86\uff0c\u5982\u679c\u4ed6080. \u90a3\u4e48\u5c31\u8fc7\u600e\u4e48\u6837\uff1f\u5982\u679c\u7b49\u4e8e80\uff0c\u4ed6\u5982\u679c\u7b49\u4e8e80\u7684\u8bdd\uff0c\u6211\u4eec\u5c31\u76f4\u63a5\u8fd4\u56de\u7a7a\uff0c\u5982\u679c\u5982\u679c\u8bf4\u4e0d\u7b49\u4e8e80\uff0c\u8fd9\u6837\u53ef\u4ee5X\u3002\u8fd9\u6837\u7684\u770b\u6cd5\u662f\u4ec0\u4e48\uff1f\u90a3\u5c31\u662f801\u3002\u5982\u679c\u662f8001\u6211\u60f3\u4e00\u4e0b\uff0c\u505a\u7684\u592a\u590d\u6742\u4e86\uff0c\u6211\u60f3\u60f3\u8fd9\u91cc\u662f\u8be5\u600e\u4e48\u53bb\u7ed9\u5b83\u53bb\u52a0\u8fdb\u53bb\u3002&nbsp;<\/p>\n\n\n\n<p>\u5982\u679c\u8bf4\u5b83\u8fd4\u56de\u7684\u662f80\uff0c\u5982\u679c\u662f80\u7684\u8bdd\uff0c\u90a3\u4e48\u5c31\u8fd4\u56de\u4e00\u4e2a\u7a7a\u3002\u7b97\u4e86\uff0c\u6211\u4eec\u8fd9\u8fb9\u53cd\u6b63\u534f\u8bae\u6709\u70b9\u4e0d\u6e05\u6670\uff0c\u6211\u4eec\u76f4\u63a5\u522410\u4e07\u5982\u679c\u7b49\u4e8e808\u3002\u5982\u679c\u4e0d\u7b49\u4e8e80\uff0c\u5982\u679c\u7b49\u4e8e80\u7684\u8bdd\uff0c\u5982\u679c\u8bf4\u5b83\u7b49\u4e8e80\u5e94\u8be5\u8bbe\u7f6e\u4e00\u4e2a\u7a7a\u624d\u5bf9\u3002\u6211\u60f3\u60f3\u884c\u3002\u6240\u4ee5\u6211\u9760\u60f3\u60f3&nbsp;<\/p>\n\n\n\n<p>\u7d27\u6025\u7684\u56fd\u5bb6\u6ca1\u6709\u7528\uff0c\u5b9e\u65bd\u6548\u679c\u3002\u5982\u679c\u8bf4\u7b49\u4e8e\u5b83\u80af\u5b9a\u662f\u4e0d\u7b49\u4e8e80\u7684\u3002\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u5148\u8bd5\u4e00\u8bd5\u6548\u679c\u3002\u5927\u6982\u5c31\u628a\u52a0\u8fdb\u53bb\u3002Ok\u8fd9\u6837\u662f\u6ee1\u8db3\u6211\u4eec\u6548\u679c\u7684\uff0c\u53d6\u4e2a\u677f\u5c31\u53ef\u4ee5\u4e86\u3002\u5b83\u600e\u4e48\u662f\u8fd9\u73a9\u610f\uff1f\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u518d\u521b\u5efa\u4e00\u4e2a\u4e00\u4e2a\u70b9\uff0c\u770b\u5230\u6ca1\u6709\uff0c\u8fd9\u4e2a\u5c31\u8fbe\u5230\u6211\u4eec\u7684\u6548\u679c\u4e86\uff0c\u7136\u540e\u6211\u4eec\u81ea\u5df1\u8fd9\u91cc\u628a\u8fd9\u4e2a\u7f51\u5740\u7ed9\u4ed6\u5e26\u4e86\u4e0a\u6765\u3002\u7136\u540e\u5982\u679c\u8bf4\u6211\u4eec\u8fd9\u91cc\u9762\u521b\u5efa\u7684\u4e0d\u662f8001\u5bf9\uff0c\u6211\u4eec\u5982\u679c\u6ca1\u6709\u7684\u8bdd\uff0c\u521a\u624d\u7684\u6761\u4ef6\u8fd9\u4e2a\u6761\u4ef6\u5e94\u8be5\u5c31\u662f\u8fd4\u56de\u7684\uff0c\u5c31\u662f\u7a7a\u5b57\u6bcd\u5757\u8fd8\u662f\u62fc\u4e0d\u4e0a\u53bb\u7684\uff0c\u8fd9\u4e2a\u662f\u7b26\u5408\u6211\u4eec\u9884\u671f\u3002\u6211\u4eec\u628a\u4ee3\u7801\u63d0\u4ea4\u4e00\u4e0b\u3002\u5e94\u8be5\u53eb\u4f18\u5316\u3002\u77ed\u94fe\u63a5\u521b\u5efa\u4ee5\u548c\u8df3\u8f6c\u529f\u80fd\uff0c\u4ec0\u4e48\u77ed\u94fe\u63a5\u521b\u5efa\u548c\u8df3\u8f6c\u529f\u80fd\uff1f\u77ed\u94fe\u63a5\u521b\u5efa\uff0c\u521b\u5efa\u65f6\u57df\u540d\u901a\u8fc7\u540e\u7aef\u3002 Ok\u8fd9\u8282\u8bfe\u5c31\u8bb2\u8fd9\u4e9b\uff0c\u57fa\u672c\u4e0a\u628a\u6211\u4eec\u540e\u7eed\u7684\u8bdd\uff0c\u5982\u679c\u5927\u5bb6\u8981\u5728\u672c\u5730\u6d4b\u8bd5\uff0c\u4ed6\u7684\u5c31\u4e0d\u7528\u518d\u6bcf\u6b21\u518d\u53bb\u8f93\u5bf9\u5e94\u7684\u57df\u540d\u4e86\uff0c\u4ee5\u53ca\u4ed6\u5c31\u4e0d\u7528\u8fd8\u6709\u7aef\u53e3\uff0c\u8fd9\u6837\u7684\u8bdd\u4f1a\u52a0\u5927\u4e00\u4e9b\u5927\u5bb6\u672c\u5730\u5f00\u53d1&nbsp;<\/p>\n\n\n\n<p>application.yaml&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>short-link:\n  domain:\n    default: nurl.ink:8001<\/code><\/pre>\n\n\n\n<p>ShortLinkServicelmpl.java \u00a0<img loading=\"lazy\" decoding=\"async\" height=\"483\" width=\"680\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/2c3672d6646c43c9974da41127057948.png\" alt=\"\"><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Value(\"${short-link.stats.locale.amap-key}\")\nprivate String statsLocaleAmapKey;\n@Value(\"${short-link.domain.default}\")\nprivate String createShortLinkDefaultDomain;\n\n@Override\npublic ShortLinkCreateRespDTO createShortLink(ShortLinkCreateReqDTO requestParam) {\n\n    String shortLinkSuffix = generateSuffix(requestParam);\n    \/\/ShortLinkDO shortLinkDO = BeanUtil.toBean(requestParam, ShortLinkDO.class);\n    \/\/shortLinkDO.setShortUri(shortLinkSuffix);\n    \/\/String fullShortUrl = requestParam.getDomain() + \"\/\" + shortLinkSuffix;\n\n    \/\/ String fullShortUrl = StrBuilder.create(requestParam.getDomain())\n    String fullShortUrl = StrBuilder.create(createShortLinkDefaultDomain)\n\n            .append(\"\/\")\n            .append(shortLinkSuffix)\n            .toString();\n\n    \/\/shortLinkDO.setEnableStatus(0);\n    \/\/shortLinkDO.setFullShortUrl(requestParam.getDomain() + \"\/\" + shortLinkSuffix);\n    ShortLinkDO shortLinkDO = ShortLinkDO.builder()\n            \/\/.domain(requestParam.getDomain())\n            .domain(createShortLinkDefaultDomain)\n\n            .originUrl(requestParam.getOriginUrl())\n            .gid(requestParam.getGid())\n            .createdType(requestParam.getCreatedType())\n            .validDateType(requestParam.getValidDateType())\n            .validDate(requestParam.getValidDate())\n            .describe(requestParam.getDescribe())\n            .shortUri(shortLinkSuffix)\n            .enableStatus(0)\n            .totalPv(0)\n            .totalUv(0)\n            .totalUip(0)\n            .fullShortUrl(fullShortUrl)\n            .build();<\/pre>\n\n\n\n<p>\u53e6\u5916\u4e00\u6bb5\u6dfb\u52a0\u548c\u8865\u5145<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Override\npublic void restoreUrl(String shortUri, ServletRequest request, ServletResponse response) {\n    String serverName = request.getServerName();\n\n    String serverPort = Optional.of(request.getServerPort())\n            .filter(each -&gt; !Objects.equals(each, 80))\n            .map(String::valueOf)\n            .map(each -&gt; \":\" + each)\n            .orElse(\"\");\n    String fullShortUrl = serverName + serverPort + \"\/\" + shortUri;\n<\/pre>\n\n\n\n<p>\u6211\u4eec\u521d\u59cb\u5316\u77ed\u94fe\u63a5\u524d\u7aef\u9879\u76ee\uff0c 64\u4e2a\u6587\u4ef6\u4ee5\u53ca\u540e\u7eed\u7684ico\u4fee\u6539\u90fd\u81ea\u884c\u5bfc\u5165\u5373\u53ef\uff1b<\/p>\n\n\n\n<p>optimzie\uff1a\u77ed\u94fe\u63a5\u521b\u5efa\u65f6\u57df\u540d\u901a\u8fc7\u540e\u7aef\u63a7\u5236&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u90a3\u5982\u679c\u540e\u7eed\u9700\u8981\u6539\u7aef\u53e3\u53f7\uff0c\u4e4b\u524d\u7684\u77ed\u94fe\u63a5\u4e0d\u5c31\u5931\u6548\u4e86\u5417\uff1f<br>\u5b58\u5728\u4e00\u4e2a\u95ee\u9898\uff0c\u54b1\u4eec\u662f\u5f00\u53d1\u73af\u5883\uff0c\u751f\u4ea7\u73af\u5883\u9ed8\u8ba4\u4e0d\u52a0\u7aef\u53e3\u53f7\u7684<\/p>\n<\/blockquote>\n\n\n\n<p>&nbsp;\u5728\u5229\u7528\u5e03\u9686\u8fc7\u6ee4\u5668\u5224\u65ad\u77ed\u94fe\u63a5\u662f\u5426\u5b58\u5728\u7684\u65f6\u5019\u662f\u4e0d\u662f\u5e94\u8be5\u4e5f\u8981\u628arequestParam.getDomain()\u6362\u6210createShortLinkDefaultDomain&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u7b54\uff1a\u662f\u8981\u6362\u7684 \u4e0d\u6362\u4f1a\u627e\u4e0d\u5230\u9875\u9762 \u5e03\u9686\u8fc7\u6ee4\u5668\u4e2d\u4e0e\u8981\u627e\u7684\u4e0d\u5339\u914d \u4f46\u662f\u6362\u4e86\u4e4b\u540e\u4ee5\u540e\u6362\u7aef\u53e3\u7684\u8bdd \u5e03\u9686\u8fc7\u6ee4\u5668\u4e2d\u7684\u6570\u636e\u5c31\u5931\u6548\u4e86 \u5728\u5224\u65ad\u8fd8\u662f\u4f1a\u627e\u4e0d\u5230\u9875\u9762 \u8fd9\u4e0d\u592a\u61c2<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u4e3a\u4ec0\u4e48\u9700\u8981\u8fc7\u6ee4\u638980\u7aef\u53e3\u7684\u8bbf\u95ee\uff1f \u56e0\u4e3aHTTP\u534f\u8bae\u7684\u9ed8\u8ba4\u7aef\u53e3\u5c31\u662f80\uff0c\u5373<a href=\"http:\/\/example.com\/\" target=\"_blank\"  rel=\"nofollow\" >Example Domain<\/a>\u5176\u5b9e\u662f<a href=\"http:\/\/example.com\/\" target=\"_blank\"  rel=\"nofollow\" >Example Domain<\/a>\u3002\u5982\u679c\u914d\u7f6e\u4e86nginx\u8fdb\u884c\u65b9\u5411\u4ee3\u7406\uff0cnginx\u4f1a\u76d1\u542c80\u7aef\u53e3\u7136\u540e\u8f6c\u53d1\u52308001\u7aef\u53e3\u3002<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c02\u8282\uff1a\u5982\u4f55\u901a\u8fc7\u63a5\u53e3\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5<\/h2>\n\n\n\n<p>\u5927\u5bb6\u8bf4\u4e00\u4e0b\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\uff0c\u9996\u5148\u7684\u8bdd\u6279\u91cf\u7a7a\u95f4\u7684\u94fe\u63a5\u56e0\u4e3a\u6d89\u53ca\u5230\u548c\u524d\u7aef\u4ea4\u4e92\u5199\u8d77\u6765\u4f1a\u6bd4\u8f83\u9ebb\u70e6\u4e00\u70b9\uff0c\u6240\u4ee5\u8bf4\u6211\u5c31\u6ca1\u6709\u5e26\u5927\u5bb6\u4e00\u70b9\u70b9\u7684\u6311\u3002\u7136\u540e\u8fd9\u4e2a\u4ee3\u7801\u6211\u4e5f\u6ca1\u6709\u63d0\u4ea4\uff0c\u6211\u4f1a\u901a\u8fc7\u4e00\u6b21\u63d0\u4ea4\u628a\u5b83\u4e0a\u4f20\u5230\u8fd9\u4e2a\u4ed3\u5e93\uff0c\u8fd9\u6837\u7684\u8bdd\u540e\u9762\u5927\u5bb6\u53bb\u770b\u89c6\u9891\u7684\u65f6\u5019\uff0c\u5c31\u80fd\u591f\u62ff\u5230\u6211\u4eec\u672c\u6b21\u63d0\u4ea4\u8bb0\u5f55\u53bb\u6bd4\u5bf9\u81ea\u5df1\u76f8\u5e94\u7684\u4e00\u4e2a\u5f00\u53d1\u597d\u5427\uff1f<\/p>\n\n\n\n<p>\u9996\u5148\u8bf4\u4e00\u4e0b\u521b\u5efa\u77ed\u94fe\u63a5\u548c\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u5b83\u6709\u4ec0\u4e48\u533a\u522b \u9996\u5148\u6211\u4eec\u5355\u4e2a\u521b\u5efa\u77ed\u94fe\u63a5\uff0c\u5b83\u53ea\u80fd\u6709\u4e00\u4e2a\u539f\u59cb\u94fe\u63a5\u4ee5\u53ca\u5bf9\u5e94\u7684\u6807\u9898\u53ea\u80fd\u6709\u4e00\u4e2a\u5bf9\u5427\uff1f\u8fd9\u4e24\u4e2a\u90fd\u662f\u4e00\u5bf9\u4e00\u7684\u3002\u6211\u4eec\u6279\u91cf\u521b\u5efa\u7684\u8bdd\u5c31\u76f8\u5f53\u4e8e\u8fd9\u4e9bdomain\u8fd9\u4e9b\u4e1c\u897f\u90fd\u4e0d\u53d8\uff0c\u751a\u81f3\u6211\u4eec\u73b0\u5728domain\u5176\u5b9e\u5df2\u7ecf\u4e0d\u5728\u4e86\uff08\u9ed8\u8ba4\u5199\u597d\u4e86\uff09\uff0c\u6211\u4eec\u5982\u679c\u628a\u8fd9\u4e2a\u53c2\u6570\u7559\u7740\uff0c\u7136\u540e\u6211\u4eec\u548c\u8fd9\u4e2a\u90fd\u5df2\u7ecf\u5176\u5b9e\u53d8\u6210\u4e86\u90e8\u5206\uff0c\u76f8\u5f53\u4e8e\u4e5f\u662f\u4e2a\u4ed6\u4eec\u4e5f\u76f8\u5f53\u4e8e\u662f\u4e00\u5bf9\u4e00\u7684\u5173\u7cfb\u3002 \u7136\u540e\u5176\u4ed6\u6ca1\u6709\u53d8\u5316\uff0c\u7136\u540e\u6211\u4eec\u63d0\u4ea4\u5230\u540e\u53f0\u4e4b\u540e<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"domain\": \"nurl.ink\",\n  \"originUrls\": &#91;\n    \"https:\/\/nageoffer.com\/\",\n    \"https:\/\/nageoffer.com\/\"\n  ],\n  \"describes\": &#91;\n    \"consequat quis nisi nulla\",\n    \"consequat quis nisi nulla\"\n  ],\n  \"gid\": \"uyCClp\",\n  \"createdType\": 1,\n  \"validDateType\": 0\n}<\/code><\/pre>\n\n\n\n<p>\u8fd9\u4e9b\u4e1c\u897f\u662f\u4e00\u4e2a\u5bf9\u5e94\u7684 Excel\u6587\u4ef6\uff0c Excel\u6587\u4ef6\u91cc\u9762\u6709\u521b\u5efa\u6210\u529f\u7684\u77ed\u94fe\u63a5\u7684\u4e00\u4e2a\u6570\u636e\uff0c\u6211\u4eec\u628a\u5b83\u4fdd\u5b58\u4e00\u4e0b\uff0c\u6211\u4eec\u7528\u8fd9\u4e2aApifox\u7684\u8bdd\u8981\u70b9\u4e0b\u8f7d\u6587\u4ef6<\/p>\n\n\n\n<p>\u7136\u540e\u5728\u8fd9\u4e2a\u91cc\u9762\u6211\u4eec\u53ef\u4ee5\u7ed9\u5b83\u70b9\u4e00\u4e2a\u6253\u5f00\uff0c\u6253\u5f00\u4e4b\u540e\u5b83\u6709\u4e09\u70b9\uff0c\u9996\u5148\u7b2c\u4e00\u5217\u662f\u6807\u9898\uff0c\u7b2c\u4e8c\u662f\u77ed\u94fe\u63a5\uff0c\u7b2c\u4e09\u5217\u662f\u539f\u59cb\u94fe\u63a5\uff0c\u8fd9\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u5173\u7cfb\uff0c\u5982\u679c\u8bf4\u6211\u4eec\u70b9\u4e86\u8fd9\u8fb9\u5404\u81ea\u70b910\u6761\uff0c\u5047\u5982\u5931\u8d25\u4e863\u6761\uff0c\u90a3\u4e48\u8fd9\u91cc\u9762\u53ea\u4f1a\u5c55\u793a7\u6761\u8bb0\u5f55\uff0c\u8981\u8ddf\u5927\u5bb6\u63d0\u524d\u8bf4\u4e00\u4e0b\uff0c\u53ef\u80fd\u6709\u540c\u5b66\u4f1a\u95ee\uff0c\u65e2\u7136\u6211\u4eec\u5df2\u7ecf\u6709\u5355\u4e2a\u521b\u5efa\u77ed\u94fe\u63a5\u4e86\uff0c\u6211\u4eec\u4e3a\u4ec0\u4e48\u8fd8\u8981\u7528\u6279\u91cf\u521b\u5efa\uff1f\u6709\u4e9b\u60c5\u51b5\u662f\u8fd9\u6837\u7684\uff0c\u5355\u4e2a\u521b\u5efa\u77ed\u94fe\u63a5\u5728\u5ba2\u6237\u6216\u8005\u7528\u6237\u5728\u5df2\u77e5\u8981\u521b\u5efa\u67d0\u4e9b\u77ed\u94fe\u63a5\u7684\u60c5\u51b5\uff0c\u5df2\u77e5\u8981\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u7684\u60c5\u51b5\u4e0b\uff0c\u4ed6\u4eec\u7528\u5355\u4e2a\u53bb\u521b\u5efa\u7684\u8bdd\uff0c\u4f1a\u6709\u4e00\u4e9b\u7f51\u7edcio\u6d88\u8017\u5bf9\u5427\uff0c\u5176\u5b9e\u4e0d\u662f\u7279\u522b\u7684\u53cb\u597d\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u6279\u91cf\u7684\u5f62\u5f0f\u5e2e\u4ed6\u4eec\u628a\u7ed9\u4ed6\u628a\u7f51\u7edc\u6d88\u8017\u7684\u7ed9\u53bb\u6389\uff0c\u7136\u540e\u5176\u6b21\u7684\u8bdd\u4f60\u770b\u6211\u4eec\u8fd9\u8fb9\u8fd4\u56de\u7684\u90fd\u662f\u4e00\u4e9bExcel\u6570\u636e\u5bf9\u5427\uff1f\u4f46\u662f\u8fd9\u4e2aExcel\u6570\u636e\u5b83\u53ea\u662f\u5728\u4f60\u524d\u7aef\uff0c\u5c31\u662f\u5728\u6211\u4eec\u8fd9\u91cc\u53bb\u6279\u91cf\u521b\u5efa\u7684\u65f6\u5019\uff0c\u4ed6\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6d41\uff0c\u5176\u5b9e\u6211\u662f\u628a\u4e00\u4e2a\u6d41\u6253\u5230\u524d\u7aef\u7684\uff0c\u7136\u540e\u5b83\u4f1a\u4e0b\u8f7d\u51fa\u6765Excel\u6587\u4ef6\uff0c\u5728\u8fd9\u91cc\u9762\u5c55\u793a\u7684\u8bdd\uff0c\u5c31\u76f8\u5f53\u4e8e\u662f\u8be6\u60c5\u91cc\u9762\u6709\u8fd9\u4e48\u591a\u53c2\u6570\uff0c\u4e0d\u8fc7\u5982\u679c\u8bf4\u5b8c\u5168\u5982\u679c\u53bb\u8bbf\u95ee\u7684\u8bdd\uff0c\u5c31\u8fd9\u6837\u6211\u4eec\u70b9\u786e\u8ba4\u5b83\u4f1a\u5f39\u7ed9\u6211\u4eec\u4e00\u4e2a\u6210\u529f\uff0c\u5176\u6b21\u4f1a\u628a\u521a\u624d\u7684Excel\u6587\u4ef6\u4ece\u8c37\u6b4c\u4e0a\u7ed9\u4e0b\u8f7d\u4e0b\u6765\uff0c\u8fd9\u662f\u4e00\u4e2a\u6b63\u5e38\u7684\u4ea4\u4e92\u3002<\/p>\n\n\n\n<p>\u8fd9\u4e2a\u65f6\u5019\u95ee\u9898\u6765\u4e86\uff0c\u6709\u4e9b\u60c5\u51b5\u4e0b\u6211\u4eec\u4e2d\u53f0\u7684\u63a5\u53e3\u5f62\u5f0f\u5bf9\u63a5\u7ed9\u4e00\u4e9b\u60f3\u8981\u8c03\u7528\u6211\u4eec\u77ed\u94fe\u63a5API\u7684\u4e00\u4e9b\u7cfb\u7edf\u5bf9\u5427\uff1f\u4f60API\u7cfb\u7edf\u53bb\u8fd4\u56de\u8fd9\u6837\u4e00\u4e2a\u7406\u7531\u662f\u80af\u5b9a\u4e0d\u6b63\u786e\u7684\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\uff0c\u5b83\u8fd4\u56de\u7684\u662f\u6b63\u5e38\u7684\u4e00\u4e2a\u6210\u529f\u7684\u6570\u91cf\u4ee5\u53ca\u6210\u529f\u7684\u4e00\u4e2a\u660e\u7ec6\uff0c\u7136\u540e\u6211\u4eec\u5728\u540e\u7ba1shortlinkcontroller\u91cc\u9762\u6211\u4eec\u53ef\u4ee5\u5728\u8fd9\u91cc\u770b\u5230\uff0c\u6211\u4eec\u5728\u8d27\u6b3e\u91cc\u9762\u62ff\u5230\u5bf9\u5e94\u7684\u6570\u636e\uff0c\u7136\u540e\u5224\u65ad\u662f\u5426\u6210\u529f\uff0c\u5982\u679c\u6210\u529f\u7684\u8bdd\uff0cok\u6211\u4eec\u62ff\u5230\u5bf9\u5e94\u7684\u6570\u636e\uff0c\u901a\u8fc7EasyExcelWebUtil\u7684\u5f62\u5f0f\u7ed9\u5b83\u5199\u8fdb\u8fbe\u5230\u63a7\u5236\u53f0\u91cc\u9762\u4e00\u4e2a\u6d41\uff0c\u7136\u540e\u8fd9\u6837\u7684\u8bdd\u8c37\u6b4c\u6d4f\u89c8\u5668\u5c31\u4f1a\u81ea\u52a8\u4e0b\u8f7d\u8fd9\u6837\u7684\u4e00\u4e2a\u4ea4\u4e92\u6d41\u7a0b\u3002<\/p>\n\n\n\n<p id=\"XcNa8\">\u4e1a\u52a1\u903b\u8f91<\/p>\n\n\n\n<p id=\"u58cf58b8\">\u521b\u5efa\u5355\u4e2a\u77ed\u94fe\u63a5\u53c2\u6570\uff1a<\/p>\n\n\n\n<pre id=\"pIDUJ\" class=\"wp-block-code\"><code>{\n    \"domain\": \"nurl.ink\",\n    \"originUrl\": \"https:\/\/nageoffer.com\/\",\n    \"gid\": \"siCwZo\",\n    \"createdType\": 1,\n    \"validDateType\": 0,\n    \"describe\": \"consequat quis nisi nulla\"\n}<\/code><\/pre>\n\n\n\n<p id=\"u6586eeac\">\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u53c2\u6570\uff0c\u5c06\u539f\u59cb\u94fe\u63a5\u548c\u6807\u9898\u63cf\u8ff0\u62c6\u5206\u4e3a\u4e00\u4e2a\u6570\u7ec4\u3002<\/p>\n\n\n\n<pre id=\"NucAJ\" class=\"wp-block-code\"><code>{\n    \"domain\": \"nurl.ink\",\n    \"originUrls\": &#91;\n        \"https:\/\/nageoffer.com\/\",\n        \"https:\/\/nageoffer.com\/\"\n    ],\n    \"describes\": &#91;\n        \"consequat quis nisi nulla\",\n        \"consequat quis nisi nulla\"\n    ],\n    \"gid\": \"uyCClP\",\n    \"createdType\": 1,\n    \"validDateType\": 0\n}<\/code><\/pre>\n\n\n\n<p id=\"u1287d3ca\">\u5e76\u4e14\uff0c\u5728\u521b\u5efa\u5b8c\u77ed\u94fe\u63a5\u4e4b\u540e\uff0c\u4f1a\u8fd4\u56de\u524d\u7aef\u4e00\u4e2a Excel \u6587\u4ef6\uff0c\u65b9\u4fbf\u7528\u6237\u67e5\u770b\u54ea\u4e9b\u539f\u59cb\u94fe\u63a5\u751f\u6210\u4e86\u77ed\u94fe\u63a5\uff0c\u4ee5\u53ca\u5bf9\u5e94\u77ed\u94fe\u63a5\u662f\u4ec0\u4e48\u3002<\/p>\n\n\n\n<p id=\"ue0994770\">\u6574\u4f53\u903b\u8f91\u5982\u4e0b\uff1a<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"932\" width=\"1978\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/d10abd6ba334c3502ab358e97cd8868c.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"feOfh\">\u4e3a\u4ec0\u4e48\u77ed\u94fe\u63a5\u4e2d\u53f0\u8fd4\u56de\u6807\u51c6\u6570\u636e\uff0c\u540e\u7ba1\u8fd4\u56deExcel\uff1f<\/p>\n\n\n\n<p id=\"u582aaf1a\">\u56e0\u4e3a\u77ed\u94fe\u63a5\u4e2d\u53f0\u662f\u63d0\u4f9b\u901a\u7528\u80fd\u529b\u7684\u4e2d\u53f0\uff0c\u4f9bN\u591a\u5ba2\u6237\u7aef\u7cfb\u7edf\u4f7f\u7528\uff0c\u4e0d\u53ea\u662f\u77ed\u94fe\u63a5\u540e\u7ba1\uff0c\u5e94\u8be5\u8fd4\u56de\u516c\u5171\u7684\u8fd4\u56de\u53c2\u6570\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u8fd4\u56de Excel \u6d41\u3002<\/p>\n\n\n\n<p id=\"ud6e36b76\">\u56e0\u4e3a\u53ef\u80fd\u6709\u4e9b\u67d0\u4e9b\u5176\u4ed6\u5ba2\u6237\u7aef\u7cfb\u7edf\u4e0d\u505a Excel \u6d41\u5904\u7406\uff0c\u5982\u679c\u5ba2\u6237\u7aef\u7cfb\u7edf\u5e0c\u671b\u8fd9\u79cd\u4ea4\u4e92\uff0c\u8ba9\u4ed6\u4eec\u6839\u636e\u8fd4\u56de\u53c2\u6570\u81ea\u5df1\u505a\u5904\u7406\u5c31\u597d\u3002<\/p>\n\n\n\n<p>\u9996\u5148\u7684\u8bddRemoteService\u8fd9\u662f\u540e\u7ba1admin\u5bf9\u5427\uff1f\u7136\u540e\u4ed6\u53bb\u6211\u4eec\u7684batchCreateShortLink\u7136\u540e\u5728\u8fd9\u91cc\u9762\u8fd4\u56de\u5bf9\u5e94\u7684\u4fe1\u606f\uff0c\u7136\u540e\u901a\u8fc7\u4fe1\u606f\u6765\u5224\u65ad\u662f\u5426\u6210\u529fisSuccess\uff0c\u5982\u679c\u6210\u529f\u7684\u8bdd\uff0c\u90a3\u4e48\u6211\u4eec\u62ff\u5230\u5b83\u5bf9\u5e94\u7684\u91cc\u9762\u7684\u4e00\u4e2a\u660e\u7ec6\u6570\u636egetBaseLinkInfos\uff0c\u7136\u540e\u5c06\u8be5\u660e\u7ec6\u6570\u636e\u901a\u8fc7Excel\u7684\u5f62\u5f0f\u7ed9\u5199\u5230\u5bf9\u5e94\u7684response\u91cc\u9762\u53bb\uff0c\u8ba9\u524d\u7aef\u7684\u63a7\u5236\u53f0\u5728\u6d4f\u89c8\u5668\u91cc\u9762\u76f4\u63a5\u4e0b\u8f7d\u8fd9\u662f\u4e00\u4e2a\u6700\u5b8c\u6574\u7684\u6d41\u7a0b\uff1bremoteService\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\n *\n * @param requestParam \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u8bf7\u6c42\u53c2\u6570\n * @return \u77ed\u94fe\u63a5\u6279\u91cf\u521b\u5efa\u54cd\u5e94\n *\/\ndefault Result&lt;ShortLinkBatchCreateRespDTO&gt; batchCreateShortLink(ShortLinkBatchCreateReqDTO requestParam) {\n    String resultBodyStr = HttpUtil.post(\"http:\/\/127.0.0.1:8001\/api\/short-link\/v1\/create\/batch\", JSON.toJSONString(requestParam));\n    return JSON.parseObject(resultBodyStr, new TypeReference&lt;&gt;() {\n    });\n}<\/pre>\n\n\n\n<p>&nbsp;admin\u7684shortlinkController<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\n *\/\n@SneakyThrows\n@PostMapping(\"\/api\/short-link\/admin\/v1\/create\/batch\")\npublic void batchCreateShortLink(@RequestBody ShortLinkBatchCreateReqDTO requestParam, HttpServletResponse response) {\n    Result&lt;ShortLinkBatchCreateRespDTO&gt; shortLinkBatchCreateRespDTOResult = shortLinkRemoteService.batchCreateShortLink(requestParam);\n    if (shortLinkBatchCreateRespDTOResult.isSuccess()) {\n        List&lt;ShortLinkBaseInfoRespDTO&gt; baseLinkInfos = shortLinkBatchCreateRespDTOResult.getData().getBaseLinkInfos();\n        EasyExcelWebUtil.write(response, \"\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5-SaaS\u77ed\u94fe\u63a5\u7cfb\u7edf\", ShortLinkBaseInfoRespDTO.class, baseLinkInfos);\n    }\n}<\/pre>\n\n\n\n<p>\u6211\u4eec\u518d\u53bb\u770b\u4e00\u4e0b\u6211\u4eec\u7684shortlink\uff0c\u91cc\u9762\u4ed6\u5728\u5e72\u4ec0\u4e48\uff0c\u8fd8\u662f\u8001\u6837\u5b50\u3002 \u6279\u91cf\u5355\u72ec\u628a\u6709\u7b77\u5b50\u5730\u7403\uff0c\u7136\u540e\u521b\u5efa\u4e00\u4e2a\u5730\u65b9\u7684\u5730\u7403\uff0c\u7136\u540e\u6211\u4eec\u518d\u5e26\u8fdb\u53bb\uff0c\u7136\u540e\u8fd9\u8fb9\u7684\u8bdd\u6211\u4eec\u76f8\u5f53\u4e8e\u4ee5\u539f\u59cbURL\u4e3a\u5224\u65ad\uff0c\u53ef\u80fd\u6709\u591a\u4e2a\u539f\u59cb\u7801\uff0c\u7136\u540e\u8fd9\u91cc\u9762\u7684\u8bdd\u6211\u4eec\u7ed9\u4ed6\u6700\u7ec8\u5176\u5b9e\u8c03\u52a8\u7684\u5e02\u573a\u662fcreateShortlink\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u7684\u521b\u5efa\u5355\u4e2a\u7684\u65b9\u6cd5\uff0c\u8fd9\u6837\u7684\u8bdd\u6211\u4eec\u628a\u4e00\u4e9b\u4fe1\u606f\u8bf4\u767d\u90fd\u662f\u53ef\u4ee5\u590d\u7528\u7684\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u901a\u8fc7BeanUtil.toBean\u5f62\u5f0f\u5c06\u8fd9\u4e9b\u4fe1\u606f\u521b\u5efa\u6210shortLinkCreateReqDTO\u5c31\u662f\u5355\u4e2a\u521b\u5efa\u7684\u4e00\u4e2adto\uff1b\u7136\u540e\u628a\u6211\u4eec\u72ec\u7acb\u53bb\u5224\u65ad\u7684\u6bd4\u5982\u8bf4\u539f\u59cb\u94fe\u63a5\u548c\u6807\u9898\u6211\u4eec\u7ed9\u5b83\u4e0b\u8f7d\u8fdb\u53bb\uff0c\u7136\u540e\u7ecf\u8fc7create\u4e4b\u540e\u628a\u4e00\u4e9b\u4fe1\u606f\u62ff\u5230\u5f53\u505a\u8fd4\u56de\u5230\u539f\u59cb\u53c2\u6570\u8fd4\u56de\u51fa\u53bb\uff0c\u7136\u540e\u8fd4\u56de\u7684\u5982\u679c\u8bf4\u521b\u5efa\u5931\u8d25\uff0cok\u6211\u4eec\u5c31\u6253\u4e2a\u65e5\u5fd7\u4ec0\u4e48\u90fd\u4e0d\u7528\u7ba1\uff0c\u5c31\u5728\u65e5\u5fd7\u91cc\u9762\u7559\u75d5\u5c31\u53ef\u4ee5\u4e86\uff0c\u7136\u540e\u8fd9\u662f\u5b83\u7684\u4e00\u4e2a\u6574\u4f53\u7684\u4ee3\u7801\u903b\u8f91\u5c31\u6bd4\u8f83\u6e05\u6670\uff0c\u5176\u5b9e\u5b83\u672c\u8d28\u4e0a\u4f9d\u8d56\u7684\u5c31\u662f\u6211\u4eec\u5355\u4e2a\u684c\u9762\uff0c\u7136\u540e\u6211\u4eec\u8fd9\u91cc\u7684\u8bdd\u662f\u4f9d\u8d56\u4e86\u4e00\u4e0b\u963f\u91cc\u5df4\u5df4\u5f00\u6e90\u7684easy Excel\uff0c\u7136\u540e\u5176\u4ed6\u7684\u903b\u8f91\u90fd\u8fd8\u597d\uff0c\u6211\u4eec\u628a\u4ee3\u7801\u63d0\u4ea4\u4e00\u4e0b\u3002shortlinkImpl\u5982\u4e0b\u6dfb\u52a0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n    @Override\n    public ShortLinkBatchCreateRespDTO batchCreateShortLink(ShortLinkBatchCreateReqDTO requestParam) {\n        List&lt;String&gt; originUrls = requestParam.getOriginUrls();\n        List&lt;String&gt; describes = requestParam.getDescribes();\n        List&lt;ShortLinkBaseInfoRespDTO&gt; result = new ArrayList&lt;&gt;();\n        for (int i = 0; i &lt; originUrls.size(); i++) {\n            ShortLinkCreateReqDTO shortLinkCreateReqDTO = BeanUtil.toBean(requestParam, ShortLinkCreateReqDTO.class);\n            shortLinkCreateReqDTO.setOriginUrl(originUrls.get(i));\n            shortLinkCreateReqDTO.setDescribe(describes.get(i));\n            try {\n                ShortLinkCreateRespDTO shortLink = createShortLink(shortLinkCreateReqDTO);\n                ShortLinkBaseInfoRespDTO linkBaseInfoRespDTO = ShortLinkBaseInfoRespDTO.builder()\n                        .fullShortUrl(shortLink.getFullShortUrl())\n                        .originUrl(shortLink.getOriginUrl())\n                        .describe(describes.get(i))\n                        .build();\n                result.add(linkBaseInfoRespDTO);\n            } catch (Throwable ex) {\n                log.error(\"\u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u5931\u8d25\uff0c\u539f\u59cb\u53c2\u6570\uff1a{}\", originUrls.get(i));\n            }\n        }\n        return ShortLinkBatchCreateRespDTO.builder()\n                .total(result.size())\n                .baseLinkInfos(result)\n                .build();\n    }<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:https:\/\/eve2333.top\/b48e2e1c-8e21-48cd-aac1-7c7587a8ac5c\" width=\"15\"><\/p>\n\n\n\n<p>\u5728pom\u4e2d\u5206\u522b\u5bfc\u5165easyExcel&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  &lt;easyexcel.version&gt;3.1.3&lt;\/easyexcel.version&gt;\n\n&lt;dependency&gt;\n    &lt;groupId&gt;com.alibaba&lt;\/groupId&gt;\n    &lt;artifactId&gt;easyexcel&lt;\/artifactId&gt;\n    &lt;version&gt; $ {easyexcel.version}&lt;\/version&gt;\n &lt;\/dependency&gt;<\/pre>\n\n\n\n<p>&nbsp;\u63a5\u4e0b\u6765\u662f \u662f\u5404\u79cddto\u4e86\uff0c\u8fd8\u6709\u4e00\u4e2a\u65b9\u6cd5\u7c7b\u653e\u5230admin\u7684toolkit\u597d\u4e86<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.toolkit;\n\nimport com.alibaba.excel.EasyExcel;\nimport jakarta.servlet.http.HttpServletResponse;\nimport lombok.SneakyThrows;\n\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\n\n\/**\n * \u5c01\u88c5 EasyExcel \u64cd\u4f5c Web \u5de5\u5177\u65b9\u6cd5\n *\/\npublic class EasyExcelWebUtil {\n\n    \/**\n     * \u5411\u6d4f\u89c8\u5668\u5199\u5165 Excel \u54cd\u5e94\uff0c\u76f4\u63a5\u8fd4\u56de\u7528\u6237\u4e0b\u8f7d\u6570\u636e\n     *\n     * @param response \u54cd\u5e94\n     * @param fileName \u6587\u4ef6\u540d\n     * @param clazz    \u6307\u5b9a\u5199\u5165\u7c7b\n     * @param data     \u5199\u5165\u6570\u636e\n     *\/\n    @SneakyThrows\n    public static void write(HttpServletResponse response, String fileName, Class&lt;?&gt; clazz, List&lt;?&gt; data) {\n        response.setContentType(\"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet\");\n        response.setCharacterEncoding(\"utf-8\");\n        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll(\"\\\\+\", \"%20\");\n        response.setHeader(\"Content-disposition\", \"attachment;filename*=utf-8''\" + fileName + \".xlsx\");\n        EasyExcel.write(response.getOutputStream(), clazz).sheet(\"Sheet\").doWrite(data);\n    }\n}\n<\/pre>\n\n\n\n<p>&nbsp;resq\\ShortLinkBaselnfoRespDTO.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.dto.resq;\n\n\nimport com.alibaba.excel.annotation.ExcelProperty;\nimport com.alibaba.excel.annotation.write.style.ColumnWidth;\nimport com.alibaba.excel.annotation.write.style.ContentRowHeight;\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n\/**\n * \u77ed\u94fe\u63a5\u57fa\u7840\u4fe1\u606f\u54cd\u5e94\u53c2\u6570\n * \u516c\u4f17\u53f7\uff1a\u9a6c\u4e01\u73a9\u7f16\u7a0b\uff0c\u56de\u590d\uff1a\u52a0\u7fa4\uff0c\u6dfb\u52a0\u9a6c\u54e5\u5fae\u4fe1\uff08\u5907\u6ce8\uff1alink\uff09\u83b7\u53d6\u9879\u76ee\u8d44\u6599\n *\/\n@Data\n@Builder\n@AllArgsConstructor\n@NoArgsConstructor\npublic class ShortLinkBaseInfoRespDTO {\n\n    \/**\n     * \u63cf\u8ff0\u4fe1\u606f\n     *\/\n    @ExcelProperty(\"\u6807\u9898\")\n    @ColumnWidth(40)\n    private String describe;\n\n    \/**\n     * \u77ed\u94fe\u63a5\n     *\/\n    @ExcelProperty(\"\u77ed\u94fe\u63a5\")\n    @ColumnWidth(40)\n    private String fullShortUrl;\n\n    \/**\n     * \u539f\u59cb\u94fe\u63a5\n     *\/\n    @ExcelProperty(\"\u539f\u59cb\u94fe\u63a5\")\n    @ColumnWidth(80)\n    private String originUrl;\n}\n<\/pre>\n\n\n\n<p>resq\\ShortLinkBatchCreateRespDTO.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.dto.resq;\n\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u6279\u91cf\u521b\u5efa\u54cd\u5e94\u5bf9\u8c61\n *\/\n@Data\n@Builder\n@NoArgsConstructor\n@AllArgsConstructor\npublic class ShortLinkBatchCreateRespDTO {\n\n    \/**\n     * \u6210\u529f\u6570\u91cf\n     *\/\n    private Integer total;\n\n    \/**\n     * \u6279\u91cf\u521b\u5efa\u8fd4\u56de\u53c2\u6570\n     *\/\n    private List&lt;ShortLinkBaseInfoRespDTO&gt; baseLinkInfos;\n}<\/pre>\n\n\n\n<p>create\u7684<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.dto.req;\n\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport lombok.Data;\nimport org.apache.shardingsphere.sharding.exception.syntax.UnsupportedUpdatingShardingValueException;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.NoArgsConstructor;\n\nimport java.util.Date;\n\n\/**\n * \u77ed\u94fe\u63a5\u521b\u5efa\u8bf7\u6c42\u5bf9\u8c61\n *\/\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\n@Builder\npublic class ShortLinkCreateReqDTO {\n    \/**\n     * \u57df\u540d\n     *\/\n    private String domain;\n    \/**\n     * \u539f\u59cb\u94fe\u63a5\n     *\/\n    private String originUrl;\n    \/**\n     * \u5206\u7ec4\u6807\u8bc6\n     *\/\n    private String gid;\n    \/**\n     * \u521b\u5efa\u7c7b\u578b\uff1a0\u63a5\u53e3\u521b\u5efa\uff0c1\u63a7\u5236\u53f0\u521b\u5efa\n     *\/\n    private Integer createdType;\n    \/**\n     * \u6709\u6548\u671f\u7c7b\u578b\uff1a0\u6c38\u4e45\u6709\u6548\uff0c1\u81ea\u5b9a\u4e49\n     *\/\n    private Integer validDateType;\n\n    \/**\n     * \u6709\u6548\u671f\n     *\/\n    @JsonFormat(pattern = \"yyyy-MM-dd MM:mm:ss\",timezone = \"GMT+8\")\n    private Date validDate;\n    \/**\n     * \u63cf\u8ff0\n     *\/\n    private String describe;\n}\n<\/pre>\n\n\n\n<p>shortLinkSercice&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\n *\n * @param requestParam \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u8bf7\u6c42\u53c2\u6570\n * @return \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\u8fd4\u56de\u53c2\u6570\n *\/\nShortLinkBatchCreateRespDTO batchCreateShortLink(ShortLinkBatchCreateReqDTO requestParam);<\/pre>\n\n\n\n<p>control\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\n *\/\n@PostMapping(\"\/api\/short-link\/v1\/create\/batch\")\npublic Result&lt;ShortLinkBatchCreateRespDTO&gt; batchCreateShortLink(@RequestBody ShortLinkBatchCreateReqDTO requestParam) {\n    return Results.success(shortLinkService.batchCreateShortLink(requestParam));\n}<\/pre>\n\n\n\n<p>&nbsp;resp\\ShortLinkBatchCreateRespDTO.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.dto.resp;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u6279\u91cf\u521b\u5efa\u54cd\u5e94\u5bf9\u8c61\n *\/\n@Data\n@Builder\n@NoArgsConstructor\n@AllArgsConstructor\npublic class ShortLinkBatchCreateRespDTO {\n\n    \/**\n     * \u6210\u529f\u6570\u91cf\n     *\/\n    private Integer total;\n\n    \/**\n     * \u6279\u91cf\u521b\u5efa\u8fd4\u56de\u53c2\u6570\n     *\/\n    private List&lt;ShortLinkBaseInfoRespDTO&gt; baseLinkInfos;\n}\n<\/pre>\n\n\n\n<p>project\\..\\ShortLinkBatchCreateReqDTO.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.dto.req;\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport lombok.Data;\n\nimport java.util.Date;\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u6279\u91cf\u521b\u5efa\u8bf7\u6c42\u5bf9\u8c61\n *\/\n@Data\npublic class ShortLinkBatchCreateReqDTO {\n\n    \/**\n     * \u539f\u59cb\u94fe\u63a5\u96c6\u5408\n     *\/\n    private List&lt;String&gt; originUrls;\n\n    \/**\n     * \u63cf\u8ff0\u96c6\u5408\n     *\/\n    private List&lt;String&gt; describes;\n\n    \/**\n     * \u5206\u7ec4\u6807\u8bc6\n     *\/\n    private String gid;\n\n    \/**\n     * \u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa\n     *\/\n    private Integer createdType;\n\n    \/**\n     * \u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49\n     *\/\n    private Integer validDateType;\n\n    \/**\n     * \u6709\u6548\u671f\n     *\/\n    @JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\", timezone = \"GMT+8\")\n    private Date validDate;\n}<\/pre>\n\n\n\n<p>admin\\..IShortLinkBatchCreateReqDTO.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.dto.req;\n\n\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport lombok.Data;\n\nimport java.util.Date;\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u6279\u91cf\u521b\u5efa\u8bf7\u6c42\u5bf9\u8c61\n * *\/\n@Data\npublic class ShortLinkBatchCreateReqDTO {\n\n    \/**\n     * \u539f\u59cb\u94fe\u63a5\u96c6\u5408\n     *\/\n    private List&lt;String&gt; originUrls;\n\n    \/**\n     * \u63cf\u8ff0\u96c6\u5408\n     *\/\n    private List&lt;String&gt; describes;\n\n    \/**\n     * \u5206\u7ec4\u6807\u8bc6\n     *\/\n    private String gid;\n\n    \/**\n     * \u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa\n     *\/\n    private Integer createdType;\n\n    \/**\n     * \u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49\n     *\/\n    private Integer validDateType;\n\n    \/**\n     * \u6709\u6548\u671f\n     *\/\n    @JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\", timezone = \"GMT+8\")\n    private Date validDate;\n}\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u4e1a\u52a1\u903b\u8f91\u8d70\u7684\u8fd8\u662f\u5355\u6761insert\u8bed\u53e5\uff0c&nbsp;\u8fd9\u4e2a\u6279\u91cf\u77ed\u94fe\u63a5\u6ca1\u6709\u6027\u80fd\u63d0\u5347\uff0c\u8fd8\u662f\u591a\u6b21IO\uff1b<\/p>\n\n\n\n<p>\u63d0\u5347\u7684\u7f51\u7edcIO\uff1b<\/p>\n\n\n\n<p>\u662f\u4e0d\u662f\u53ef\u4ee5\u5728\u4e00\u6b21for\u5faa\u73af\u63d2\u5165\u591a\u6761\u6570\u636e\u5e76\u5728Mapper\u4e2d\u4f7f\u7528foreach\u7684\u65b9\u5f0f\u6765\uff0c\u907f\u514d\u9891\u7e41\u7684\u8bbf\u95ee\u6570\u636e\u5e93\uff1b\u76f4\u63a5\u64cd\u4f5cmapper\u7684\u8bdd \u6dfb\u52a0\u7f13\u5b58\u600e\u4e48\u529e\uff1b\u4e0d\u5f71\u54cd \u8fd9\u4e2a uu \u7684\u610f\u601d\u662f\u7528 SQL \u4e2d\u7684\u6279\u91cf\u63d2\u5165\u800c\u5df2<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;URLEncoder.encode() \u65b9\u6cd5\u5728\u7f16\u7801\u65f6\u5c06\u7a7a\u683c\u8f6c\u6362\u4e3a +\uff0c\u662f\u56e0\u4e3a\u8fd9\u79cd\u65b9\u5f0f\u7b26\u5408 application\/x-www-form-urlencoded \u7f16\u7801\u683c\u5f0f\u7684\u89c4\u8303\u3002\u5728\u8fd9\u79cd\u7f16\u7801\u89c4\u8303\u4e2d\uff0c\u7a7a\u683c\u7528 + \u8868\u793a\uff0c\u800c\u4e0d\u662f %20\u3002\u8fd9\u662f URL \u7f16\u7801\u7684\u4e00\u79cd\u5386\u53f2\u505a\u6cd5\uff0c\u5e38\u7528\u4e8e\u8868\u5355\u6570\u636e\u7684\u7f16\u7801\u548c\u4f20\u9012\u3002<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c03\u8282\uff1a\u4fee\u590d\u77ed\u94fe\u63a5\u8df3\u8f6c\u7a7a\u6307\u9488\u95ee\u9898<\/h2>\n\n\n\n<p>\u5728\u6211\u4eec\u77ed\u94fe\u63a5\u7cfb\u7edf\u91cc\u6709\u4e00\u4e2abug\uff0c\u8fd9\u4e2a\u662f\u4e4b\u524d\u6709\u5f88\u591a\u540c\u5b66\u5728\u77e5\u8bc6\u661f\u7403\u4ee5\u53ca\u5728\u5176\u4ed6\u6e20\u9053\u7ed9\u6211\u53cd\u9988\u7684\u3002\u9996\u5148\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u77ed\u94fe\u63a5\uff0c\u6211\u4eec\u628a\u67d0\u4e2a\u5206\u7ec4\u7528\u6765\u521b\u5efa\u4e00\u4e0b\u8bd5\u8bd5\uff0c\u7136\u540e\u6211\u4eec\u9009\u62e9\u6c38\u4e45\u6709\u6548\u671f\u7684\u60c5\u51b5\u624d\u4f1a\u51fa\u95ee\u9898\u3002\u7136\u540e\u6211\u4eec\u70b9\u786e\u8ba4\uff0c\u73b0\u5728\u628a\u8fd9\u4e2a\u77ed\u94fe\u63a5\u521b\u5efa\u51fa\u6765\u4e86\uff0c\u73b0\u5728\u6211\u4eec\u8bbf\u95ee\u4e00\u4e0b\uff0cok\u662f\u53ef\u4ee5\u6b63\u5e38\u8df3\u8f6c\u5bf9\u5427\uff1f\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u5982\u679c\u8bf4\u628a\u5b83\u7ed9\u653e\u5165\u56de\u6536\u7ad9\uff0c\u7136\u540e\u6211\u4eec\u518d\u4ece\u56de\u6536\u7ad9\u7ed9\u5b83\u6062\u590d\u8fc7\u6765\uff0c\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u518d\u8bbf\u95ee\uff0c\u5c31\u4f1a\u51fa\u73b0\u4e00\u4e2a\u7cfb\u7edf\u6267\u884c\u51fa\u9519\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u770b\u4e00\u4e0b\u62a5\u9519\u4fe1\u606f\uff0c\u6839\u636e\u62a5\u9519\u7ed3\u679c\u53ef\u4ee5\u770b\u5230\u8bf4\u7684\u662fshortLinkDO.getValidDate()\u8fc7\u671f\u65f6\u95f4\u662fnull\u5bf9\u5427\uff1f\u8fd9\u4e2a\u95ee\u9898\u5f88\u5bb9\u6613\u7406\u89e3\uff0c\u56e0\u4e3a\u6211\u4eec\u8fd9\u8fb9\u662f\u6c38\u4e45\u6709\u6548\u671f\u7684\u60c5\u51b5\u4e0bvalidDate\u5b57\u6bb5\u662f\u7a7a\u7684\uff0c\u6240\u4ee5\u5b83\u6ca1\u6709\u8fc7\u671f\u65f6\u95f4\u3002\u5728\u8df3\u8f6c\u65b9\u6cd5\u8fd9\u91cc\uff0c\u5f53\u6211\u4eec\u53bb\u5224\u65ad\u5982\u679cshortLinkDO\u4e0d\u7b49\u4e8e\u7a7a\uff0c\u6216\u8005\u5b83\u7684\u8fc7\u671f\u65f6\u95f4\u5df2\u7ecf\u8fc7\u671f\u7684\u60c5\u51b5\u4e0b\uff0c\u9700\u8981\u7ed9\u5b83\u8df3\u8f6c\u5230404\u9875\u9762\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u8fd9\u8fb9\u8fd8\u8981\u52a0\u4e00\u4e2a\u5224\u65ad\uff0c\u90a3\u5c31\u662f\u8981\u5224\u65ad\u8fd9\u4e2avalidDate\u53c2\u6570\u4e0d\u7b49\u4e8e\u7a7a\uff0c\u7136\u540e\u518d\u5224\u65ad\u5b83\u7684\u8fc7\u671f\u65f6\u95f4\u662f\u5426\u5c0f\u4e8e\u5f53\u524d\u65f6\u95f4\u3002<\/p>\n\n\n\n<p>&nbsp;\u8fd9\u4e2a\u5df2\u7ecf\u6539\u8fc7\u6765\u4e86\uff0c\u5c31\u662f\u90a3\u4e2a\u4e09\u6b21\u6ce8\u91ca\u540e\u7684\u6570\u636e<br>\/\/ \u539f\u6765\u9519\u8bef\u7684\u5199\u6cd5\uff08\u5f53validDate\u4e3anull\u65f6\u4f1a\u89e6\u53d1\u7a7a\u6307\u9488\uff09<br>\/\/ if (shortLinkDO.getValidDate() != null &amp;&amp; shortLinkDO.getValidDate().before(new Date())) {<br>\/\/ \u4fee\u590d\u540e\u7684\u5199\u6cd5\uff1a\u5148\u5224\u65adshortLinkDO\u662f\u5426\u4e3anull\uff0c\u518d\u5904\u7406validDate\u7684\u53ef\u80fdnull\u60c5\u51b5<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">        \/\/stringRedisTemplate.opsForValue().set(String.format(GOTO_SHORT_LINK_KEY, fullShortUrl), shortLinkDO.getOriginUrl());\n        \/\/if (shortLinkDO != null) {\n        \/\/if (shortLinkDO.getValidDate() != null &amp;&amp; shortLinkDO.getValidDate().before(new Date())) {\n        if (shortLinkDO == null || (shortLinkDO.getValidDate() != null &amp;&amp; shortLinkDO.getValidDate().before(new Date()))) {\n            stringRedisTemplate.opsForValue().set(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, fullShortUrl), \"-\", 30, TimeUnit.MINUTES);\n            ((HttpServletResponse) response).sendRedirect(\"\/page\/notfound\");\n            return;\n        }\n        stringRedisTemplate.opsForValue().set(\n                String.format(GOTO_SHORT_LINK_KEY, fullShortUrl),\n                shortLinkDO.getOriginUrl(),\n                LinkUtil.getLinkCacheValidTime(shortLinkDO.getValidDate()), TimeUnit.MILLISECONDS\n        );\n        shortLinkStats(fullShortUrl, shortLinkDO.getGid(), request, response);\n        ((HttpServletResponse) response).sendRedirect(shortLinkDO.getOriginUrl());\n\n    } finally {\n        lock.unlock();\n    }\n}<\/pre>\n\n\n\n<p>\u7136\u540e\u6211\u4eec\u91cd\u542f\u670d\u52a1\uff0c\u8fd9\u4e2a\u65f6\u5019\u91cd\u65b0\u521b\u5efa\u77ed\u94fe\u63a5\uff0c\u8bbf\u95ee\u6d4b\u8bd5\u53ef\u4ee5\u6b63\u5e38\u8df3\u8f6c\u3002\u63a5\u7740\u6211\u4eec\u628a\u5b83\u79fb\u5165\u56de\u6536\u7ad9\uff0c\u518d\u4ece\u56de\u6536\u7ad9\u6062\u590d\u3002\u6309\u7167\u521a\u624d\u7684\u60c5\u51b5\uff0c\u73b0\u5728\u5e94\u8be5\u62a5\u9519\u7684\uff0c\u4f46\u4fee\u590d\u540e\u5c31\u6ca1\u6709\u62a5\u9519\u4e86\uff0c\u8bbf\u95ee\u6b21\u6570\u4e5f\u6b63\u786e\u66f4\u65b0\u4e3a2\u6b21\u3002\u8fd9\u4e2a\u95ee\u9898\u5c31\u89e3\u51b3\u4e86\uff0c\u5176\u5b9e\u5c31\u662f\u52a0\u4e86\u4e00\u4e2anull\u503c\u5224\u65ad\u7684\u9632\u62a4\u903b\u8f91\u3002\u8fd9\u662f\u6b20\u4e86\u5927\u5bb6\u5f88\u957f\u65f6\u95f4\u7684\u4e00\u4e2a\u95ee\u9898\uff0cface\u4fee\u590d\u4e86\u77ed\u94fe\u63a5\u8df3\u8f6c\u65f6\u7a7a\u6307\u9488\u7684\u95ee\u9898\uff0c\u73b0\u5728\u5f7b\u5e95\u89e3\u51b3\u4e86\u3002<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><img loading=\"lazy\" decoding=\"async\" height=\"386\" width=\"670\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/bbb693a8172842de9dd38a8456ef38aa.png\" alt=\"\"><\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c04\u8282\uff1a\u4fee\u590d\u77ed\u94fe\u63a5\u4fee\u6539\u6709\u9650\u671f\u540e\u65e0\u6cd5\u8df3\u8f6c\u95ee\u9898<\/h2>\n\n\n\n<p>\u8bf4\u4e00\u4e0b\u54b1\u4eec\u4e4b\u524d\u505a\u4fee\u6539\u77ed\u94fe\u63a5\u7684\u65f6\u5019\u7559\u4e0b\u6765\u7684\u4e00\u4e2a\u5c0f\u95ee\u9898\u3002\u4e4b\u524d\u505a\u4fee\u6539\u94fe\u63a5\u7684\u65f6\u5019\u53ea\u662f\u64cd\u4f5c\u6570\u636e\u5e93\u7684\u503c\uff0c\u5176\u5b9e\u5bf9\u4e8e\u7f13\u5b58\u6211\u4eec\u662f\u6ca1\u6709\u8fc7\u591a\u7684\u64cd\u4f5c\u7684\uff0c\u8fd9\u6837\u7684\u8bdd\u4f1a\u5e26\u6765\u4e00\u4e2a\u95ee\u9898\u3002\u6211\u7ed9\u5927\u5bb6\u6f14\u793a\u4e00\u4e0b\u3002\u73b0\u5728\u5148\u770b\u5f53\u524d\u7684\u77ed\u94fe\u63a5\u662f\u53ef\u4ee5\u88ab\u8bbf\u95ee\u7684\uff0c\u7136\u540e\u5982\u679c\u8bf4\u6211\u4eec\u628a\u5b83\u8bbe\u7f6e\u6210\u4e00\u4e2a\u5df2\u7ecf\u8fc7\u53bb\u7684\u6709\u6548\u671f\uff08\u5df2\u7ecf\u5931\u6548\u4e86\uff09\uff0c\u8fd9\u4e2a\u65f6\u5019\u5176\u5b9e\u5b83\u8fd8\u662f\u53ef\u4ee5\u8bbf\u95ee\u7684\uff0c\u8fd9\u660e\u663e\u5c31\u6709\u70b9\u95ee\u9898\u5bf9\u5427\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u5e94\u8be5\u600e\u4e48\u529e\uff1f\u6211\u4eec\u5e94\u8be5\u5728\u8fd9\u4e0a\u9762\u53bb\u7ed9\u4ed6\u505a\u4e00\u4e2a\u5224\u65ad\u3002<\/p>\n\n\n\n<p>\u5982\u679c\u8bf4\u5b83\u6709\u6548\u671f\u7684\u7c7b\u578b\u6216\u8005\u8bf4\u6709\u6548\u671f\u548c\u4e4b\u524d\u7684\u8bb0\u5f55\u4e0d\u4e00\u6837\u4e86\uff0c\u6211\u4eec\u9700\u8981\u5bf9\u4ed6\u628a\u4ed6\u7684\u8df3\u8f6c\u7684\u7f13\u5b58\u7ed9\u5220\u6389\uff0c\u8fd9\u6837\u7684\u8bdd\u5e94\u8be5\u662f\u4e00\u4e2a\u89e3\u51b3\u65b9\u6848\u3002\u5177\u4f53\u6765\u8bf4\u5c31\u662f\u5f53type\u4e0d\u4e00\u81f4\u6216\u8005validDate\u4e0d\u4e00\u81f4\u65f6\uff0c\u89e6\u53d1\u7f13\u5b58\u5220\u9664\u903b\u8f91\u3002\u53ef\u4ee5\u4e86\u3002\u4ed6\u4fe9\u5982\u679c\u8bf4\u6709\u4efb\u4f55\u4e00\u4e2a\u4e0d\u4e00\u81f4\uff0c\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u5e94\u8be5\u600e\u4e48\u529e\uff1f\u6211\u4eec\u5e94\u8be5\u53bb\u64cd\u4f5c\u5220\u9664GOTO_SHORT_LINK_KEY\u7684\u8bb0\u5f55\u5220\u6389\uff0c\u4e5f\u5c31\u662f\u5b83\u901a\u8fc7\u77ed\u94fe\u63a5\u8df3\u8f6c\u539f\u59cb\u94fe\u63a5\u7684\u5b58\u50a8\uff0c\u7136\u540e\u628a\u5b83\u7ed9\u5220\u6389\u518d\u91cd\u65b0\u751f\u6210\u3002\u6211\u4eec\u8fd9\u6837\u7684\u8bdd\u5e94\u8be5\u5c31\u53ef\u4ee5\u907f\u514d\u521a\u624d\u7684\u95ee\u9898\uff0cok\u6211\u4eec\u91cd\u542f\u4e00\u4e0b\u670d\u52a1\u3002\u7136\u540e\u6211\u4eec\u628a\u5b83\u7ed9\u6062\u590d\u8fc7\u6765\uff0c\u4e5f\u662fok\u7684\u3002\u53ef\u4ee5\u8df3\u8f6c\uff0c\u7136\u540e\u6211\u4eec\u518d\u6539\u6210\u81ea\u5b9a\u4e49\u7684\u65f6\u95f4\uff0c\u6bd4\u5982\u8bbe\u6210\u76f4\u63a5\u5c31\u5931\u6548\u4e86\u3002\u73b0\u5728\u8bbf\u95ee\u7684\u9875\u9762\u5c31\u662f404\uff0c\u4e3a\u4ec0\u4e48\uff1f\u662f\u56e0\u4e3a\u6211\u4eec\u628a\u5b83\u7684\u8df3\u8f6c\u7f13\u5b58\u7acb\u523b\u7ed9\u5220\u9664\u4e4b\u540e\uff0c\u76f8\u5f53\u4e8e\u5b83\u6ca1\u6709\u77ed\u94fe\u63a5\u5bf9\u5e94\u7684\u539f\u59cb\u94fe\u63a5\u7f13\u5b58\u4e86\uff0c\u8fd9\u6837\u7684\u8bdd\u5b83\u5c31\u5f97\u53bb\u6570\u636e\u5e93\u91cc\u9762\u52a0\u8f7d\uff0c\u4f46\u662f\u4ece\u6570\u636e\u5e93\u52a0\u8f7d\u7684\u65f6\u5019\u5b83\u5df2\u7ecf\u662f\u4e00\u4e2a\u8fc7\u671f\u7684\u72b6\u6001\u4e86\uff0c\u5bf9\u5427\uff1f\u5b83\u7684\u6709\u6548\u671f\u5df2\u7ecf\u8fc7\u4e86\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5bf9\u5427\uff1f\u53ea\u6709\u628a\u5b83\u52a0\u8f7d\u5230\u4e0d\u5b58\u5728\u7684\u60c5\u51b5\u91cc\u53bb\u4e86\uff0c\u6240\u4ee5\u8bf4\u5b83\u4f1a\u76f4\u63a5\u8fd4\u56de404\u3002<\/p>\n\n\n\n<p>\u5176\u5b9e\u4ed6\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5f53\u4ed6\u53bb\u505a\u53d8\u66f4\u7684\u65f6\u5019\uff0c\u6211\u7ed9\u5927\u5bb6\u6f14\u793a\u4e00\u4e0b\u3002\u7b49\u4e00\u4e0b\uff0c\u73b0\u5728\u4ed6\u5df2\u7ecf\u662f\u4e00\u4e2a404\u7684\u72b6\u6001\u5bf9\u4e0d\u5bf9\uff1f\u5df2\u7ecf\u4e0d\u5b58\u5728\u4e86\uff0c\u5047\u5982\u8bf4\u6211\u4eec\u73b0\u5728\u628a\u5b83\u6062\u590d\u4e86\u5bf9\u5427\uff1f\u4ed6\u6062\u590d\u4e86\u4e4b\u540e\u662f\u4e0d\u662f\u5c31\u53ef\u4ee5\u8df3\u8f6c\u4e86\uff1f\u73b0\u5728\u770b\u4e00\u4e0b\u662f\u4e0d\u662f\u8fd8\u662f\u4e0d\u80fd\u8df3\u8f6c\uff0c\u4e3a\u4ec0\u4e48\uff1f\u662f\u4e0d\u662f\uff1f\u56e0\u4e3a\u6211\u4eec\u8fd9\u91cc\u9762\u867d\u7136\u7ed9\u5b83\u6062\u590d\u4e86\uff0c\u4f46\u662f\u5b83\u5728\u8fd9\u91cc\u8df3\u8f6c\u7684GOTO_IS_NULL_SHORT_LINK_KEY\u7f13\u5b58\u8fd8\u5b58\u5728\uff0c\u8fd9\u91cc\u662f\u4e0d\u662f\u8fd8\u5b58\u5728\u7740\u5bf9\u4e0d\u5bf9\uff1f\u6240\u4ee5\u6211\u4eec\u5982\u679c\u628a\u4ed6\u4ece\u4e00\u4e2a\u5df2\u7ecf\u5931\u6548\u7684\u72b6\u6001\u53d8\u6210\u6709\u6548\u72b6\u6001\u65f6\uff0c\u6211\u4eec\u4e5f\u8981\u628a\u5b83\u7684\u8fd9\u6761\u65e0\u6548\u8bb0\u5f55\u7ed9\u5b83\u5220\u6389\uff0c\u5bf9\u4e0d\u5bf9\uff1f\u597d\uff0c\u6211\u4eec\u8fd9\u8fb9\u8fd8\u5f97\u518d\u52a0\u4e00\u5c42\u5224\u65ad\u903b\u8f91\u3002\u5177\u4f53\u6765\u8bf4\uff1a<\/p>\n\n\n\n<p>ShortLinkImpl\u5982\u4e0b&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Transactional(rollbackFor = Exception.class)\n@Override\npublic void updateShortLink(ShortLinkUpdateReqDTO requestParam) {\n    LambdaQueryWrapper&lt;ShortLinkDO&gt; queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class)\n            .eq(ShortLinkDO::getGid, requestParam.getGid())\n            .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n            .eq(ShortLinkDO::getDelFlag, 0)\n            .eq(ShortLinkDO::getEnableStatus, 0);\n    ShortLinkDO hasShortLinkDO = baseMapper.selectOne(queryWrapper);\n    if (hasShortLinkDO == null) {\n        throw new ClientException(\"\u77ed\u94fe\u63a5\u8bb0\u5f55\u4e0d\u5b58\u5728\");\n    }\n    ShortLinkDO shortLinkDO = ShortLinkDO.builder()\n            .domain(hasShortLinkDO.getDomain())\n            .shortUri(hasShortLinkDO.getShortUri())\n            .clickNum(hasShortLinkDO.getClickNum())\n            .favicon(hasShortLinkDO.getFavicon())\n            .createdType(hasShortLinkDO.getCreatedType())\n            .gid(requestParam.getGid())\n            .originUrl(requestParam.getOriginUrl())\n            .describe(requestParam.getDescribe())\n            .validDateType(requestParam.getValidDateType())\n            .validDate(requestParam.getValidDate())\n            .favicon(getFavicon(requestParam.getOriginUrl()))\n            .build();\n    if (Objects.equals(hasShortLinkDO.getGid(), requestParam.getGid())) {\n        LambdaUpdateWrapper&lt;ShortLinkDO&gt; updateWrapper = Wrappers.lambdaUpdate(ShortLinkDO.class)\n                .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n                .eq(ShortLinkDO::getGid, requestParam.getGid())\n                .eq(ShortLinkDO::getDelFlag, 0)\n                .eq(ShortLinkDO::getEnableStatus, 0)\n                .set(Objects.equals(requestParam.getValidDateType(), VailDateTypeEnum.PERMANENT.getType()), ShortLinkDO::getValidDate, null);\n        baseMapper.update(shortLinkDO, updateWrapper);\n    } else {\n        LambdaUpdateWrapper&lt;ShortLinkDO&gt; updateWrapper = Wrappers.lambdaUpdate(ShortLinkDO.class)\n                .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n                .eq(ShortLinkDO::getGid, hasShortLinkDO.getGid())\n                .eq(ShortLinkDO::getDelFlag, 0)\n                .eq(ShortLinkDO::getEnableStatus, 0);\n        baseMapper.delete(updateWrapper);\n        baseMapper.insert(shortLinkDO);\n    }\n\/\/\u4e0b\u9762\u662f\u65b0\u52a0\u5165\u7684\u51fd\u6570\n    if (!Objects.equals(hasShortLinkDO.getValidDateType(), requestParam.getValidDateType())\n            || !Objects.equals(hasShortLinkDO.getValidDate(), requestParam.getValidDate())) {\n        stringRedisTemplate.delete(String.format(GOTO_SHORT_LINK_KEY, requestParam.getFullShortUrl()));\n        if (hasShortLinkDO.getValidDate() != null &amp;&amp; hasShortLinkDO.getValidDate().before(new Date())) {\n            if (Objects.equals(requestParam.getValidDateType(), VailDateTypeEnum.PERMANENT.getType()) || requestParam.getValidDate().after(new Date())) {\n                stringRedisTemplate.delete(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, requestParam.getFullShortUrl()));\n            }\n        }\n    }\n}<\/pre>\n\n\n\n<p>\u8fd9\u6bb5\u4ee3\u7801\u7684\u610f\u601d\u662f\uff1a\u5982\u679c\u8bf4\u5b83\u7684\u8fc7\u671f\u65f6\u95f4\u4e0d\u7b49\u4e8e\u7a7a\uff0c\u8bc1\u660e\u5b83\u662f\u4e2a\u5e26\u6709\u6548\u671f\u7684\u77ed\u94fe\u63a5\uff0c\u800c\u4e14\u8fd9\u4e2a\u77ed\u94fe\u63a5\u662f\u5728\u5f53\u524d\u65f6\u95f4\u4e4b\u524d\u7684\uff0c\u5c31\u8bc1\u660e\u5b83\u5df2\u7ecf\u8fc7\u671f\u4e86\u7684\u8bdd\uff0c\u6211\u4eec\u8981\u5224\u65ad\uff1a\u5982\u679c\u65b0\u7684\u53c2\u6570\u662f\u6c38\u4e45\u6548\u671f\uff0c\u6216\u8005\u65b0\u7684\u6709\u6548\u671f\u65f6\u95f4\u5728\u5f53\u524d\u65f6\u95f4\u4e4b\u540e\uff0c\u5c31\u8bf4\u660e\u8fd9\u6761\u8bb0\u5f55\u73b0\u5728\u662f\u6709\u6548\u7684\uff0c\u8981\u628a\u4e4b\u524d\u5b58\u7684GOTO_IS_NULL_SHORT_LINK_KEY\u65e0\u6548\u7f13\u5b58\u7ed9\u5220\u6389\u3002\u8fd9\u6837\u7684\u8bdd\u76f8\u5f53\u4e8e\uff1a\u5982\u679c\u8bf4\u5b83\u7684\u6709\u6548\u671f\u7c7b\u578b\u662f\u6c38\u4e45\u6709\u6548\uff0c\u6216\u8005\u8bf4\u5b83\u7684\u6709\u6548\u671f\u65f6\u95f4\u5728\u5f53\u524d\u65f6\u95f4\u4e4b\u540e\uff0c\u5c31\u8bc1\u660e\u8fd9\u6761\u8bb0\u5f55\u73b0\u5728\u4e0d\u662f\u5931\u6548\u72b6\u6001\uff0c\u5982\u679c\u6709small\u7684K\u7684\u7f13\u5b58\u8bb0\u5f55\uff0c\u9ebb\u70e6\u4f60\u7ed9\u6211\u5220\u9664\u6389\uff0c\u8ba9\u7cfb\u7edf\u91cd\u65b0\u8d70\u6570\u636e\u5e93\u52a0\u8f7d\u6700\u65b0\u72b6\u6001\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u91cd\u542f\u4e00\u4e0b\u670d\u52a1\u3002\u5e94\u8be5\u5c31\u80fd\u770b\u5230\u6548\u679c\u4e86\u3002\u7136\u540e\u6211\u4eec\u518d\u53d8\u66f4\u4e00\u4e0b\u6709\u6548\u671f\uff0c\u6bd4\u5982\u53d8\u66f4\u523030\u53f7\u3002\u7b2c\u4e00\u6b21\u6bd4\u8f83\u91cd\u8981\uff0c\u6ca1\u4e8b\uff0c\u4eca\u5929\u53ef\u4ee5\u8bf4\u662f\u4ec0\u4e48\u611f\u89c9\uff1f\u54b1\u521a\u624d\u91cd\u542f8:30\u91cd\u542f\u4e86\uff0c\u4e0d\u5e94\u8be5\u6709\u95ee\u9898\u4e86\u3002\u6211\u770b\u4e00\u4e0b\u5982\u679c\u8bf4\uff0c\u5b83\u4e0d\u4e3a\u7a7a\uff0c\u5e76\u4e14\u4e4b\u524d\u7684\u8bb0\u5f55\u5b83\u7684\u6d88\u606f\u65f6\u95f4\u5927\u4e8e\u5f53\u524d\u65f6\u95f4\u7684\u3002\u7a0d\u7b49\u6211\u4eec\u5c31\u76f4\u63a5\u518d\u521b\u5efa\u4e00\u4e2a\u6d4b\u8bd5\u7528\u4f8b\u5427\u3002<\/p>\n\n\n\n<p>\u9996\u5148\u6211\u4eec\u521b\u5efa\u4e86\u4e00\u6761\u77ed\u94fe\u63a5\uff0c\u7136\u540e\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u7ed9\u5b83\u6539\u6210\u5df2\u7ecf\u662f\u4e00\u4e2a\u5931\u6548\u72b6\u6001\u7684\u8bb0\u5f55\uff0c\u6b63\u5e38\u60c5\u51b5\u4e0b\u8fd9\u4e2a\u5931\u6548\u72b6\u6001\u5e94\u8be5\u662f\u8df3\u4e0d\u8fc7\u53bb\u5bf9\u5427\uff1f\u5e94\u8be5404\u4e86\u3002\u6309\u7167\u521a\u624d\u6211\u4eec\u6ca1\u6709\u53d8\u66f4\u524d\u7684\u903b\u8f91\uff0c\u5373\u4f7f\u6211\u4eec\u7ed9\u5b83\u4fee\u6539\u6210\u6c38\u4e45\u5b58\u50a8\uff0c\u5b83\u4e5f\u4e00\u6837\u8df3\u4e0d\u8fc7\u53bb\uff0c\u4f46\u662f\u73b0\u5728\u4fee\u6539\u540e\u53ef\u4ee5\u8df3\u8f6c\u8fc7\u53bb\u5bf9\u4e0d\u5bf9\uff1f\u7136\u540e\u518d\u6bd4\u5982\u8bf4\u6211\u4eec\u7ed9\u5b83\u53d8\u66f4\u6210\u4e00\u4e2a\u6b64\u523b\u5df2\u7ecf\u8fc7\u671f\u7684\u6709\u6548\u671f\uff0c\u8fd9\u4e2a\u65f6\u5019\u5e94\u8be5\u662f\u8df3\u4e0d\u8fc7\u53bb\u7684\u3002\u6211\u4eec\u7ed9\u5b83\u53d8\u66f4\u6210\u4e00\u4e2a\u5386\u53f2\u7684\u6709\u6548\u671f\uff0c\u53d8\u66f4\u6210\u4e00\u4e2a\u4e0d\u5728\u4e4b\u524d\u7684\u8bb0\u5f55\uff0c\u540e\u671f\u4f1a\u5931\u6548\u7684\u4e00\u4e2a\u8bb0\u5f55\uff0c\u8fd9\u6837\u7684\u8bdd\u4ed6\u8fd8\u662f\u80fd\u8df3\u8fc7\u53bb\uff0c\u8fd9\u4e2a\u95ee\u9898\u5c31\u59a5\u5584\u89e3\u51b3\u4e86\u3002<\/p>\n\n\n\n<p>\u53ef\u4ee5\u770b\u5230\u770b\u7740\u6bd4\u8f83\u7b80\u5355\u7684\u4e00\u4e9b\u529f\u80fd\uff0c\u4f46\u662f\u5176\u5b9e\u80cc\u540e\u7684\u8fd9\u4e9b\u903b\u8f91\u8fd8\u662f\u6709\u4e00\u4e9b\u7684\uff0c\u4e0d\u662f\u5f88\u590d\u6742\uff0c\u4f46\u662f\u4f60\u9700\u8981\u9759\u4e0b\u5fc3\u53bb\u601d\u8003\u3002\u56e0\u4e3a\u5f53\u65f6\u6211\u4eec\u5728\u505a\u4fee\u6539\u7684\u65f6\u5019\uff0c\u662f\u4ee5\u6700\u5feb\u5b8c\u6210\u548c\u8054\u8c03\u7684\u65b9\u5f0f\u5199\u7684\uff0c\u6240\u4ee5\u8bf4\u4f1a\u9020\u6210\u4e00\u4e9b\u5c0f\u5751\u662f\u53ef\u4ee5\u7406\u89e3\u7684\uff0c\u7ed9\u81ea\u5df1\u627e\u8865\u4e00\u4e0b\u3002\u6211\u4eec\u63d0\u4ea4\u4e86\"\u4fee\u590d\u77ed\u94fe\u63a5\u4fee\u6539\u540e\u65e0\u6cd5\u8bbf\u95ee\u95ee\u9898\"\u7684\u4ee3\u7801\u53d8\u66f4\uff0c\u597d\u597d\u5b8c\u6210\u8fd9\u4e2a\u529f\u80fd\u3002<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u521b\u5efa\u7684\u65f6\u5019\u5c31\u5931\u6548\u7684\u8bdd\u597d\u50cf\u8fd8\u80fd\u8bbf\u95ee-----\u52a0\u4e00\u4e2a\u524d\u7f6e\u68c0\u9a8c\uff0c\u8fc7\u671f\u65f6\u95f4\u4e0d\u80fd\u5c0f\u4e8e\u5f53\u524d\u65f6\u95f4<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u611f\u89c9\u8fd9\u4e2a\u5224\u65ad\uff1ahasShortLinkDO.getValidDate() != null &amp;&amp; hasShortLinkDO.getValidDate().before(new Date())\u6709\u70b9\u591a\u4f59\u4e86\uff0c\u5927\u4e0d\u4e86\u7f13\u5b58\u4e2d\u6ca1\u6709GOTO_IS_NULL_SHORT_LINK_KEY\uff0c\u4e0d\u5220\u5c31\u662f\u4e86\uff1b<\/p>\n\n\n\n<p>\u5982\u679c\u5df2\u7ecf\u8fc7\u671f\u7684\u6570\u636e\uff0c\u7f13\u5b58\u4e2d\u5b58\u5728\u7a7a\u503c\u3002\u7136\u540e\u4fee\u6539\u4e3a\u4e0d\u8fc7\u671f\u6570\u636e\uff0c\u5982\u679c\u4e0d\u5220\u9664\u7a7a\u503c\uff0c\u5c31\u65e0\u6cd5\u8bbf\u95ee\u4e86<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u8fd9\u6837\u8fd8\u662f\u6709\u95ee\u9898\u5440\uff0c\u5982\u679c\u4fee\u6539\u7684\u662f\u539f\u59cb\u94fe\u63a5\uff0c\u800c\u7f13\u5b58\u8fd8\u4e0d\u53d8\u7684\u8bdd\uff0c\u8df3\u8f6c\u7684\u94fe\u63a5\u8fd8\u662f\u539f\u6765\u7684\u800c\u4e0d\u662f\u65b0\u7684&nbsp;\uff1b\u4f60\u8bf4\u7684\u662f\u5bf9\u7684\uff0c\u540e\u9762\u7684\u4ee3\u7801\u5df2\u4fee\u590d\u8be5\u95ee\u9898<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;L\uff1a\u770b\u5b8c\u611f\u89c9\u903b\u8f91\u5f88\u5947\u602a\uff0crequestParam\u662f\u91cc\u9762\u6211\u4eec\u60f3\u8981\u4fee\u6539\u7684\u6570\u636e\uff0c\u7136\u540ehasShortLink\u5c31\u662f\u6211\u4eec\u627e\u5230\u4e86\u60f3\u8981\u7684\u6570\u636e\u540e\u5c06\u4fee\u6539\u7684\u6570\u636e\u6dfb\u52a0\u8fdb\u53bb\uff08\u4e5f\u5c31\u662f\u4fee\u6539\u5b8c\u7684\u5b9e\u4f53\u5bf9\u8c61\uff09\uff0c\u90a3\u4f60\u540e\u9762\u7684\u5224\u65ad\u4e2d if\uff08xxxxx&amp;&amp;hasShortLinkDO.getValidDate().before(new Date())\uff09{ if\uff08requestParam.getValidDate.after(new Date()\uff09} \u4e0d\u662f\u77db\u76fe\u4e86\u5417\uff0c\u5df2\u7ecf\u5224\u65ad\u51fa\u5b83\u6709\u6548\u671f\u975e\u6c38\u4e45\uff0c\u5e76\u4e14\u6709\u6548\u671f\u5df2\u7ecf\u662f\u5931\u6548\uff0c\u76f4\u63a5\u5220\u9664\u7f13\u5b58\u4e0d\u5c31\u884c\u4e86\u5417<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;L\uff1a\u5982\u679c\u6709\u6761\u77ed\u94fe\u63a5\u65e9\u5c31\u8fc7\u671f\u4e86\uff0c\u7136\u540e\u4e3a\u4e86\u9632\u6b62\u7f13\u5b58\u51fb\u7a7f\uff08\u5728restoreUrl\u91cc\uff09\u4f1a\u5728redis\u91cc\u8bbe\u7f6egotoShortLinkIsNullKey\u3002\u6b64\u65f6\u901a\u8fc7\u4fee\u6539\u671f\u9650\u4f7f\u94fe\u63a5\u6062\u590d\u6709\u6548\u6027\uff0c\u5982\u679c\u4e0d\u5220\u9664gotoShortLinkIsNullKey\uff0c\u8fd8\u662f\u65e0\u6cd5\u8bbf\u95ee\u3002<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>if (!Objects.equals(hasShortLinkDO.getValidDateType(), requestParam.getValidDateType()) || !Objects.equals(hasShortLinkDO.getValidDate(), requestParam.getValidDate())) { if (Objects.equals(requestParam.getValidDateType(), 0) || (requestParam.getValidDate() != null &amp;&amp; requestParam.getValidDate().after(new Date()))) stringRedisTemplate.delete(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, requestParam.getFullShortUrl())); else stringRedisTemplate.delete(String.format(GOTO_SHORT_LINK_KEY, requestParam.getFullShortUrl())); }\u7c7b\u578b\u4e3a\u6c38\u4e45\u6216\u8005\u65f6\u95f4\u5927\u4e8e\u5f53\u524d\u65f6\u95f4\u5219\u8bf4\u660e\u662f\u73b0\u5728\u662f\u53ef\u7528\u7684,\u5c31\u628aGOTO_IS_NULL_SHORT_LINK_KEY\u7f13\u5b58\u5220\u9664\u4e86,\u5176\u4ed6\u60c5\u51b5\u662f\u4e0d\u53ef\u7528\u7684\uff0c\u5c31\u628aGOTO_SHORT_LINK_KEY\u5220\u9664\u3002&nbsp;<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>&nbsp;\u603b\u7ed3\u4e00\u4e0b\uff1a \u5b58\u5728\u95ee\u98981\uff1a\u5982\u679c\u628a\u77ed\u94fe\u63a5\u8bbe\u7f6e\u6210\u5931\u6548\uff0c\u77ed\u94fe\u63a5\u8fd8\u662f\u53ef\u4ee5\u8bbf\u95ee \u539f\u56e0\uff1a\u539f\u56e0\u662f\u77ed\u94fe\u63a5\u8bbe\u7f6e\u6210\u5931\u6548\u540e\uff0c\u6ca1\u6709\u628a\u7f13\u5b58\u5220\u9664\u3002 \u89e3\u51b3\u529e\u6cd5\uff1a\u6211\u4eec\u53ef\u4ee5\u5728\u5224\u65ad\u5230\u6709\u6548\u671f\u7c7b\u578b\u66f4\u6539\u6216\u8005\u6709\u6548\u671f\u66f4\u6539\u540e\u628a\u7f13\u5b58\u5220\u9664\u3002 \u5b58\u5728\u95ee\u9898 2\uff1a\u5f53\u628a\u77ed\u94fe\u63a5\u8bbe\u7f6e\u6210\u5931\u6548\u540e\uff0c\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u663e\u793a 404\uff08\u8fd9\u662f\u6b63\u5e38\u7684\uff09\uff0c\u4f46\u662f\u5f53\u6211\u4eec\u518d\u6062\u590d\u77ed\u94fe\u63a5\u540e\uff0c\u6062\u590d\u540e\u7684\u77ed\u94fe\u63a5\u4f9d\u7136\u4e0d\u53ef\u8df3\u8f6c \u539f\u56e0\uff1a \u539f\u56e0\u662f\u5f53\u6211\u4eec\u628a\u77ed\u94fe\u63a5\u8bbe\u7f6e\u6210\u5931\u6548\u540e\uff0c\u518d\u53bb\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u8fd9\u65f6\u5019\u67e5\u8be2\u7684\u77ed\u94fe\u63a5\u5df2\u7ecf\u8fc7\u671f\uff0c\u6309\u7167\u4ee5\u524d\u7684\u5224\u65ad\u903b\u8f91\uff0c\u4f1a\u628a\u8fc7\u671f\u7684\u77ed\u94fe\u63a5\u7f13\u5b58\u7a7a\u503c\u3002\u56e0\u6b64\uff0c\u5f53\u6211\u4eec\u91cd\u65b0\u628a\u77ed\u94fe\u63a5\u6062\u590d\u540e\uff0c\u7a7a\u503c\u4f9d\u7136\u5b58\u5728\uff0c\u8bbf\u95ee\u7684\u65f6\u5019\u76f4\u63a5\u6253\u5230\u7a7a\u503c\u53bb\u4e86\uff0c\u56e0\u6b64\u8fd9\u65f6\u5019\u77ed\u94fe\u63a5\u4f9d\u7136\u4e0d\u53ef\u8df3\u8f6c\u3002 \u89e3\u51b3\u529e\u6cd5\uff1a\u5982\u679c\u539f\u6765\u7684\u6709\u6548\u671f\u662f\u5df2\u8fc7\u671f\u7684\uff0c\u73b0\u5728\u8981\u628a\u5b83\u6539\u6210\u6709\u6548\uff0c\u5c31\u8981\u53bb\u5220\u9664\u7f13\u5b58\u7684\u7a7a\u503c<\/strong><\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u4e2a\u4eba\u8ba4\u4e3a\u8fd9\u91cc\u7684\u64cd\u4f5c\u5e94\u8be5\u662f\u53ea\u8981\u8fdb\u884c\u4e86\u4fee\u6539\u64cd\u4f5c(\u65e5\u671f\uff0curl\uff09\uff0c\uff0c\u5c31\u53ef\u4ee5\u5220\u9664\u8be5\u77ed\u94fe\u5728redis\u91cc\u9762\u7684\u6240\u6709\u7f13\u5b58\u4e86\u3002\u54ea\u6015\u54ea\u4e2akey\u4e0d\u5b58\u5728\uff0credis\u5220\u9664\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684key\u662f\u51e0\u4e4e\u4e0d\u5b58\u5728\u6027\u80fd\u5f00\u9500\u7684\u3002<\/p>\n\n\n\n<p>\/\/\u5bf9\u4e8e\u4fee\u6539\u4e4b\u540eredis\u7684\u5904\u7406 if (!Objects.equals(pendingShortLinkDO.getValidDateType(), requestParam.getValidDateType()) || !Objects.equals(pendingShortLinkDO.getValidDate(), requestParam.getValidDate()) || !Objects.equals(pendingShortLinkDO.getFullShortUrl() ,requestParam.getFullShortUrl()) || !Objects.equals(pendingShortLinkDO.getOriginUrl(),requestParam.getOriginUrl()) ){ stringRedisTemplate.delete(String.format(GOTO_SHORT_LINK_KEY, requestParam.getFullShortUrl())); stringRedisTemplate.delete(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, requestParam.getFullShortUrl())); }<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u5176\u5b9e\u8fd8\u6709\u4e2aBUG\u5c31\u662f\u4fee\u6539\u77ed\u8fde\u63a5\u540e\u5c31\u662f\u6211\u4e0d\u4fee\u6539\u6709\u6548\u671f\u4ec0\u4e48\u7684\uff0c\u6211\u628a\u539f\u59cb\u94fe\u63a5\u8fdb\u884c\u4fee\u6539\u540e\uff0c\u4f60\u4f1a\u53d1\u73b0\u8fdb\u884c\u8df3\u8f6c\u7684\u65f6\u5019\u5c31\u662f\u8df3\u8f6c\u7684\u8fd8\u662f\u672a\u4fee\u6539\u4e4b\u524d\u7684\u77ed\u8fde\u63a5\uff0c\u800c\u4e0d\u662f\u4fee\u6539\u540e\u7684\u539f\u59cb\u94fe\u63a5\uff0c\u662f\u56e0\u4e3a\u7f13\u5b58\u4e2d\u8fd8\u662f\u6709\u7684\uff0c\u4f60\u628a\u7f13\u5b58\u4e2d\u7684\u5220\u6389\u5c31\u597d\u4e86&nbsp;<\/p>\n\n\n\n<p>\u7b2c\u4e00\uff1a\u521b\u5efa\u7684\u65f6\u5019\u5c31\u521b\u5efa\u8fc7\u671f\u8fd9\u6837\u4e5f\u80fd\u8bbf\u95ee\u5462\uff0c\uff0c\uff0c\u7b2c\u4e8c\u8ddf\u8001\u5e08\u5199\u7684\u4e0d\u4e00\u6837\uff0c\u6211\u4e4b\u524d\u5c31\u4fee\u6539\u4e86\uff0c\u76f4\u63a5\u6dfb\u52a0\u4e00\u4e2atry finall,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.build();\ntry {\n    if (Objects.equals(hashShortLinkDO.getGid(), requestParam.getGid())) { \/\/\u8bf4\u660e\u4f20\u9012\u6765\u7684\u5206\u7ec4\u6ca1\u6709\u53d1\u751f\u53d8\u5316\n        LambdaUpdateWrapper&lt;ShortLinkDO&gt; updateWrapper = Wrappers.lambdaUpdate(ShortLinkDO.class)\n            .eq(ShortLinkDO::getGid, requestParam.getGid())\n            .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n            .eq(ShortLinkDO::getDelFlag, val: 0)\n            .eq(ShortLinkDO::getEnableStatus, val: 0)\n            .set(Objects.equals(requestParam.getValidDate(), validDateTypeEnum.PERMANENT.getType()), ShortLinkDO::getValidDate, requestParam.getValidDate());\n        baseMapper.update(build, updateWrapper);\n    } else { \/\/\u8bf4\u660e\u4f20\u9012\u6765\u7684\u5206\u7ec4\u4e5f\u53d1\u751f\u4e86\u53d8\u5316\n        LambdaQueryWrapper&lt;ShortLinkDO&gt; wrapper = Wrappers.lambdaQuery(ShortLinkDO.class)\n            .eq(ShortLinkDO::getGid, hashShortLinkDO.getGid())\n            .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n            .eq(ShortLinkDO::getDelFlag, val: 0)\n            .eq(ShortLinkDO::getEnableStatus, val: 0);\n        baseMapper.delete(wrapper);\n        baseMapper.insert(build);\n    }\n} finally {\n    \/\/\u540c\u65f6\u5c06\u8fd9\u4e2a\u539f\u5148\u7684\u7a7a\u767d\u7684redis\u7f13\u5b58\u4e5f\u7ed9\u5220\u6389...\u8fd9\u91cc\u5c31\u4e0d\u8fdb\u884c\u9884\u70ed\u4e86\uff0c\u4e00\u822c\u6765\u8bf4\u4ece\u56de\u6536\u7ad9\u79fb\u51fa\u7684\u4e5f\u6ca1\u6709\u591a\u5927\u7684\u70ed\u5ea6\u6d41\u91cf\n    stringRedisTemplate.delete(String.format(RedisKeyConstant.GOTO_SHORT_LINK_KEY, requestParam.getFullShortUrl()));\n    stringRedisTemplate.delete(String.format(RedisKeyConstant.GOTO_IS_NULL_LINK_KEY, requestParam.getFullShortUrl()));\n}<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1\" height=\"1\" src=\"https:\/\/eve2333.top\/wp-content\/uploads\/2025\/07\/1752804478-image.gif\" alt=\"\" class=\"wp-image-1218\" title=\"\u70b9\u51fb\u5e76\u62d6\u62fd\u4ee5\u79fb\u52a8\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>@Override\npublic ShortLinkCreateRespDTO createShortLink(ShortLinkCreateReqDTO requestParam) {\n    if ((requestParam.getValidDateType() != 0 &amp;&amp; Objects.equals(requestParam.getValidDate(), null)) \/\/\u5982\u679c\u9009\u62e9\u81ea\u5b9a\u4e49\u65f6\u95f4\uff0c\u5e76\u4e14\u4f20\u5165\u7684\u65f6\u95f4\u4e3a\u7a7a-\u62a5\u9519\n        || (!Objects.equals(requestParam.getValidDate(), null) &amp;&amp; requestParam.getValidDate().before(new Date()))) { \/\/\u5982\u679c\u4f20\u5165\u7684\u65f6\u95f4\u4e0d\u7b49\u4e8e\u7a7a\uff0c\u5e76\u4e14\u4f20\u5165\u7684\u65f6\u95f4\u5c0f\u4e8e\u5f53\u524d\u65f6\u95f4-\u62a5\u9519\n        throw new ClientException(\"\u81ea\u5b9a\u4e49\u8fc7\u671f\u65f6\u95f4\u4e0d\u80fd\u4e3a\u7a7a\u4e14\u4e0d\u80fd\u5c0f\u4e8e\u5f53\u524d\u65f6\u95f4\");\n    }\n}<\/code><\/pre>\n<\/blockquote>\n\n\n\n<p>pv\u548cuv\u7684\u95ee\u9898\u5728\u5199\u7684\u65f6\u5019\u5df2\u4fee\u6539&nbsp;<\/p>\n\n\n\n<p>\u8fd9\u91cc\u6709\u4e00\u5927\u524d\u7aef\u7ec6\u5fae\u5904\u7684\u4fee\u6539\uff0c\u53ef\u76f4\u63a5git\u770b\u4e0b\u8df3\u8fc7\u5373\u53ef\uff0c\u6211\u53ef\u4ee5\u5728\u6839\u76ee\u5f55\u4e0b\u9762\u65b0\u4e00\u4e2aresource\/database\uff0c\u6765\u52a0\u4e0a\u63cf\u8ff0link.sql<\/p>\n\n\n\n<p>fix\uff1a\u4fee\u590d\u77e5\u94fe\u63a5\u8bbf\u95ee\u8bb0\u5f55\u4e2d\u7684\u8bbf\u5ba2\u7c7b\u578b\u5b57&nbsp; &nbsp; &nbsp; &nbsp;ShortLinkStatsServicelmpl.java\u7edf\u7edf\u53d8\u6210\u8fd9\u4e2a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.map(item -&gt; item.get(\"uvType\"))<\/p>\n\n\n\n<p>\u5728\u8fd9\u91cc\u67092\u9879\u540e\u7aef\u4e0a\u7684\u7684\u4fee\u6539\uff0c\u5c31\u662f\u5408\u5e76\u5230\u4e3b\u7ebf\u4e0a\uff1bb76f44b - Merge branch 'main' ...(17 files)&nbsp; \u8fd8\u6709&nbsp; ac44d71 - Merge branch 'main' .. (3 files)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c05\u8282\uff1a\u77ed\u94fe\u63a5\u53d8\u66f4\u5206\u7ec4\u8bb0\u5f55\u529f\u80fd<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"oPsYU\">\u4e4b\u524d\u6f0f\u6d1e<\/h3>\n\n\n\n<p id=\"udf760fb8\">\u4e4b\u524d\u7684\u4ee3\u7801\u903b\u8f91\uff0c\u5982\u679c\u5b58\u5728\u77ed\u94fe\u63a5\u8bb0\u5f55\u4fee\u6539\u5206\u7ec4\uff0c\u90a3\u4e48\u5c31\u4f1a\u53d8\u6210\u77ed\u94fe\u63a5\u8bb0\u5f55\u4e0d\u5b58\u5728\u95ee\u9898\u3002<\/p>\n\n\n\n<pre id=\"gqNcW\" class=\"wp-block-code\"><code>LambdaQueryWrapper&lt;ShortLinkDO&gt; queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class)\n        .eq(ShortLinkDO::getGid, requestParam.getGid())\n        .eq(ShortLinkDO::getFullShortUrl, requestParam.getFullShortUrl())\n        .eq(ShortLinkDO::getDelFlag, 0)\n        .eq(ShortLinkDO::getEnableStatus, 0);\nShortLinkDO hasShortLinkDO = baseMapper.selectOne(queryWrapper);\nif (hasShortLinkDO == null) {\n    throw new ClientException(\"\u77ed\u94fe\u63a5\u8bb0\u5f55\u4e0d\u5b58\u5728\");\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">&nbsp;\u65b9\u6cd5\u6267\u884c\u903b\u8f91<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"qrmpH\">1. \u5220\u9664\u539f\u59cb\u77ed\u94fe\u63a5\u8bb0\u5f55<\/h3>\n\n\n\n<p id=\"u02619d10\">\u5982\u679c\u8bf4\u6211\u4eec\u7684\u8fd9\u4e2aGID\u53d8\u66f4\u4e86\u4e4b\u540e\uff0c\u56e0\u4e3a\u6839\u636eGID\u8fdb\u884c\u5206\u8868\uff0c\u53ef\u80fd\u4e0d\u5b58\u5728\u539f\u59cb\u8868\u4e2d\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u4e3aShortLinkUpdateReqDTO.java \u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684gid<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u539f\u59cb\u5206\u7ec4\u6807\u8bc6\n *\/\nprivate String originGid;\n<\/pre>\n\n\n\n<p>\u7136\u540e\u6211\u4eec\u7684\u77ed\u94fe\u63a5\u903b\u8f91\u975e\u5e38\u7684\u590d\u6742\uff1b\u4ee3\u7801\u91cc\u9762\u64cd\u4f5c\u4e00\u4e0b\u8fd9\u4e2a\u903b\u8f91\u5c31\u53ef\u4ee5\u4e86\u3002\u7136\u540e\u63a5\u4e0b\u6765\u5c31\u662f\u6211\u4eec\u5efa\u7acb\u4e00\u4e2a\u53d8\u66f4\u4e0a\u9762\u8fd9\u4e2a\u9501\u5927\u5bb6\u53ef\u4ee5\u5148\u5ffd\u7565\uff1b\u9996\u5148\u7b2c\u4e00\u6b65\u5bf9\u5427\uff1f\u6211\u4eec\u5c06\u4e4b\u524d\u7684\u8868\u8bb0\u5f55\u7ed9\u4ed6\u7f6e\u4e3a\u5927\u5bb6flag\u5bf9\u5427\uff1f\u4fee\u6539\u4e00\u4e0b\uff0c\u7136\u540e\u6211\u4eec\u518d\u7ed9\u4ed6\u8fdb\u884c\u65b0\u589e\u4e00\u4e0b\uff0c\u8fd9\u6837\u7684\u8bdd\u5b83\u5c31\u76f8\u5f53\u4e8e\u5728\u4e24\u4e2a\u8868\u91cc\u9762\u4f1a\u64cd\u4f5c\u4e24\u4e2a\u8868\u8bb0\u5f55\u53ef\u80fd\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"KvIYp\">2. \u4fee\u6539\u552f\u4e00\u7d22\u5f15<\/h3>\n\n\n\n<p>\u7b2c\u4e8c\u70b9\u7684\u8bdd\u90a3\u5c31\u662f\u4fee\u6539\u4e3a\u7d22\u5f15\uff0c\u6211\u4eec\u4e4b\u524d\u552f\u4e00\u7d22\u5f15\u662f\u5efa\u7684\u5305\u62ec\u8bf4\u548c\uff0cURL\u5bf9\u5427\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u4e3a\u4ec0\u4e48\u8981\u4fee\u6539\u8fd9\u4e2a\u5fae\u7f29\u5f15\uff1f\u90a3\u662f\u6709\u4e00\u79cd\u53ef\u80fd\u6027\uff0c\u5c31\u662f\u6211\u4eec\u7684 gid\u5bf9\u5427\uff1f\u5047\u5982\u4f60\u53d8\u66f4\u4e86\uff0c\u4ed6\u53ef\u80fd\u8fd8\u662f\u4f1a\u5f55\u5165\u5230\u5f53\u524d\u7684\u8868\uff0c\u8fd9\u6837\u7684\u8bdd\u5047\u5982\u8bf4\u6211\u4e4b\u524d\u5df2\u7ecf\u6709\u8fd9\u6837\u7684\u65b9\u5f0f\u63a8\u5b8c\u4e86\uff0c\u4f60\u518d\u5f55\u4e00\u4e2a\u4ed6\u4e0d\u5c31\u840e\u7f29\u51b2\u7a81\u5bf9\u5427\uff1f\u6240\u4ee5\u8bf4\u662f\u4e0d\u5efa\u8bae\u7684\uff0c\u7136\u540e\u5927\u5bb6\u53ef\u80fd\u4f1a\u8bf4\u6211\u80fd\u591f\u6211\u76f4\u63a5\u5728\u4ed6\u5224\u65ad\u7684\u65f6\u5019\uff0c\u6211\u6839\u636e\u5e0c\u7684\u5206\u7247\u7684\u76f8\u5173\u7684\u4e1c\u897f\uff0c\u6211\u786e\u5b9a\u4ed6\u5728\u54ea\u4e2a\u8868\u662f\u4e0d\u662f\u5728\u5f53\u524d\u8868\u91cc\u4e0d\u5c31\u884c\u4e86\uff0c\u5bf9\u4e0d\u5bf9\uff1f<\/p>\n\n\n\n<p>\u662f\u53ef\u4ee5\u4f46\u662f\u6211\u60f3\u544a\u8bc9\u5927\u5bb6\u7684\u662f\u8fd9\u79cd\u903b\u8f91\u4e0a\u7684\u5224\u65ad\u662f\u5bf9\u4ee3\u7801\u7684\u4f18\u96c5\u4ee5\u53ca\u540e\u7eed\u7684\u6269\u5c55\u4f1a\u6709\u4e00\u5b9a\u7684\u8f7b\u677e\u6027\uff0c\u4f60\u60f3\u4e4b\u524d\u6211\u4eec\u5206\u914d\u7684\u903b\u8f91\u53ea\u5728\u6c99\u8fea\u65af\u6807\u7684\u5e95\u5c42\u7684\u5206\u6790\u7b97\u6cd5\u91cc\u9762\uff0c\u6709\u7528\u5230\u4f60\u5c06\u6765\u4f60\u5728\u8fd9\u91cc\u9762\u5c31\u662f\u5728\u4e1a\u52a1\u91cc\u9762\u53bb\u7528\u7684\u8bdd\uff0c\u90a3\u5982\u679c\u8bf4\u4f60\u7684\u4ee3\u7801\u6362\u4e2a\u4eba\u63a5\u624b\uff0c\u4eba\u5bb6\u4e0d\u77e5\u9053\u8fd9\u4e2a\u903b\u8f91\uff0c\u90a3\u5c31\u51c9\u4e86\uff0c\u6240\u4ee5\u8bf4\u8fd9\u79cd\u4fb5\u5165\u5f0f\u7684\u8fd9\u79cd\u53d8\u66f4\u6211\u4eec\u662f\u80af\u5b9a\u63a8\u8350\u7684<\/p>\n\n\n\n<p>\u7136\u540e\u5927\u5bb6\u8bf4\u9a6c\u54e5\u6211\u7528\u8fd9\u4e2adel_flag\u5bf9\u5427\uff1fdel_flag\u4e0d\u4e5f\u884c\u5bf9\u4e0d\u5bf9\uff1f\u56e0\u4e3a\u6211\u4eec\u7684\u77ed\u4fe1\u4e00\u65e6\u5220\u9664\u662f\u4e0d\u5141\u8bb8\u88ab\u91cd\u590d\u7684\u518d\u53bb\u521b\u5efa\u4e86\u5bf9\u5427\uff1f\u8fd9\u6837\u6211\u52a0\u4e2adel_flag\u5bf9\u5427\uff1f\u5b83\u53ea\u6709\u4e00\u4e2a0\u5c31\u662f\u5e26\u56de\u6765\u6b63\u5e38\u60c5\u51b5\u4e0b\uff0c\u4ed6\u662f\u5426\u8bf4\u8981\u52a0\u8fd9\u4e2adel_flagg\u7b49\u4e8e0\u5bf9\u5427\uff1f\u90a3\u662f\u53ef\u4ee5\u7684\uff0c\u7136\u540e\u4ed6\u5c31\u53d8\u6210\u4e00\u4e86\u4e4b\u540e\uff0c\u7136\u540e\u4ed6\u518d\u8fdb\u6765\u4e2a0\u4e5f\u662f\u53ef\u4ee5\u7684\u6ca1\u95ee\u9898\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4e3a\u4ec0\u4e48\u4e0d\u7528del_flag\u5bf9\u5427\uff1f\u6211\u4e3a\u4ec0\u4e48\u8981\u52a0\u4e00\u4e2aDel&nbsp;time\u5462\uff1f\u6709\u6ca1\u6709\u540c\u5b66\u77e5\u9053\u7684\u60f3\u4e00\u60f3\uff0c\u6216\u8005\u4f60\u53ef\u4ee5\u628a\u89c6\u9891\u6682\u505c\u4e00\u4e0b\uff0c\u5927\u5bb6\u770b\u5c31\u662f\u5220\u9664\u65f6\u95f4\u6233\uff0c\u5c31\u5982\u679c\u8bf4\u4f60\u5220\u9664\u4e86ok\uff0c\u628a\u5f53\u524d\u65f6\u95f4\u6233\u4f20\u8fc7\u6765\uff0c\u6709\u6ca1\u6709\u6ca1\u60f3\u5230\u5bf9\u5427\uff1f\u8fd9\u4e2a\u662f\u5927\u5bb6TM\u7684\u6807\u8bc6\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u53ef\u80fd\u4e00\u4e2a\u77ed\u94fe\u63a5\u4f1a\u88ab\u91cd\u590d\u7684\u53bb\u4f7f\u7528\uff0c\u8fd9\u4e2a\u76f8\u5f53\u662f\u4e00\u4e2a\u6269\u5c55\u529f\u80fd\uff0c\u53ef\u80fd\u6211\u4eec\u4e0d\u4f1a\u5728\u8fd9\u4e2a\u4ee3\u7801\u91cc\u9762\u53bb\u5199\uff0c\u4f46\u662f\u5927\u5bb6\u8981\u8003\u8651\u5230\u6bd4\u5982\u8bf4\u6211\u4eec\u73b0\u5728\u521b\u5efa\u51fa\u6765\u7684\u8fd9\u79cd\u77ed\u94fe\u63a5\u5bf9\u5427\uff1f<\/p>\n\n\n\n<p>\u540e\u9762\u77ed\u94fe\u63a5\u90fd\u662f\u6211\u4eec\u901a\u8fc7\u4ee3\u7801\u81ea\u52a8\u6807\u793a\u51fa\u6765\u7684\uff0c\u5bf9\u5427\uff1f\u6709\u6ca1\u6709\u8fd9\u6837\u4e00\u79cd\u4e1a\u52a1\u9700\u8981\u4f60\u53bb\u5c06\u628a\u94fe\u63a5\u7ed9\u4ed6\u81ea\u5b9a\u4e49\uff0c\u6bd4\u5982\u8bf4\u770bAAA ABA\u5bf9\u5427\uff1f\u8fd9\u6837\u7684\u8bdd\u4ed6\u4e5f\u60f3\u590d\u7528\u8fd9\u79cd\u60c5\u51b5\uff0c\u4f60\u5c31\u5f97\u4e3a\u8fd9\u4e2a\u4e1c\u897f\u53bb\u505a\u4e00\u4e9b\u9002\u914d\u5bf9\u5427\uff1f\u6211\u53ea\u544a\u8bc9\u5927\u5bb6\u7528Dell diagram\u8fd9\u79cd\u5f62\u5f0f\uff0c\u5047\u5982\u8bf4\u6211\u6709\u4e00\u4e2a\u540e\u7f00\u662fa\uff0c\u6211\u53ef\u4ee5\u91cd\u590d\u5220\u9664\uff0c\u56e0\u4e3a\u4ed6\u6bcf\u6b21\u7684 Dell time\u90fd\u662f\u4e0d\u4e00\u6837\u7684\uff0c\u6240\u4ee5\u4e0d\u4f1a\u89e6\u53d1\u552f\u4e00\u6807\u8bc6\uff0c\u56e0\u4e3a\u6211\u4eec\u9ed8\u8ba4\u53ea\u4f1a\u6709\u4e00\u6761\u6709\u6548\u7684\u8bb0\u5f55\u5b83\u5c31\u662f\u96f6\u597d\u5427\uff1f&nbsp;<\/p>\n\n\n\n<p id=\"u55ecb5ac\">\u7d22\u5f15\u6309\u7167\u76ee\u524d\u521b\u5efa\u7684 <code>full_short_url<\/code> \u5b57\u6bb5\u53ef\u80fd\u5b58\u5728\u51b2\u7a81\u3002<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"164\" width=\"1146\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/fe6b9ad7edb3396c6c8190918eb222d8.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"uab8e93ca\">\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u5b57\u6bb5\u5b58\u50a8\u5220\u9664\u65f6\u95f4\u6233 <code>del_time<\/code>\uff0c\u9632\u6b62\u552f\u4e00\u7d22\u5f15\u51b2\u7a81\u3002<\/p>\n\n\n\n<p id=\"ued5017e8\"><code>del_flag<\/code> \u4e5f\u80fd\u5b8c\u6210\u4e0a\u8ff0\u9700\u6c42\uff0c\u4e3a\u4ec0\u4e48\u8981\u5355\u72ec\u521b\u5efa\u4e2a <code>del_time<\/code>\uff1f\u65b9\u4fbf\u540e\u5e8f\u529f\u80fd\u6269\u5c55\uff1a\u5982\u679c\u60f3\u8981\u590d\u7528\u67d0\u4e2ashort-uri<\/p>\n\n\n\n<p id=\"u462af346\"><strong>\u56e0\u4e3a\u5206\u8868\u65f6\u4fee\u6539\u77ed\u94fe\u63a5\u5206\u7ec4(gid)\u8981\u5148\u5220\u9664\u518d\u65b0\u589e\uff0c\u53ef\u80fd\u5bfc\u81f4\u65b0\u589e\u7684\u77ed\u94fe\u63a5\u8def\u7531\u5230\u76f8\u540c\u7684\u8868\u5bfc\u81f4\u552f\u4e00\u7d22\u5f15\u51b2\u7a81\u3002\u65b0\u589e\u7684del_time\u548cfull_short_url\u7ec4\u6210\u552f\u4e00\u7d22\u5f15\u53ef\u4ee5\u6709\u6548\u907f\u514d\u8fd9\u79cd\u51b2\u7a81\u3002<br>\u65b0\u7684\u552f\u4e00\u7d22\u5f15\u53d8\u6210\uff1afull_short_url, del_time\u3002<\/strong><\/p>\n\n\n\n<p>\u7528url+flag\u5982\u679c\u4fee\u6539\u540e\u8fd8\u5728\u540c\u4e00\u4e2a\u8868\u4e2d\uff0c\u6700\u591a\u4f60\u5c31\u53ea\u80fd\u4fee\u6539\u8fd9\u4e00\u6b21\uff0c\u591a\u4e00\u6b21\u90fd\u6539\u4e0d\u4e86\uff0c\u7528\u4e86\u65f6\u95f4\u6233\uff0c\u60f3\u6539\u591a\u5c11\u6b21\u90fd\u53ef\u4ee5\uff1blink.sql\u91cd\u65b0\u5bfc\u5165\u4e00\u4e0b\u8bed\u53e5\u597d\u5427<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE `t_group_0`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_1`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_10`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_11`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_12`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_13`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_14`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_15`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_2`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_3`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_4`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_5`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_6`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_7`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_8`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_group_9`\n(\n    `id`          bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`         varchar(32)  DEFAULT NULL COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `name`        varchar(64)  DEFAULT NULL COMMENT '\u5206\u7ec4\u540d\u79f0',\n    `username`    varchar(256) DEFAULT NULL COMMENT '\u521b\u5efa\u5206\u7ec4\u7528\u6237\u540d',\n    `sort_order`  int(3) DEFAULT NULL COMMENT '\u5206\u7ec4\u6392\u5e8f',\n    `create_time` datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time` datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`    tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username_gid` (`gid`,`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_0`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_1`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_10`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_11`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_12`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_13`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_14`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_15`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_2`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_3`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_4`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_5`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_6`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_7`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_8`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_9`\n(\n    `id`              bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `domain`          varchar(128)                                   DEFAULT NULL COMMENT '\u57df\u540d',\n    `short_uri`       varchar(8) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `full_short_url`  varchar(128)                                   DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `origin_url`      varchar(1024)                                  DEFAULT NULL COMMENT '\u539f\u59cb\u94fe\u63a5',\n    `click_num`       int(11) DEFAULT '0' COMMENT '\u70b9\u51fb\u91cf',\n    `gid`             varchar(32)                                    DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `favicon`         varchar(256)                                   DEFAULT NULL COMMENT '\u7f51\u7ad9\u56fe\u6807',\n    `enable_status`   tinyint(1) DEFAULT NULL COMMENT '\u542f\u7528\u6807\u8bc6 0\uff1a\u542f\u7528 1\uff1a\u672a\u542f\u7528',\n    `created_type`    tinyint(1) DEFAULT NULL COMMENT '\u521b\u5efa\u7c7b\u578b 0\uff1a\u63a5\u53e3\u521b\u5efa 1\uff1a\u63a7\u5236\u53f0\u521b\u5efa',\n    `valid_date_type` tinyint(1) DEFAULT NULL COMMENT '\u6709\u6548\u671f\u7c7b\u578b 0\uff1a\u6c38\u4e45\u6709\u6548 1\uff1a\u81ea\u5b9a\u4e49',\n    `valid_date`      datetime                                       DEFAULT NULL COMMENT '\u6709\u6548\u671f',\n    `describe`        varchar(1024)                                  DEFAULT NULL COMMENT '\u63cf\u8ff0',\n    `total_pv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2PV',\n    `total_uv`        int(11) DEFAULT NULL COMMENT '\u5386\u53f2UV',\n    `total_uip`       int(11) DEFAULT NULL COMMENT '\u5386\u53f2UIP',\n    `create_time`     datetime                                       DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`     datetime                                       DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_time`        bigint(20) DEFAULT '0' COMMENT '\u5220\u9664\u65f6\u95f4\u6233',\n    `del_flag`        tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_full-short-url` (`full_short_url`,`del_time`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_access_logs`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `user`           varchar(64)  DEFAULT NULL COMMENT '\u7528\u6237\u4fe1\u606f',\n    `ip`             varchar(64)  DEFAULT NULL COMMENT 'IP',\n    `browser`        varchar(64)  DEFAULT NULL COMMENT '\u6d4f\u89c8\u5668',\n    `os`             varchar(64)  DEFAULT NULL COMMENT '\u64cd\u4f5c\u7cfb\u7edf',\n    `network`        varchar(64)  DEFAULT NULL COMMENT '\u8bbf\u95ee\u7f51\u7edc',\n    `device`         varchar(64)  DEFAULT NULL COMMENT '\u8bbf\u95ee\u8bbe\u5907',\n    `locale`         varchar(256) DEFAULT NULL COMMENT '\u5730\u533a',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_access_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `pv`             int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `uv`             int(11) DEFAULT NULL COMMENT '\u72ec\u7acb\u8bbf\u5ba2\u6570',\n    `uip`            int(11) DEFAULT NULL COMMENT '\u72ec\u7acbIP\u6570',\n    `hour`           int(3) DEFAULT NULL COMMENT '\u5c0f\u65f6',\n    `weekday`        int(3) DEFAULT NULL COMMENT '\u661f\u671f',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_access_stats` (`full_short_url`,`gid`,`weekday`,`hour`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_browser_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `cnt`            int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `browser`        varchar(64)  DEFAULT NULL COMMENT '\u6d4f\u89c8\u5668',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_browser_stats` (`full_short_url`,`gid`,`date`,`browser`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_device_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `cnt`            int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `device`         varchar(64)  DEFAULT NULL COMMENT '\u8bbf\u95ee\u8bbe\u5907',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_browser_stats` (`full_short_url`,`gid`,`date`,`device`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_0`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_1`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_10`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_11`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_12`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_13`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_14`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_15`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_2`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_3`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_4`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_5`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_6`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_7`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_8`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_goto_9`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_locale_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `cnt`            int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `province`       varchar(64)  DEFAULT NULL COMMENT '\u7701\u4efd\u540d\u79f0',\n    `city`           varchar(64)  DEFAULT NULL COMMENT '\u5e02\u540d\u79f0',\n    `adcode`         varchar(64)  DEFAULT NULL COMMENT '\u57ce\u5e02\u7f16\u7801',\n    `country`        varchar(64)  DEFAULT NULL COMMENT '\u56fd\u5bb6\u6807\u8bc6',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_locale_stats` (`full_short_url`,`gid`,`date`,`adcode`,`province`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_network_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `cnt`            int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `network`        varchar(64)  DEFAULT NULL COMMENT '\u8bbf\u95ee\u7f51\u7edc',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_browser_stats` (`full_short_url`,`gid`,`date`,`network`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_os_stats`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u5b8c\u6574\u77ed\u94fe\u63a5',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `cnt`            int(11) DEFAULT NULL COMMENT '\u8bbf\u95ee\u91cf',\n    `os`             varchar(64)  DEFAULT NULL COMMENT '\u64cd\u4f5c\u7cfb\u7edf',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_os_stats` (`full_short_url`,`gid`,`date`,`os`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_0`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_1`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_10`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_11`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_12`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_13`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_14`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_15`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_2`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_3`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_4`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_5`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_6`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_7`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_8`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_link_stats_today_9`\n(\n    `id`             bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `gid`            varchar(32)  DEFAULT 'default' COMMENT '\u5206\u7ec4\u6807\u8bc6',\n    `full_short_url` varchar(128) DEFAULT NULL COMMENT '\u77ed\u94fe\u63a5',\n    `date`           date         DEFAULT NULL COMMENT '\u65e5\u671f',\n    `today_pv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5PV',\n    `today_uv`       int(11) DEFAULT '0' COMMENT '\u4eca\u65e5UV',\n    `today_uip`      int(11) DEFAULT '0' COMMENT '\u4eca\u65e5IP\u6570',\n    `create_time`    datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`    datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`       tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_today_stats` (`full_short_url`,`gid`,`date`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_0`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716344307570487299 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_1`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1726253659068588035 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_10`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1726262175087058946 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_11`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716835884998893571 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_12`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716356833762906114 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_13`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716777589441347586 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_14`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716835562859589634 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_15`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1725312189079834626 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_2`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1726260205890691074 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_3`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716826815625977859 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_4`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716777824704053251 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_5`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716835362095034371 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_6`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716991700406161411 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_7`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1716834641844936706 DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_8`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;;\n\nCREATE TABLE `t_user_9`\n(\n    `id`            bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',\n    `username`      varchar(256) DEFAULT NULL COMMENT '\u7528\u6237\u540d',\n    `password`      varchar(512) DEFAULT NULL COMMENT '\u5bc6\u7801',\n    `real_name`     varchar(256) DEFAULT NULL COMMENT '\u771f\u5b9e\u59d3\u540d',\n    `phone`         varchar(128) DEFAULT NULL COMMENT '\u624b\u673a\u53f7',\n    `mail`          varchar(512) DEFAULT NULL COMMENT '\u90ae\u7bb1',\n    `deletion_time` bigint(20) DEFAULT NULL COMMENT '\u6ce8\u9500\u65f6\u95f4\u6233',\n    `create_time`   datetime     DEFAULT NULL COMMENT '\u521b\u5efa\u65f6\u95f4',\n    `update_time`   datetime     DEFAULT NULL COMMENT '\u4fee\u6539\u65f6\u95f4',\n    `del_flag`      tinyint(1) DEFAULT NULL COMMENT '\u5220\u9664\u6807\u8bc6 0\uff1a\u672a\u5220\u9664 1\uff1a\u5df2\u5220\u9664',\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `idx_unique_username` (`username`) USING BTREE\n) ENGINE=InnoDB AUTO_INCREMENT=1726852231086505986 DEFAULT CHARSET=utf8mb4;;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"kt8Ki\">3. \u8fc1\u79fb\u76f8\u5173\u4e1a\u52a1\u8868\u6570\u636e<\/h3>\n\n\n\n<p>\u52a0\u4e86\u4e2a\u5b57\u6bb5\uff0c\u7136\u540e\u8fc1\u53d8\u66f4\u4e86\u4e00\u4e2a\u8fd9\u4e2a\u7f29\u5f71\u5bf9\u5427\uff0c<\/p>\n\n\n\n<p id=\"u1232977c\">\u5c06\u77ed\u94fe\u63a5\u76f8\u5173\u7684\u8868\u8fdb\u884c\u6570\u636e\u4fee\u6539\uff0c\u5982\u679c\u6d89\u53ca\u5230\u5206\u7247\u884c\u4e3a\uff0c\u5148\u5220\u9664\u539f\u6709\u6570\u636e\u518d\u65b0\u589e\u3002\u5982\u679c\u4e0d\u6d89\u53ca\u5206\u7247\u884c\u4e3a\uff0c\u53ea\u9700\u8981\u4fee\u6539\u5bf9\u5e94\u7684\u6570\u636e\u5e93\u8868\u8bb0\u5f55\u5373\u53ef\u3002<\/p>\n\n\n\n<p>\u6211\u4eecgi d\u548c\u6211\u4eec\u7684\u4e00\u4e2a\u5c31\u662ffull_short_url\u662f\u8d2f\u7a7f\u6574\u4e2a\u77ed\u94fe\u63a5\u4e1a\u52a1\u7684,\u8fd9\u79cd\u60c5\u51b5\u4e0b\u600e\u4e48\u529e\uff1f\u6ca1\u6709\u5206\u8868\u7684\u8bb0\u5f55\uff0c\u6211\u4eec\u76f4\u63a5\u53bb\u7ed9\u4ed6\u6539gid\u7684\u8bb0\u5f55\uff0c\u5206\u8868\u8bb0\u5f55\u6309\u7167\u521a\u624d\u77ed\u94fe\u63a5\u7684\u6807\u8bc6\u7684\u90a3\u79cd\u65b9\u5f0f\u5148\u5220\u518d\u52a0\uff0c\u7136\u540e\u6211\u4eec\u53ef\u4ee5\u770b\u8fd9\u4e2a\u4ee3\u7801\u4f1a\u975e\u5e38\u7684\u957f\uff0c\u5bf9\u5427\uff1fToday\u5f53\u524d\u4eca\u5929\u7684\u8bbf\u95ee\u8bb0\u5f55\u5f00\u59cb\u5220\u5bf9\u5427\uff1f\u7136\u540e\u5728\u65b0\u589e\uff0c\u56e0\u4e3a\u5b83\u8fd9\u4e2a\u6570\u636e\u53ef\u80fd\u975e\u5e38\u591a\uff0c\u6240\u4ee5\u6211\u4eec\u7528\u4e86\u4e00\u4e2a\u4e09\u4e2a\u4f4d\u7f6e\u3002\u7136\u540e\u63a5\u4e0b\u6765\u5bf9\u5404\u79cd\u5f02\u578b\u589e\u751f\uff0c\u5b8c\u4e8b\u513f\u5927\u6982\u5c31\u662f\u8fd9\u4e48\u4e2a\u903b\u8f91\uff0c\u7136\u540e\u8fd9\u4e2a\u7684\u8bdd\u662f\u6ca1\u6709\u529e\u6cd5\u7684\uff0c\u56e0\u4e3a\u786e\u5b9e\u628aGDP\u653e\u8fdb\u53bb\uff0c\u56e0\u4e3aJD\u5bf9\u6211\u4eec\u4e00\u4e2a\u4e3b\u8981\u7684\u5c31\u662f\u5206\u914d\u7684\u952e\uff0c\u4f60\u5fc5\u987b\u8981\u8fd9\u4e48\u53bb\u505a\uff0c\u7136\u540e\u5b83\u7684\u4e8b\u52a1\u4f1a\u6bd4\u8f83\u957f\u4e00\u70b9\uff0c\u8fd9\u4e2a\u662f\u6ca1\u529e\u6cd5\u7684\u3002\u56e0\u4e3a\u5982\u679c\u6211\u4eec\u4e00\u65e6\u8fdb\u884c\u5e76\u884c\u64cd\u4f5c\u7684\u8bdd\uff0c\u53ef\u80fd\u4f1a\u9047\u5230\u4e00\u4e2a\u95ee\u9898\uff0c\u5c31\u662f\u90a3\u4e2a\u4e8b\u7269\u4f1a\u4e32\uff0c\u8fd9\u6837\u7684\u8bdd\u5c31\u6ca1\u6709\u529e\u6ca1\u6709\u529e\u6cd5\u8fbe\u5230\u90a3\u79cd\u56de\u7a33\u7684\u6548\u679c\u3002shortlinkImpl<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tJNJV\">4. \u5f15\u5165\u8bfb\u5199\u9501<\/h3>\n\n\n\n<p>\u4e4b\u540e\u5982\u679c\u8bf4\u6709\u7528\u6237\u8981\u53bb\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u6211\u4eec\u7edf\u8ba1\u76f8\u5173\u7684\u5206\u7ec4\u91cc\u9762\u7684\u6570\u636e\uff0c\u5bf9\u5427\uff1f\u6211\u521a\u624d\u8bf4\u7684\u8fd9\u4e9b\u90e8\u961f\u8fd9\u4e9b\u7edf\u8ba1\u8868\u91cc\u9762\u8fd8\u6709\u4e4b\u524d\u7684\u63a5\u5730\uff0c\u5047\u5982\u8bf4\u5b83\u5b9a\u578b\u4e86\u5bf9\u5427\uff1f\u6211\u4eec\u628a\u8fd9\u4e9b\u8868\u7684\u6570\u636e\u7ed9\u5b83\u5168\u90e8\u4fee\u6539\u6210\u6700\u65b0\u7684\u63a5\u5730\u4e86\uff0c\u90a3\u662f\u4e0d\u662f\u6211\u4eec\u5c31\u6ca1\u6709\u529e\u6cd5\u518d\u8fdb\u884c\u7edf\u8ba1\uff0c\u5f80\u91cc\u9762\u653e\u7684\u65f6\u5019\u5c31\u6ca1\u529e\u6cd5\u7ed9\u4ed6\u7edf\u8ba1\u6210\u6700\u65b0\u7684\u8bb0\u5f55\u4e86\uff0c\u5bf9\u4e0d\u5bf9\uff1f\u8fd9\u4e2a\u600e\u4e48\u529e\uff1f\u4f60\u4eec\u5206\u4e0d\u662f\u8d70\u5417\uff1f\u5927\u5bb6\u60f3\u60f3\u662f\u4e0d\u662f\u8981\u7528\u4ec0\u4e48\u624b\u518c\uff0c\u6bd4\u5982\u8bf4\u6211\u5728\u6211\u518d\u53bb\u4fee\u6539\u94fe\u63a5\u4e4b\u524d\uff0c\u6211\u5f15\u5165\u4e00\u4e2a\u5206\u5e03\u5f0f\u7684\u7ad9\u9501\uff0c\u7136\u540e\u6211\u8bbf\u95ee\u77ed\u94fe\u63a5\u7684\u65f6\u5019\u4e5f\u5f15\u5165\u72ec\u5360\u9501\uff0c\u8fd9\u6837\u7684\u8bdd\u4e24\u8005\u4e92\u4e0d\u5e72\u6270\u5bf9\u5427\uff1f\u56e0\u4e3a\u4ed6\u4fee\u6539\u7684\u65f6\u5019\u7edf\u8ba1\u662f\u62ff\u4e0d\u5230\u9501\u7684\uff0c\u6240\u4ee5\u8bf4\u6ca1\u6709\u95ee\u9898\uff0c\u90a3\u7edf\u8ba1\u7684\u65f6\u5019\u6211\u628a\u9501\u7ed9\u5360\u4f4f\uff0c\u4f60\u4fee\u6539\u4e0d\u4e86\u8fd9\u79cd\u662f\u4e0d\u662f\u4e5f\u6ca1\u95ee\u9898\uff1f\u6709\u51e0\u4e2a\u5f88\u5751\u7684\u5730\u65b9\uff0c\u9996\u5148\u7b2c\u4e00\u90a3\u5c31\u662f\u8fd9\u91cc\u62ff\u544a\u8bc9\u6211\u6ca1\u95ee\u9898\uff0c\u62ff\u5206\u5e03\u9501\u6ca1\u95ee\u9898\uff0c\u4f46\u662f\u6211\u5728\u7edf\u8ba1\u7684\u65f6\u5019\uff0c\u6211\u5728\u8fd9\u91cc\u6211\u5728\u7edf\u8ba1\u7684\u65f6\u5019\uff0c\u96be\u9053\u8bf4\u6211\u8981\u53bb\u62ff\u5206\u5e03\u5f0f\u89e3\u9501\u5417\u5bf9\u4e0d\u5bf9\uff1f\u6211\u62ff\u4e2a\u5206\u5e03\u5f0f\u9501\u7684\u8bdd\uff0c\u90a3\u662f\u4e0d\u662f\u610f\u5473\u7740\u6211\u4e00\u6761\u77ed\u94fe\u63a5\u53ea\u80fd\u5141\u8bb8\u4e00\u4e2a\u7528\u6237\u53bb\u8bbf\u95ee\uff0c\u540c\u4e00\u65f6\u95f4\u662f\u4e0d\u5141\u8bb8\u4e00\u4e2a\u7528\u6237\u53bb\u8bbf\u95ee\uff0c\u8fd9\u80af\u5b9a\u662f\u4e0d\u73b0\u5b9e\u7684\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u5c31\u5f97\u8fd0\u7528\u5230\u4e00\u4e9b\u624e\u5c14\u5e76\u53d1\u73b0\u7684\uff0c\u4e1c\u897f\uff0c\u8bfb\u5199\u9501\uff0c\u4ec0\u4e48\u662f\u8bfb\u5199\u9501\u5bf9\u5427\uff1f<\/p>\n\n\n\n<p>\u601d\u8003\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u77ed\u94fe\u63a5\u6b63\u5728\u4fee\u6539\u5206\u7ec4\uff0c\u8fd9\u65f6\u6709\u7528\u6237\u6b63\u5728\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u7edf\u8ba1\u76d1\u63a7\u76f8\u5173\u7684\u5206\u7ec4\u8fd8\u662f\u4e4b\u524d\u7684\u6570\u636e\uff0c\u662f\u5426\u5c31\u6d89\u53ca\u5230\u65e0\u6cd5\u6b63\u786e\u7edf\u8ba1\u76d1\u63a7\u6570\u636e\u95ee\u9898\uff1f<\/p>\n\n\n\n<p id=\"u4bc69f71\">\u5f15\u5165\u5206\u5e03\u5f0f\u9501\uff1f<\/p>\n\n\n\n<p id=\"u832df2e8\">\u5f15\u5165\u8bfb\u5199\u9501\uff1f<\/p>\n\n\n\n<p id=\"u303966c2\">\u8bfb\u5199\u9501\u662f\u4e00\u79cd\u7528\u4e8e\u7ba1\u7406\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u8bbf\u95ee\u7684\u540c\u6b65\u673a\u5236\uff0c\u5141\u8bb8\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u5171\u4eab\u8d44\u6e90\uff0c\u4f46\u5728\u5199\u5165\u65f6\u4fdd\u8bc1\u72ec\u5360\u8bbf\u95ee\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u7684\u4e00\u81f4\u6027\u548c\u5b8c\u6574\u6027\u3002<\/p>\n\n\n\n<p id=\"uf776e9ce\">\u8bfb\u5199\u9501\u5206\u4e3a\u4e24\u7c7b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8bfb\u9501\uff08\u5171\u4eab\u9501\uff09\uff1a<\/strong> \u591a\u4e2a\u7ebf\u7a0b\u53ef\u4ee5\u540c\u65f6\u83b7\u53d6\u8bfb\u9501\uff0c\u7528\u4e8e\u5e76\u53d1\u8bfb\u53d6\u5171\u4eab\u8d44\u6e90\u3002\u8bfb\u9501\u5728\u6ca1\u6709\u5199\u9501\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u88ab\u591a\u4e2a\u7ebf\u7a0b\u6301\u6709\u3002<\/li>\n\n\n\n<li><strong>\u5199\u9501\uff08\u6392\u5b83\u9501\uff09\uff1a<\/strong> \u5199\u9501\u662f\u72ec\u5360\u7684\uff0c\u4e00\u65e6\u4e00\u4e2a\u7ebf\u7a0b\u83b7\u53d6\u4e86\u5199\u9501\uff0c\u5176\u4ed6\u7ebf\u7a0b\u65e0\u6cd5\u540c\u65f6\u83b7\u53d6\u8bfb\u9501\u6216\u5199\u9501\u3002\u5199\u9501\u7528\u4e8e\u4fee\u6539\u5171\u4eab\u8d44\u6e90\uff0c\u786e\u4fdd\u5728\u5199\u5165\u65f6\u6ca1\u6709\u5176\u4ed6\u7ebf\u7a0b\u80fd\u591f\u8bbf\u95ee\u3002<\/li>\n<\/ol>\n\n\n\n<p id=\"u6317dbb2\">\u8bfb\u5199\u9501\u7684\u4f18\u52bf\u5728\u4e8e\u5b83\u5141\u8bb8\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u5171\u4eab\u8d44\u6e90\uff0c\u63d0\u9ad8\u4e86\u8bfb\u53d6\u7684\u5e76\u53d1\u6027\uff0c\u4ece\u800c\u63d0\u5347\u4e86\u6027\u80fd\u3002\u4f46\u662f\uff0c\u5728\u5199\u5165\u65f6\u5fc5\u987b\u72ec\u5360\u8d44\u6e90\uff0c\u4ee5\u786e\u4fdd\u6570\u636e\u7684\u4e00\u81f4\u6027\u3002\u8fd9\u79cd\u9501\u7684\u4f7f\u7528\u573a\u666f\u9002\u7528\u4e8e\u8bfb\u64cd\u4f5c\u9891\u7e41\uff0c\u5199\u64cd\u4f5c\u8f83\u5c11\u7684\u60c5\u51b5\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ZzrBy\">5. \u5f15\u5165\u5ef6\u8fdf\u961f\u5217<\/h3>\n\n\n\n<p id=\"u06108876\">\u5982\u679c\u7528\u6237\u6b63\u5728\u4fee\u6539\u77ed\u94fe\u63a5\u5206\u7ec4\uff0c\u56e0\u4e3a\u6d89\u53ca\u5230\u8868\u64cd\u4f5c\u5f88\u591a\uff0c\u6211\u4eec\u5047\u8bbe\u53ef\u80fd\u4f1a\u64cd\u4f5c 300ms\u3002<\/p>\n\n\n\n<p id=\"ue44cbdfb\">\u8fd9 300ms \u5185\u96be\u9053\u5c31\u4e0d\u5141\u8bb8\u7528\u6237\u8bbf\u95ee\uff1f<\/p>\n\n\n\n<p>\u6211\u7ed9\u5927\u5bb6\u770b\u4e00\u4e0b\uff0c\u9996\u5148\u6211\u4eec\u518d\u53bb\u505a\u8fd9\u4e2a\u77ed\u94fe\u63a5\u7edf\u8ba1\u7684\u65f6\u5019\uff0c\u6211\u4eec\u9996\u5148\u8981\u62ff\u5199\u9501\uff0c\u6211\u4eec\u4e0d\u662f\u7528\u8bfb\u9501\u5bf9\u5427\uff1f\u62ff\u5230\u8bfb\u9501\u4e4b\u540e\u5176\u4ed6\u4eba\u8bbf\u95ee\u4e5f\u80fd\u62ff\u5230\u8bfb\u9501\uff0c\u8fd9\u6837\u7684\u8bdd\u4ed6\u5c31\u80fd\u6b63\u5e38\u8bbf\u95ee\uff0c\u540c\u65f6\u6211\u4eec\u62ff\u5230\u8bfb\u9501\u7684\u65f6\u5019\uff0c\u4fee\u6539\u903b\u8f91\u5c31\u65e0\u6cd5\u6267\u884c\uff0c\u4f60\u770b\u5230\u6ca1\u6709\uff1f\u4ed6\u53bb\u83b7\u53d6\u5931\u8d25\uff0c\u4ed6\u4f1a\u544a\u8bc9\"\u77ed\u94fe\u63a5\u8d44\u6e90\u88ab\u5360\u7528\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5\"\uff0c\u8fd9\u79cd\u60c5\u51b5\u662f\u6bd4\u8f83\u5408\u7406\u7684\u3002\u8fd9\u6837\u5c31\u5b8c\u7f8e\u907f\u514d\u90a3\u4e2a\u95ee\u9898\u4e86\u5417\uff1f\u4e0d\u662f\u3002\u4e4b\u524d\u6211\u4eec\u83b7\u53d6\u9501\u662f\u6709\u7cfb\u7edf\u635f\u8017\u7684\uff0c\u8981\u77e5\u9053\u666e\u901a\u60c5\u51b5\u4e0b\u8bbf\u95ee\u90fd\u662f\u8bfb\u9501\u4e0d\u9700\u8981\u7ade\u4e89\uff0c\u73b0\u5728\u9700\u8981\u52a0\u9501\u76f8\u5f53\u4e8e\u53ef\u80fd\u5e26\u6765\u51e0\u6beb\u79d2\u5230\u51e0\u5341\u6beb\u79d2\u7684\u989d\u5916\u5f00\u9500\uff0c\u5927\u5bb6\u662f\u8981\u77e5\u9053\u7684\u3002\u4f46\u4e3a\u4e86\u9002\u914d\u4fee\u6539\u903b\u8f91\u6ca1\u6709\u529e\u6cd5\uff0c\u540e\u7eed\u53ef\u80fd\u4f1a\u601d\u8003\u67b6\u6784\u8bbe\u8ba1\u5347\u7ea7\u65b9\u6848\uff0c\u6bd4\u5982\u662f\u5426\u80fd\u7528\u5176\u4ed6\u65b9\u5f0f\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u5230\u65f6\u5019\u53ef\u80fd\u4f1a\u5206\u4eab\u76f8\u5173\u65b9\u6848\u3002<\/p>\n\n\n\n<p>\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u7528\u6237\u6b63\u5728\u4fee\u6539\u5206\u7ec4\uff0c\u64cd\u4f5c\u91cf\u5927\u7684\u8bdd\u53ef\u80fd\u8d85\u8fc7300\u6beb\u79d2\u3002\u5f53\u4ed6\u83b7\u53d6\u5230\u5199\u9501\u540e\uff0c\u8bfb\u9501\u5168\u90e8\u88ab\u963b\u585e\uff0c\u6b64\u65f6\u4fee\u6539\u8017\u65f6300\u6beb\u79d2\u90fd\u4e0d\u5141\u8bb8\u8bbf\u95ee\u5417\uff1f\u8fd9\u663e\u7136\u4e0d\u5408\u7406\u3002\u5982\u679c\u56e0\u4e3a\u5f02\u5e38\u60c5\u51b5\u5bfc\u81f4\u963b\u585e\u65f6\u95f4\u6269\u5927\u5230\u51e0\u79d2\uff0c\u91c7\u7528\u6b7b\u7b49\u8bfb\u9501\u7684\u65b9\u5f0f\u4f1a\u600e\u6837\uff1f\u6211\u4eec\u7684\u5e94\u7528\u5c31\u53ef\u80fd\u6302\u6389\uff0c\u56e0\u4e3a\u5f88\u591a\u7ebf\u7a0b\u88ab\u5360\u7528\u65e0\u6cd5\u5904\u7406\u65b0\u8bf7\u6c42\u3002\u90a3\u600e\u4e48\u529e\uff1f\u89e3\u51b3\u65b9\u6848\u662f\u5ef6\u8fdf\u961f\u5217\u3002\u5ef6\u8fdf\u961f\u5217\u5206\u4e3a\u4e24\u79cd\uff1a\u5185\u5b58\u7ea7\u522b\u7684\uff08\u5982JDK\u81ea\u5e26\u7684DelayQueue\uff09\u548cMQ\u7ea7\u522b\u7684\uff08\u5982RocketMQ\/RabbitMQ\uff09\u3002\u867d\u7136\u5185\u5b58\u961f\u5217\u53ef\u7528\u4f46\u4e0d\u5efa\u8bae\uff0c\u6bd4\u5982\u5806\u79ef\u51e0\u767e\u4e0a\u5343\u8bf7\u6c42\u65f6\uff0c\u5e94\u7528\u91cd\u542f\u4f1a\u5bfc\u81f4\u7edf\u8ba1\u4e22\u5931\u3002<\/p>\n\n\n\n<p>\u6700\u7ec8\u6211\u4eec\u9009\u62e9Redisson\u5c01\u88c5\u7684\u5ef6\u8fdf\u961f\u5217\u5b9e\u73b0\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class DelayShortLinkStatsProducer {\n    public void send(ShortLinkStatsRecordDTO statsRecord) {\n        RBlockingDeque&lt;ShortLinkStatsRecordDTO&gt; blockingDeque = redissonClient.getBlockingDeque(DELAY_QUEUE_STATS_KEY);\n        RDelayedQueue&lt;ShortLinkStatsRecordDTO&gt; delayedQueue = redissonClient.getDelayedQueue(blockingDeque);\n        delayedQueue.offer(statsRecord, 5, TimeUnit.SECONDS); \/\/ 5\u79d2\u5ef6\u8fdf\u6295\u9012\n    }\n}<\/code><\/pre>\n\n\n\n<p>&nbsp;\u901a\u8fc7<code>delayedQueue.offer()<\/code>\u5c06\u7edf\u8ba1\u5b9e\u4f53\u5f02\u6b65\u6295\u9012\uff0c5\u79d2\u540e\u88ab\u6d88\u8d39\u3002\u8fd9\u4e2a\u673a\u5236\u5927\u5bb6\u5e94\u8be5\u6bd4\u8f83\u719f\u6089\u3002<code>ShortLinkStatsRecordDTO<\/code>\u901a\u8fc7\u65b0\u62bd\u8c61\u7684<code>buildLinkStatsRecordAndSetUser()<\/code>\u65b9\u6cd5\u6784\u5efa\uff0c\u907f\u514d\u6d41\u6c34\u8d26\u4ee3\u7801\u91cd\u590d\u3002MQ\u7684Consumer\u7aef\uff08\u5373\u6d88\u8d39\u7aef\uff09\u4f1a\u5904\u7406\u8fd9\u4e9b\u5ef6\u8fdf\u6d88\u606f\uff0c\u5b9e\u73b0\u89e3\u8026\u7edf\u8ba1\u4e0e\u4e1a\u52a1\u903b\u8f91\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tpsJc\">6. \u56de\u6536\u7ad9\u5220\u9664<\/h3>\n\n\n\n<p id=\"u8c636490\">\u56e0\u4e3a\u52a0\u4e86 <code>del_time<\/code>\uff0c\u6240\u4ee5\u56de\u6536\u7ad9\u5220\u9664\u529f\u80fd\u4e5f\u8981\u6539\u9020\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"cPaBt\">7. \u4fee\u6539\u77ed\u94fe\u63a5\u5206\u7ec4\u67e5\u8be2\u6570\u91cf\u63a5\u53e3<\/h3>\n\n\n\n<p id=\"u0b24856a\">\u6dfb\u52a0 <code>del_flag<\/code> \u6761\u4ef6\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u8bf7\u95ee\uff1f&nbsp;\u5f53\u4fee\u6539\u77ed\u94fe\u63a5\u4fee\u6539\u5206\u7ec4\u65f6\uff0c\u5206\u7ec4ID\u4f1a\u4fee\u6539\uff0c\u7136\u540e\u4fee\u6539\u6240\u6709\u65e5\u5fd7\u8868\u7684\u5206\u7ec4\u7684\u5206\u7ec4ID\u3002\u82e5\u5728\u8fd9\u4e2d\u95f4\u7a7f\u63d2\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u8981\u4fee\u6539\u7edf\u8ba1\u4fe1\u606f\uff0c\u56e0\u4e3a\u7edf\u8ba1\u4fe1\u606f\u662f\u5206\u7ec4ID\u67e5\u627e\u7684\uff0c\u6b64\u65f6\u7edf\u8ba1\u4fe1\u606f\u8868\u8fd8\u662f\u65e7\u7684\u5206\u7ec4ID\uff0c\u5c31\u627e\u4e0d\u5230\u5bf9\u5e94\u7684\u4fe1\u606f\u3002\u8fd9\u5c31\u8981\u5f15\u5165\u5206\u5e03\u5f0f\u9501\uff0c\u5219\u540c\u4e00\u65f6\u95f4\u4ec5\u5141\u8bb8\u4e00\u4e2a\u7528\u6237\u8bbf\u95ee\uff0c\u663e\u7136\u4e0d\u73b0\u5b9e\u3002\u6240\u4ee5\u8bfb\u5199\u9501\uff0c\u4f46\u662f\u5f53\u5199\u65e5\u5fd7\u7684\u65f6\u5019\u4e0d\u5141\u8bb8\u77ed\u94fe\u63a5\u8bbf\u95ee\uff0c\u4e0d\u79d1\u5b66\uff0c\u56e0\u4e3a\u8bbf\u95ee\u66f4\u6539\u65e5\u5fd7\u4fe1\u606f\u4e0d\u91cd\u8981\uff0c\u6240\u4ee5\u653e\u5165\u5ef6\u8fdf\u961f\u5217<\/p>\n\n\n\n<p>\u5f15\u5165\u5206\u5e03\u9501\uff1f\u5982\u679c\u5728\u4fee\u6539\u77ed\u94fe\u63a5\u7684\u65f6\u5019\u7528\u5230\u5206\u5e03\u5f0f\u9501\uff0c\u90a3\u4e48\u5728\u8bbf\u95ee\u77ed\u94fe\u63a5\u7684\u65f6\u5019\u5c31\u9700\u8981\u5f15\u5165\u5206\u5e03\u5f0f\u9501\u8fdb\u884c\u89e3\u9501\uff0c\u4f1a\u9020\u6210\u540c\u4e00\u65f6\u95f4\u53ea\u5141\u8bb8\u4e00\u4e2a\u7528\u6237\u8bbf\u95ee\u7684\u540e\u679c<\/p>\n\n\n\n<p>\u5f15\u5165\u8bfb\u5199\u9501\uff1f\u53ef\u540c\u65f6\u83b7\u5f97\u8bfb\u9501\uff0c\u4f46\u662f\u5199\u9501\u662f\u72ec\u5360\u7684\uff0c\u4f46\u662f\u4f1a\u9020\u6210\u83b7\u5f97\u5199\u9501\u7684\u65f6\u5019\uff0c\u8bfb\u9501\u83b7\u53d6\u4e0d\u5230\uff0c\u90a3\u4e48\u4f1a\u5f71\u54cd\u7528\u6237\u8bbf\u95ee\u77ed\u94fe\u63a5<\/p>\n\n\n\n<p>\u8fd9 300ms \u5185\u96be\u9053\u5c31\u4e0d\u5141\u8bb8\u7528\u6237\u8bbf\u95ee\uff1f<br>1.\u8fd9\u91cc\u6ca1\u4eba\u89e3\u91ca\u4e00\u4e0b\u5417\uff1f\u6709\u6ca1\u6709\u5927\u4f6c\uff0c\u6211\u7591\u60d1\u7684\u5730\u65b9\u5c31\u662f\u8fd9\u91cc\u7684\u89e3\u51b3\u65b9\u6848\u662f\u5f15\u5165MQ\uff0c\u4f46\u662f\u95ee\u9898\u662fMQ\u5728\u5b8c\u6210\u8fd9\u4e2a\u4efb\u52a1\u7684\u65f6\u5019\u4e0d\u4e5f\u5f97\u83b7\u53d6\u5199\u9501\u5417\uff1f\uff0c\u90a3\u5982\u679c\u5728\u8fd9\u4e2a\u65f6\u5019\u7531\u7528\u6237\u8fdb\u884c\u8bbf\u95ee\uff0c\u90a3\u4e0d\u8fd8\u5f97\u662f\u8981\u8fdb\u884c\u7b49\u5f85\u5417\uff1f<br>2.\u5728\u4fee\u6539\u77ed\u94fe\u63a5\u7684\u4ee3\u7801\u90a3\u91cc\u6ca1\u6709\u770b\u89c1\u5ef6\u8fdf\u961f\u5217\uff0c\u8fd9\u4e2a\u5ef6\u8fdf\u961f\u5217\u548c\u76d1\u63a7\u90a3\u91cc\u7684\u5ef6\u8fdf\u961f\u5217\u6709\u5173\u7cfb\u5417\uff1f<\/p>\n\n\n\n<p>\u77ed\u94fe\u63a5\u8bb0\u5f55\u53d8\u66f4\u5206\u7ec4\u529f\u80fd&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;Echo\uff1a\u4e3a\u4ec0\u4e48\u8981\u5355\u72ec\u521b\u5efadel_time\uff1f\u8fd9\u91cc\u6ca1\u6709\u542c\u61c2<\/p>\n\n\n\n<p>QtdS&nbsp;\u56de\u590d&nbsp;Echo\uff1a\u7b2c\u4e00\u6b21\u53d8\u66f4\uff0c\u5982\u679c\u8def\u7531\u5230\u540c\u4e00\u5f20\u8868\uff0c\u4f1a\u51fa\u73b0\u4e00\u4e2adelFlag\u4e3a0\u7684\u8bb0\u5f55\uff0c\u5982\u679c\u7b2c\u4e8c\u6b21\u53d8\u66f4\uff0c\u5982\u679c\u8fd8\u662f\u8def\u7531\u5230\u540c\u4e00\u5f20\u8868\uff0c\u5c31\u4f1a\u51fa\u73b0\u4e24\u4e2adelFalag\u4e3a0\u7684\u8bb0\u5f55\uff0c\u4e0d\u7b26\u5408\u552f\u4e00\u7d22\u5f15\u7684\u8bbe\u8ba1<\/p>\n\n\n\n<p>Echo&nbsp;\u56de\u590d&nbsp;QtdS\uff1a\u611f\u8c22\u60a8\u7684\u56de\u590d\uff01\u4f46\u662f\u4e3a\u4ec0\u4e48\u4e0d\u76f4\u63a5\u628a\u53d8\u66f4\u524d\u7684\u8bb0\u5f55\u5220\u6389\u5462<\/p>\n\n\n\n<p>QtdS&nbsp;\u56de\u590d&nbsp;Echo\uff1a\u76f4\u63a5\u5220\u53ef\u4ee5\u89e3\u51b3\uff0c\u4f46\u4e00\u822c\u90fd\u662f\u7528\u7684\u903b\u8f91\u5220\uff0c\u4e0d\u5efa\u8bae\u771f\u5220<\/p>\n\n\n\n<p>Echo&nbsp;\u56de\u590d&nbsp;QtdS\uff1a\u8c22\u8c22\uff01<\/p>\n\n\n\n<p>Goat&nbsp;\u56de\u590d&nbsp;Echo\uff1a\u6211\u7684\u7406\u89e3\u662f \u7b2c\u4e00\u6b21\u4ed6\u53d8\u66f4\u4e4b\u540e\uff0c\u5982\u679c\u8def\u7531\u5230\u540c\u4e00\u5f20\u8868\u7684\u8bdd\uff0c\u6b64\u65f6\u8fd9\u5f20\u8868\u4e2d\u6709fullShortUrl\u76f8\u540c\u4f46\u662fdelFlag\u4e0d\u540c\u7684\u8868\uff0c\u5982\u679cfullShortUrl\u76f8\u540c\u7684\u8bdd\u5c31\u4f1a\u51fa\u73b0\u552f\u4e00\u7d22\u5f15\u78b0\u649e\uff0c\u6240\u4ee5\u9700\u8981\u52a0del_time\u7528\u6765\u552f\u4e00\u7d22\u5f15<\/p>\n\n\n\n<p>\u76ae\u86cb\u7626\u8089\u7ca5\u3002&nbsp;\u56de\u590d&nbsp;Echo\uff1a\u5c31\u662f\u6015\u6570\u636e\u627e\u4e0d\u5230,\u90a3\u4e48\u64cd\u4f5c\u5c31\u662f\u628a\u4e4b\u524d\u7684\u8868delFlag\u8bbe\u7f6e\u4e3a1,\u7136\u540e\u518d\u63d2\u5165\u4e00\u6761\u3002\u8fd9\u65f6\u5019\u63d2\u5165\u6570\u636e\u7684\u5206\u8868\u6807\u8bc6HashCode\u53d6\u4f59\u4e4b\u540e\u548c\u4e4b\u524d\u63d2\u5165\u6570\u636e\u7684\u5206\u8868\u6807\u8bc6\u53d6\u4f59\u7684HashCode\u76f8\u540c\u3002\u90a3\u4e48\u5c31\u6362\u4e00\u4e2a\u552f\u4e00\u7d22\u5f15\u3002\u4f46\u662f\u6211\u89c9\u5f97\u76f4\u63a5\u628a\u4ed6\u5220\u9664\u4e86\u4f1a\u4e0d\u4f1a\u597d\u4e00\u70b9\u3002\u56e0\u4e3a\u76f4\u63a5\u4e0d\u7528\u6362\u4e86\uff0c\u8fd9\u91cc\u4e0d\u4e00\u5b9a\u8bf4\u4e00\u5b9a\u8981\u628adelFlag\u8bbe\u7f6e\u4e3a1\u7684\u5427<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u90a3\u4e3a\u4ec0\u4e48\u4e0d\u80fd\u7981\u6b62\u4fee\u6539GID\u5462\uff0c\u5c31\u50cf\u7528\u6237\u4e0d\u80fd\u6539username\u4e00\u6837&nbsp;<\/p>\n\n\n\n<p>\u7981\u6b62\u4fee\u6539gid\u8fd9\u4e2a\u4e1a\u52a1\u96be\u907f\u514d\uff0c\u6bd4\u5982\u6211\u8981\u6062\u590d\u56de\u6536\u7ad9\u7684\u77ed\u94fe\u63a5\uff0c\u800c\u539f\u6765\u7684\u5206\u7ec4\u5df2\u7ecf\u5220\u9664\u4e86\uff0c\u90a3\u4e48\u6b64\u65f6\u4e0d\u5f97\u4e0d\u79fb\u52a8\u5230\u9ed8\u8ba4\u5206\u7ec4\u4e2d\u3002\u6709gid\uff0c\u5728\u6539gid\u65f6\u4fee\u6539DB\u6b21\u6570\u591a\uff1b\u6ca1\u6709gid\uff0c\u5728\u67e5\u8be2\u5206\u7ec4\u7edf\u8ba1\u4fe1\u606f\u65f6\u67e5\u8be2DB\u6b21\u6570\u591a\uff0c\u53ea\u80fd\u505a\u4e2a\u6743\u8861\uff0c\u65e0\u6cd5\u5b8c\u5168\u907f\u514d\u8fd9\u4e2a\u95ee\u9898\u3002<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u738b\u5c0f\u660e\uff1a\u5176\u5b9e\u6211\u89c9\u5f97\uff0c\u90a3\u4e48\u591a\u7edf\u8ba1\u8868\u91cc\u9762\uff0c\u6700\u597d\u8fd8\u662f\u4e0d\u8981\u52a0\u4e0a\u5206\u7ec4gid\uff0c\u6709\u4e00\u4e2afullShortUrl\u5c31\u591f\u4e86\uff0c\u5df2\u7ecf\u5168\u5c40\u552f\u4e00\u4e86\uff0c\u5426\u5219\u4fee\u6539\u4e00\u4e0b\u5206\u7ec4\u8981\u6539\u7684\u6570\u636e\u5e93\u6570\u636e\u592a\u591a\u4e86<\/p>\n\n\n\n<p>\u4e00\u5207\u968f\u7f18&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u5bf9\uff0c\u7edf\u8ba1\u6570\u636e\u8ddf\u77ed\u94fe\u63a5\u7ed1\u5b9a\u5c31\u597d\u4e86<\/p>\n\n\n\n<p>\u4e00\u5207\u968f\u7f18&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u4e0b\u9762\u8bc4\u8bba\u548b\u5220\u4e86\uff0c\u521a\u60f3\u56de\u590d\u4f60\u3002<\/p>\n\n\n\n<p>\u738b\u5c0f\u660e&nbsp;\u56de\u590d&nbsp;\u4e00\u5207\u968f\u7f18\uff1a\u90a3\u4e2a\u8bc4\u8bba\u60f3\u9519\u4e86 \u54c8\u54c8 \u5f53\u65f6\u770b\u4e86\u904d\u89c6\u9891\u6ca1\u6709\u7ec6\u770b\u4ee3\u7801<\/p>\n\n\n\n<p>\u4e00\u5207\u968f\u7f18&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u5927\u4f6c\u80fd\u4e0d\u80fd\u52a0\u4f60\u5fae\u4fe1\uff0c\u611f\u89c9\u4f60\u597d\u5f3a<\/p>\n\n\n\n<p>\u738b\u5c0f\u660e&nbsp;\u56de\u590d&nbsp;\u4e00\u5207\u968f\u7f18\uff1a\u597d\u7684\uff0c\u4f60\u52a0\u6211\u5427\uff0cwx:wanganwen11,\u975e\u5927\u4f6c\uff0c\u4e00\u8d77\u5b66\u4e60\u4ea4\u6d41<\/p>\n\n\n\n<p>\u590f\u5929&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u6211\u4e5f\u611f\u89c9\uff0c\u5c24\u5176\u662f\u90a3\u4e2aLog\u6570\u636e\u91cf\u975e\u5e38\u5927\u4f30\u8ba1\u51e0\u5343\u4e07\u4e0a\u4ebf\uff0c\u53bb\u4fee\u6539\u6240\u6709\u7684\u65e5\u5fd7\u4fe1\u606f\u592a\u5413\u4eba\u4e86<\/p>\n\n\n\n<p>\u5fc3\u6001\u8981\u597d\u6602&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u8fd9\u4e9b\u7edf\u8ba1\u8868\u597d\u50cf\u672c\u6765\u4e5f\u662f\u8981\u5206\u8868\u7684\uff0c\u53bb\u6389gid\u7684\u8bdd\u5427fullShortUrl\u5f53\u6210\u5206\u8868\u952e\u5e94\u8be5\u4e5f\u884c<\/p>\n\n\n\n<p>\u8302\u76db&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u611f\u89c9\u9891\u7e41\u6539\u76d1\u63a7\u65e5\u5fd7\u6709\u70b9\u602a\u602a\u7684\uff0c\u4f46\u4e0d\u8981gid\u5206\u7ec4\u76d1\u63a7\u600e\u4e48\u505a\u5462<\/p>\n\n\n\n<p>\u72ec\u6765\u72ec\u5f80&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u662f\u4e0d\u662f\u4e3a\u4e86\u5206\u7ec4\u7edf\u8ba1\u554a\uff1f<\/p>\n\n\n\n<p>PzF&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u6211\u7684\u60f3\u6cd5\u662f\u8fd9\u6837\u7684\uff1a\u5728\u6709\u8def\u7531\u8868\u8fd9\u4e2a\u4e2d\u95f4\u8868\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4e0d\u7ed9\u77ed\u94fe\u63a5\u76f8\u5173\u7684\u7edf\u8ba1\u8868\u52a0\u4e0agid\uff0c\u5bf9\u4e8e\u5355\u4e2a\u77ed\u94fe\u63a5\u7684\u7edf\u8ba1\u6570\u636e\u83b7\u53d6\uff0c\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7fullShortUrl\u6765\u8fdb\u884c\u7edf\u8ba1\u6570\u636e\u67e5\u8be2\uff08fullShortUrl\u662f\u5168\u5c40\u552f\u4e00\u7684\uff09\uff1b\u800c\u5bf9\u4e8e\u77ed\u94fe\u63a5\u7ec4\u7684\u7edf\u8ba1\uff0c\u53ef\u4ee5\u5148\u6839\u636e\u9700\u8981\u7edf\u8ba1\u7684gid\uff0c\u53bbt_link\u8868\u4e2d\u627e\u5230gid\u4e0b\u7684\u6240\u6709fullShortUrl\uff0c\u7531\u4e8egid\u662ft_link\u7684\u5206\u7247\u952e\uff0c\u540c\u4e00\u4e2a\u5206\u7ec4\u4e0b\u7684fullShortUrl\u5728\u540c\u4e00\u5f20\u5206\u8868\u4e2d\uff0c\u518d\u5229\u7528fullShortUrl\u53bb\u8fdb\u884c\u7edf\u8ba1\u6c47\u603b\uff0c\u4f46\u662f\u5bf9\u4e8e\u6574\u7ec4\u7684\u7edf\u8ba1\uff0c\u53ef\u80fd\u8fd9\u4f1a\u6bd4\u52a0\u4e0agid\u8fdb\u884c\u7edf\u8ba1\u8017\u65f6\u66f4\u957f\u4e00\u4e9b\uff0c\u56e0\u4e3a\u6d89\u53ca\u5230t_link\u8868\u3002\u6240\u4ee5\u8003\u8651\u7edf\u8ba1\u529f\u80fd\u548c\u5207\u6362\u5206\u7ec4\u529f\u80fd\u4f7f\u7528\u7684\u9891\u7387\uff0c\u7edf\u8ba1\u529f\u80fd\u4f7f\u7528\u6b21\u6570\u53ef\u80fd\u66f4\u591a\uff0c\u6240\u4ee5\u8fd8\u662f\u52a0\u4e0a\u4e86gid\uff1f<\/p>\n\n\n\n<p>\u738b\u5c0f\u660e&nbsp;\u56de\u590d&nbsp;PzF\uff1a\u6211\u7684\u60f3\u6cd5\u662f\u77ed\u94fe\u63a5\u8bbf\u95ee\u6b21\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\uff0c\u7edf\u8ba1\u6570\u636e\u975e\u5e38\u5927\uff0c\u90a3\u4e48\u4fee\u6539\u4e00\u4e0b\u5206\u7ec4\u53ef\u80fd\u662f\u51e0\u5343\u4e07\u6761\u6570\u636e\u7684\u4fee\u6539\uff0c\u8fd9\u4e2a\u5ef6\u8fdf\u592a\u5927\u4e86....\u76f8\u6bd4\u6765\u8bf4\uff0c\u7528gid\u5148\u67e5\u8be2\u4e00\u4e0b\u6240\u6709fullshorturl\uff0c\u8fd9\u70b9\u65f6\u95f4\u53ef\u80fd\u6839\u672c\u7b97\u4e0d\u4e86\u4ec0\u4e48\uff0c\u800c\u4e14\u5bf9\u4e8e\u67e5\u8be2\u7684\u6570\u636e\uff0c\u8fd8\u53ef\u4ee5\u901a\u8fc7\u505a\u7f13\u5b58\u7b49\u65b9\u5f0f\u51cf\u5c0f\u5ef6\u8fdf\uff0c\u6240\u4ee5\u6211\u5220\u9664\u4e86\u7edf\u8ba1\u8868\u7684gid\u3002\u5f53\u7136\uff0c\u4e24\u79cd\u5404\u6709\u5229\u5f0a<\/p>\n\n\n\n<p>PzF&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u55ef\u55ef\u786e\u5b9e\u4f60\u8bf4\u7684\u4e5f\u6709\u9053\u7406\uff0c\u611f\u8c22\u4f60\u63d0\u4f9b\u4e0d\u4e00\u6837\u7684\u60f3\u6cd5<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u76d1\u63a7\u8868\u4e0d\u5b58 gid \u601d\u8def\u662f\u5bf9\u7684\u3002\u4e0d\u8fc7\uff0c\u6b63\u5e38\u6765\u8bf4\uff0c\u5982\u679c\u505a\u5206\u7ec4\u76d1\u63a7\uff0c\u6309\u7167\u4f60\u7684\u8fd9\u4e2a\u8bf4\u6cd5\u884c\u4e0d\u901a\u7684\uff0c\u5047\u8bbe\u4e00\u4e2a\u5206\u7ec4\u4e0b\u5341\u4e07\u7684\u77ed\u94fe\u63a5\uff0c\u96be\u9053\u8981 in 10 \u4e07\u4e2a\u4e48\uff1f\u540e\u9762\u6211\u91cd\u6784\u4e86\u5206\u7ec4\u67e5\u8be2\uff0c\u4e5f\u662f\u628a gid \u4ece\u76d1\u63a7\u8868\u5220\u9664\uff0c\u91c7\u7528\u5185\u5173\u8054\u5f62\u5f0f\uff0c\u907f\u514d\u4e86\u63d0\u524d\u67e5\u8be2\u5206\u7ec4\u4e0b\u6240\u6709\u77ed\u94fe\u63a5\u3002<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u4e3a\u4ec0\u4e48\u8981\u52a0\u4e00\u4e2adel_time\u5b57\u6bb5\uff1f\u4e2a\u4eba\u7406\u89e3 1. \u4fee\u6539\u4e86\u5206\u7ec4\uff0c\u903b\u8f91\u5220\u9664 delFlag \u7f6e\u4e3a1\uff0c\u7136\u540e\u521b\u5efa\u65b0\u7684\u5206\u7ec4\u7684\u77ed\u94fe\u63a5\u63d2\u5165\uff0c\u6709\u53ef\u80fd\u5728\u540c\u4e00\u5f20\u8868\u4e2d\uff0c\u90a3\u4e48\u6b64\u65f6\u5c31\u8fdd\u80cc\u4e86\u552f\u4e00\u7d22\u5f15\uff0c\u6240\u4ee5\u9700\u8981\u4f18\u5316\u3002 2. \u4e3a\u4ec0\u4e48\u4e0d\u4f7f\u7528 delFlag \u5f53\u505a\u552f\u4e00\u7d22\u5f15\uff0c\u800c\u9700\u8981\u6dfb\u52a0\u4e00\u4e2adel_time\u5462\uff0c \u56e0\u4e3a\u4e00\u4e2a\u77ed\u94fe\u63a5\u4e0d\u6b62\u4f1a\u88ab\u4fee\u6539\u4e00\u6b21\uff0c\u5982\u679c\u4fee\u6539\u4e86\u591a\u6b21\uff0c\u90fd\u51fa\u73b0\u5728\u540c\u4e00\u5f20\u8868\u4e2d\uff0cdelFlag\u53ea\u67090\u548c1\uff0c\u4e5f\u4f1a\u552f\u4e00\u7d22\u5f15\u51b2\u7a81\uff0c\u6240\u4ee5\u9700\u8981\u6dfb\u52a0\u4e00\u4e2a delTime \u5b57\u6bb5\uff0c\u6765\u552f\u4e00\u7d22\u5f15\u3002&nbsp;<\/p>\n\n\n\n<p>\u90a3\u4e3a\u4ec0\u4e48\u4e0d\u76f4\u63a5\u628a\u4e4b\u524d\u90a3\u4e2a\u6570\u636e\u7269\u7406\u5220\u9664\u5462?\u5176\u5b9e\u6ca1\u5fc5\u8981\u8bf4\u4e00\u5b9a\u8981\u4fdd\u7559\u4e4b\u524d\u7684\u6570\u636e\u5427?\u63a7\u5236\u53f0\u76d1\u63a7\u7684\u6570\u636e\u4e5f\u4e0d\u4f1a\u76d1\u63a7delFlag=1\u7684\u5440\u3002\u8fd8\u662f\u4ee5\u540e\u8981\u51fa\u4e00\u4e2a\u7edf\u8ba1\u6570\u91cf\u5173\u4e8e\u7528\u6237\u5220\u9664\u4e86\u591a\u5c11\u6761\u77ed\u94fe\u63a5\u8fd9\u79cd\u4e48?\u611f\u89c9\u5982\u679c\u6ca1\u8fd9\u65b9\u9762\u4e1a\u52a1\u7684\u8bdd,\u6700\u597d\u5c31\u662f\u7269\u7406\u5220\u9664\u4e86\u3002<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u4e3a\u4ec0\u4e48\u8981\u5728\u4e00\u4e2a\u7ebf\u7a0b\u6c60\u91cc\u8fd0\u884cConsumer\u554a\uff0c\u8fd9\u8ddf\u4f46\u5f00\u4e00\u4e2a\u7ebf\u7a0b\u6709\u4ec0\u4e48\u533a\u522b\u5417\uff1f\u53ef\u4ee5\u770b\u770b\u7ebf\u7a0b\u6c60\u7684\u4f5c\u7528\uff0c\u7528\u5230\u591a\u7ebf\u7a0b\u76f4\u63a5\u521b\u5efa\u7ebf\u7a0b\u80af\u5b9a\u662f\u4e0d\u884c\u7684<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;DelayShortLinkStatsConsumer \u4e2d for\u5faa\u73af\u91ccLockSupport.parkUntil(500)\u662f\u4e0d\u662f\u6709\u95ee\u9898\uff1fparkUntil\u4f20\u5165\u7684\u53c2\u6570\u5e94\u8be5\u662f\u4e00\u4e2a\u7edd\u5bf9\u65f6\u95f4\u6233\uff0c\u5e94\u8be5\u5199\u6210LockSupport.parkUntil(System.currentTimeMillis() + 500)\u5427<\/p>\n\n\n\n<p>\u53ef\u80fd\uff0c\u8fd9\u4e2a\u6211\u7814\u7a76\u4e0b\u3002\u4e0d\u8fc7\u54b1\u4eec\u540e\u7eed\u7684\u5ef6\u65f6\u5df2\u7ecf\u6ca1\u4e86<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u5f15\u5165\u5220\u9664\u65f6\u95f4\u6233\u7684\u539f\u56e0\uff1a\u5982\u679c\u7528\u6237\u60f3\u8981\u4fee\u6539gid,\u56e0\u4e3a\u8fd9\u91ccgid\u4f5c\u4e3a\u5206\u7247\u952e\uff0c\u65b0gid\u4e0d\u4e00\u5b9a\u80fdhash\u5230\u539f\u6765\u8868\uff0c\u6240\u4ee5\u8fd9\u91cc\u7684\u601d\u8def\u662f\u5148\u903b\u8f91\u5220\u9664\u539f\u6765\u8868\u7684\u903b\u8f91\uff0c\u518d\u7ecf\u8fc7\u65b0gid\u7684\u503chash\u5230\u65b0\u8868\u65b0\u589e\u4e00\u6761\u8bb0\u5f55\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u6709\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff0c\u5c31\u662f\u539f\u6765\u77ed\u94fe\u63a5\u7ecf\u903b\u8f91\u5220\u9664\u540e\uff0c\u65b0\u7684gid\u53ef\u80fd\u8fd8\u4f1ahash\u5230\u539f\u6765\u7684\u8868\uff0c \u56e0\u4e3a\u552f\u4e00\u7d22\u5f15\u662ffull_short_url,\u6240\u4ee5\u5c31\u51fa\u9519\u4e86\uff0c\u90a3\u53ef\u80fd\u4f1a\u60f3\u518d\u5c06del_flag\u4e5f\u52a0\u5165\u7d22\u5f15\uff0c \u4f46\u662f\u5982\u679c\u8fd8\u60f3\u4fee\u6539gid\u5c31\u5fc5\u987b\u5c06del_flag\u7f6e\u4e3a1\uff0c\u5982\u679c\u8fd9\u6837\u505a\u5c31\u4f1a\u6709\u4e24\u6761\u8bb0\u5f55full_short_url\u76f8\u540c\uff0cdel_flag\u53c8\u76f8\u540c\u3002 \u90a3\u6709\u7684\u4eba\u53ef\u80fd\u4f1a\u60f3\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u628afull_short_url\u548cgid\u4f5c\u4e3a\u590d\u5408\u7d22\u5f15\uff0c\u8fd9\u4e2a\u4e5f\u4e0d\u884c\uff0c\u56e0\u4e3a\u4e00\u6761\u8bb0\u5f55\u4ece\u4e00\u4e2a\u5206\u7ec4\u79fb\u5230\u53e6\u4e00\u4e2a\u5206\u7ec4\uff0c\u6b64\u65f6\u4f1a\u903b\u8f91\u5220\u9664\uff0c\u539f\u672c\u7684\u8bb0\u5f55\u4f1a\u7559\u4e0b\u3002\u90a3\u8fd9\u8bb0\u5f55\u53c8\u79fb\u56de\u5230\u539f\u6765\u7684\u5206\u7ec4\u4e86\u5462\uff1f\u5c31\u4f1a\u56e0\u4e3a\u903b\u8f91\u5220\u9664\u7559\u4e0b\u7684\u8bb0\u5f55\uff0c\u800c\u4ea7\u751f\u51b2\u7a81&nbsp;<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u6c42\u52a9\u5927\u4f6c\u4eec\uff0c\u8fd9\u4e00\u8282\u4e0d\u662f\u5f88\u7406\u89e3\u6211\u4eec\u8981\u7528\u5230\u6d88\u606f\u961f\u5217\uff0c\u5f53\u66f4\u6539\u94fe\u63a5\u7684\u5206\u7ec4\u7684\u65f6\u5019\u4f7f\u7528\u5199\u9501\uff0c\u8fd9\u4e2a\u65f6\u5019\u7528\u6237\u662f\u65e0\u6cd5\u8bbf\u95ee\u8fd9\u4e2a\u77ed\u94fe\u63a5\u5417\uff1f\u7136\u540e\u66f4\u6539\u5b8c\u6bd5\u540e\uff0c\u7528\u6237\u53ef\u4ee5\u6b63\u5e38\u8bbf\u95ee\uff0c\u4e3a\u4ec0\u4e48\u7edf\u8ba1\u77ed\u94fe\u63a5\u7684\u4e00\u4e9b\u6570\u636e\u9700\u8981\u7528\u5230\u6d88\u606f\u961f\u5217\u554a\uff1f<\/p>\n\n\n\n<p>\u5199\u9501\u9501\u4f4f\u4e4b\u540e\uff0c\u7528\u6237\u786e\u5b9e\u65e0\u6cd5\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u4f46\u8fd9\u4e2a\u8bbf\u95ee\u9700\u6c42\u6ca1\u6709\u53d8\uff0c\u8bbf\u95ee\u5982\u679c\u4e0d\u52a0\u6d88\u606f\u961f\u5217\u5e94\u8be5\u4f1a\u4e00\u76f4\u7b49\u7740\u8fd9\u4e2a\u9501\uff0c\u8fd9\u6837\u4f1a\u5360\u7528\u8d44\u6e90\u5427\uff0c\u52a0\u4e0a\u6d88\u606f\u961f\u5217\u5c31\u53ef\u4ee5\u76f4\u63a5\u91ca\u653e\u8fd9\u4e2a\u8fdb\u7a0b\uff0c\u7136\u540e\u8ba9\u7528\u6237\u76f4\u63a5\u8bbf\u95eeoriginUrl\uff0c\u4e4b\u540e\u5728\u6d88\u606f\u961f\u5217\u91cc\u6d88\u8d39\u7edf\u8ba1\u77ed\u94fe\u63a5\u6570\u636e\u7684\u8fd9\u4e2a\u8bf7\u6c42\uff0c\u5e94\u8be5\u662f\u8fd9\u4e2a\u903b\u8f91<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u540e\u9762\u6d4b\u8bd5\u7684\u65f6\u5019\u53d1\u73b0RecycleBinServiceImpl\u8fd9\u91cc\u6709\u95ee\u9898<\/p>\n\n\n\n<p>1.\u9996\u5148\uff0c\u6211\u4eec\u6267\u884csaveRecycleBin\u5220\u9664\u4e00\u4e2a\u77ed\u94fe\u63a5\u7684\u65f6\u5019\u662f\u5148\u79fb\u52a8\u81f3\u56de\u6536\u7ad9\uff0c\u5728\u56de\u6536\u7ad9\u4e2d\u7684\u77ed\u94fe\u63a5\u6b64\u65f6del_time\u8fd8\u662f\u4e3a0\uff0c\u53ea\u662f\u4fee\u6539\u5217enable_status\u7f6e\u4e3a1\uff0c\u8fd9\u4e2a\u529f\u80fd\u6ca1\u95ee\u9898\u3002 2.\u5176\u6b21\uff0c\u5f53\u6267\u884cremoveRecycleBin\u5f7b\u5e95\u56de\u6536\u7ad9\u4e2d\u7684\u77ed\u94fe\u63a5\u4e4b\u540e\uff0c\u662f\u8ba9del_time\u8bbe\u7f6e\u4e3a\u5f53\u524d\u7cfb\u7edf\u65f6\u95f4\u7136\u540e\u8ba9del_flag\u8bbe\u7f6e\u4e3a1\uff0c\u8fd9\u4e2a\u529f\u80fd\u4e5f\u6ca1\u95ee\u9898\uff0c\u56e0\u4e3adel_time\u4e3a0\u624d\u8868\u793a\u77ed\u8fde\u63a5\u80fd\u7528\u3002 3.\u4f46\u662f\uff0c\u5f53\u518d\u6b21\u67e5\u8be2\u56de\u6536\u7ad9\u4e2d\u7684\u77ed\u94fe\u63a5\u540e\uff0c\u8fd8\u662f\u4f1a\u67e5\u8be2\u5230\u6211\u4eec\u4ece\u56de\u6536\u7ad9\u5220\u9664\u7684\u77ed\u94fe\u63a5\uff0c\u56e0\u4e3a\u6211\u4eec\u6267\u884cpageShortLink\u7684\u65f6\u5019\u5e76\u6ca1\u6709\u9650\u5236del_time\u8fd9\u4e2a\u67e5\u8be2\u6761\u4ef6\uff0c\u56e0\u6b64\u4e0d\u7ba1\u77ed\u94fe\u63a5\u662f\u5426\u5728\u56de\u6536\u7ad9\u4e2d\u5220\u9664\u90fd\u4f1a\u67e5\u8be2\u5230\uff0c\u6211\u4eec\u9700\u8981\u52a0\u4e0a.eq(ShortLinkDO::getDelTime, 0L)\u624d\u8868\u793a\u6ca1\u88ab\u5f7b\u5e95\u5220\u9664\u3002<\/p>\n\n\n\n<p>\u8fd9\u5757\u662f\u6ca1\u52a0del_time\u7684\u4ee3\u7801\uff0c\u6309\u4f60\u7684\u903b\u8f91\uff0c\u7b2c\u4e8c\u6b65\u8ba9del_flag\u8bbe\u7f6e\u4e3a1\u4e86\uff0c\u90a3\u5728\u67e5\u8be2\u7684\u65f6\u5019\uff0c\u5224\u65ad.eq(ShortLinkDO::getDelFlag, 0)\uff0c\u53ea\u80fd\u67e5\u7684\u51fa\u6765del_flag\u4e3a0\u7684\uff0c\u5220\u9664\u7684\u67e5\u4e0d\u5230\u7684<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public IPage&lt;ShortLinkPageRespDTO&gt; pageShortLink(ShortLinkRecycleBinPageReqDTO requestParam) {\n    LambdaQueryWrapper&lt;ShortLinkDO&gt; queryWrapper = Wrappers.lambdaQuery(ShortLinkDO.class)\n        .in(ShortLinkDO::getGid, requestParam.getGidList())\n        .eq(ShortLinkDO::getEnableStatus, val: 1)\n        .eq(ShortLinkDO::getDelFlag, val: 0)\n        .orderByDesc(ShortLinkDO::getUpdateTime);\n    IPage&lt;ShortLinkDO&gt; resultPage = baseMapper.selectPage(requestParam, queryWrapper);\n    return resultPage.convert(ShortLinkDO each -&gt; {\n        ShortLinkPageRespDTO result = BeanUtil.toBean(each, ShortLinkPageRespDTO.class);\n        result.setDomain(\"http:\/\/\" + result.getDomain());\n        return result;\n    });\n}<\/code><\/pre>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u4e2a\u4eba\u7684\u7406\u89e3\uff0c\u8fd9\u4e00\u96c6\u7684\u5e72\u8d27\u6ee1\u6ee1\uff0c\u4f46\u4ece\u7406\u89e3\u7684\u89d2\u5ea6\uff0c\u4f18\u5316\u7b49\u4ee5\u540e\u518d\u8bf4\u54c8\u54c8\u54c8\uff1a 1.\u5982\u679c\u5355\u5355\u4f7f\u7528full_short_url\u6765\u4f5c\u4e3a\u552f\u4e00\u7d22\u5f15\uff0c\u90a3\u4e48\u65e0\u6cd5\u5bf9\u8be5url\u8fdb\u884c\u590d\u7528,t_link\u7684\u5206\u7247\u952e\u662fgid\uff0c\u5982\u679c\u4fee\u6539gid\u7684\u8bdd\uff0c\u8be5\u8bb0\u5f55\u53ef\u80fd\u8def\u7531\u5230\u5176\u5b83\u8868\u4e2d\uff0c\u6240\u4ee5\u9700\u8981\u5728\u8be5\u8868\u4e2d\u5220\u9664\u8be5\u8bb0\u5f55\uff0c\u5c06\u8be5\u8bb0\u5f55\u7684del_flag\u7f6e\u4e3a1\uff0c\u5982\u679c\u53e6\u5916\u7684gid\u4e5f\u88ab\u5206\u5230\u8fd9\u4e00\u7ec4\uff0c\u60f3\u521b\u5efa\u540c\u4e00\u4e2afull_short_url\uff0c\u5c31\u4e0d\u884c\uff0c\u8fbe\u4e0d\u5230full_short_url\u590d\u7528\u7684\u529f\u80fd\uff1b 2.\u6240\u4ee5\u52a0\u4e0a\u4e00\u4e2adel_time\u65f6\u95f4\u6233\uff0c\u548cshort_link_url\u4e00\u540c\u4f5c\u4e3a\u8054\u5408\u7d22\u5f15\uff0c\u4e0d\u540c\u7684gid\u53ef\u4ee5\u5bf9\u5728\u8be5\u8868\u4e2d\u88ab\u5220\u9664\u7684full_short_url\u8fdb\u884c\u590d\u7528\uff1b 3.\u4fee\u6539gid\u9700\u8981\u8fdb\u884c\u7684\u4e24\u6b65\u64cd\u4f5c\uff0c\u4e00\u5220\u9664\u5728\u539f\u6765\u5206\u7247\u7684\u8bb0\u5f55(\u5c06del_flag\u7f6e\u4e3a1)\uff0c\u5728\u65b0\u5206\u7247\u4e2d\u6dfb\u52a0\u8bb0\u5f55\uff1b 4.\u5728\u4fee\u6539gid\u7684\u8fc7\u7a0b\u4e2d\uff0c\u7528\u6237\u8bbf\u95ee\u8be5\u5206\u7ec4\u7684short_link\uff0c\u56e0\u4e3aMySQL\u9ed8\u8ba4\u652f\u6301\u7684\u662f\u53ef\u91cd\u590d\u8bfb\uff0c\u90a3\u4e48\u76d1\u63a7\u6570\u636e\u5c31\u4e0d\u51c6\u786e-&gt;\u9700\u8981\u52a0\u9501\uff0c\u52a0\u5206\u5e03\u5f0f\u9501\uff1f\u90a3\u5c31\u4e0d\u80fd\u5e76\u53d1\uff0c\u4e00\u4e2a\u7528\u6237\u8bbf\u95ee\u8be5short_link\uff0c\u522b\u7684\u7528\u6237\u8bbf\u95ee\u4e0d\u4e86\u3002\u5982\u679c\u52a0\u8bfb\u5199\u9501\uff0c\u76f8\u5f53\u4e8e\u5927\u5bb6\u90fd\u53ef\u4ee5\u8bfb\uff0c\u4f46\u662f\u83b7\u5f97\u5199\u9501\u7684\u7528\u6237\u53ea\u6709\u4e00\u4e2a\u3002\u8fbe\u52301.\u76d1\u63a7\u6570\u636e\u51c6\u786e2.\u5e76\u53d1\uff01 5.\u96be\u9053\u4f60\u4fee\u6539\u7684\u65f6\u5019\u6211\u5c31\u4e0d\u80fd\u8bbf\u95ee\u4e86\uff1f\u7528\u6237\u4f53\u9a8c\u611f\u592a\u5dee\u4e86\u5427\uff1f\u6240\u4ee5\u9700\u8981\u5728\u4fee\u6539\u7684\u65f6\u5019\u4e5f\u80fd\u8fdb\u884c\u8bbf\u95ee\uff0c\u4f46\u662f\u8bbf\u95ee\u7684\u6570\u636e\u5f97\u8bb0\u5f55\u597d\uff0c\u8bb0\u5f55\u7684\u662f\u6211\u4fee\u6539\u540egid\u7684\u8bbf\u95ee\u6570\u636e(\u76d1\u63a7\u6570\u636e\u5ef6\u8fdf\u52a0\u8f7d)\uff0c\u6240\u4ee5\u9700\u8981\u4f7f\u7528\u5ef6\u8fdf\u961f\u5217\u3002\u4f46\u662f\u4fdd\u8bc1\u4e86\u7528\u6237\u4f53\u9a8c\u611f\uff0c\u56e0\u4e3a\u7528\u6237\u4e0d\u4f1a\u5728\u7b2c\u4e00\u65f6\u95f4\u53bb\u770b\u76d1\u63a7\u6570\u636e\uff0c\u53ef\u4ee5\u63a5\u53d7\u7a0d\u8bb8\u5ef6\u8fdf<\/p>\n\n\n\n<p>\u6211\u60f3\u95ee\u4e00\u4e0b\uff0c\u5982\u679c\u662f\u6539\u4e86gid\uff0c\u90a3\u4e48\u76f4\u63a5\u6267\u884c\u7269\u7406\u5220\u9664\u7684\u64cd\u4f5c\uff0c\u4e0d\u5c31\u53ef\u4ee5\u7ee7\u7eed\u4f7f\u7528full_short_url\u4f5c\u4e3a\u552f\u4e00\u7d22\u5f15\u4e86\u5417<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.consumer;\n\nimport com.nageoffer.shortlink.project.dto.biz.ShortLinkStatsRecordDTO;\nimport com.nageoffer.shortlink.project.service.ShortLinkService;\nimport lombok.RequiredArgsConstructor;\nimport org.redisson.api.RBlockingDeque;\nimport org.redisson.api.RDelayedQueue;\nimport org.redisson.api.RedissonClient;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.stereotype.Component;\n\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.locks.LockSupport;\n\nimport static com.nageoffer.shortlink.project.common.constant.RedisKeyConstant.DELAY_QUEUE_STATS_KEY;\n\n\/**\n * \u5ef6\u8fdf\u8bb0\u5f55\u77ed\u94fe\u63a5\u7edf\u8ba1\u7ec4\u4ef6\n *\/\n@Component\n@RequiredArgsConstructor\npublic class DelayShortLinkStatsConsumer implements InitializingBean {\n\n    private final RedissonClient redissonClient;\n    private final ShortLinkService shortLinkService;\n\n    public void onMessage() {\n        Executors.newSingleThreadExecutor(\n                        runnable -&gt; {\n                            Thread thread = new Thread(runnable);\n                            thread.setName(\"delay_short-link_stats_consumer\");\n                            thread.setDaemon(Boolean.TRUE);\n                            return thread;\n                        })\n                .execute(() -&gt; {\n                    RBlockingDeque&lt;ShortLinkStatsRecordDTO&gt; blockingDeque = redissonClient.getBlockingDeque(DELAY_QUEUE_STATS_KEY);\n                    RDelayedQueue&lt;ShortLinkStatsRecordDTO&gt; delayedQueue = redissonClient.getDelayedQueue(blockingDeque);\n                    for (; ; ) {\n                        try {\n                            ShortLinkStatsRecordDTO statsRecord = delayedQueue.poll();\n                            if (statsRecord != null) {\n                                shortLinkService.shortLinkStats(null, null, statsRecord);\n                                continue;\n                            }\n                            LockSupport.parkUntil(500);\n                        } catch (Throwable ignored) {\n                        }\n                    }\n                });\n    }\n\n    @Override\n    public void afterPropertiesSet() throws Exception {\n        onMessage();\n    }\n}\n<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u77ed\u94fe\u63a5\u4fee\u6539\u5206\u7ec4 ID \u9501\u524d\u7f00 Key\n *\/\npublic static final String LOCK_GID_UPDATE_KEY = \"short-link_lock_update-gid_%s\";\n\n\/**\n * \u77ed\u94fe\u63a5\u5ef6\u8fdf\u961f\u5217\u6d88\u8d39\u7edf\u8ba1 Key\n *\/\npublic static final String DELAY_QUEUE_STATS_KEY = \"short-link_delay-queue:stats\";<\/pre>\n\n\n\n<p>&nbsp;\u8fd8\u6709ShortLinkUpdateReqDTO.java\u90fd\u8981\u52a0\u5165<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u5206\u7ec4\u6807\u8bc6\n *\/\nprivate String gid;\n\/**\n * \u539f\u59cb\u5206\u7ec4\u6807\u8bc6\n *\/\nprivate String originGid;<\/pre>\n\n\n\n<p>shortlinkDO\u91cc\u9762\u52a0\u5165 \u7b49\u5176\u4ed6\u7684dto\u6587\u4ef6\u4e5f\u8981\u4fee\u6539<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u5220\u9664\u65f6\u95f4\n *\/\nprivate Long delTime;<\/pre>\n\n\n\n<p>&nbsp;LinkStatsTodayService.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.service;\n\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkStatsTodayDO;\n\n\/**\n * \u77ed\u94fe\u63a5\u4eca\u65e5\u7edf\u8ba1\u63a5\u53e3\u5c42\n *\/\npublic interface LinkStatsTodayService extends IService&lt;LinkStatsTodayDO&gt; {\n}<\/pre>\n\n\n\n<p>ShortLinkService.java \u6dfb\u52a0<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u77ed\u94fe\u63a5\u7edf\u8ba1\n *\n * @param fullShortUrl         \u5b8c\u6574\u77ed\u94fe\u63a5\n * @param gid                  \u5206\u7ec4\u6807\u8bc6\n * @param shortLinkStatsRecord \u77ed\u94fe\u63a5\u7edf\u8ba1\u5b9e\u4f53\u53c2\u6570\n *\/\nvoid shortLinkStats(String fullShortUrl, String gid, ShortLinkStatsRecordDTO shortLinkStatsRecord);\n<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.service.impl;\n\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkStatsTodayDO;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkStatsTodayMapper;\nimport com.nageoffer.shortlink.project.service.LinkStatsTodayService;\nimport org.springframework.stereotype.Service;\n\n\/**\n * \u77ed\u94fe\u63a5\u4eca\u65e5\u7edf\u8ba1\u63a5\u53e3\u5b9e\u73b0\u5c42\n *\/\n@Service\npublic class LinkStatsTodayServiceImpl extends ServiceImpl&lt;LinkStatsTodayMapper, LinkStatsTodayDO&gt; implements LinkStatsTodayService {\n}<\/pre>\n\n\n\n<p>&nbsp;DelayShortLinkStatsProducer.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.producer;\n\n\nimport com.nageoffer.shortlink.project.dto.biz.ShortLinkStatsRecordDTO;\nimport lombok.RequiredArgsConstructor;\nimport org.redisson.api.RBlockingDeque;\nimport org.redisson.api.RDelayedQueue;\nimport org.redisson.api.RedissonClient;\nimport org.springframework.stereotype.Component;\n\nimport java.util.concurrent.TimeUnit;\n\nimport static com.nageoffer.shortlink.project.common.constant.RedisKeyConstant.DELAY_QUEUE_STATS_KEY;\n\n\/**\n * \u5ef6\u8fdf\u6d88\u8d39\u77ed\u94fe\u63a5\u7edf\u8ba1\u53d1\u9001\u8005\n *\/\n@Component\n@RequiredArgsConstructor\npublic class DelayShortLinkStatsProducer {\n\n    private final RedissonClient redissonClient;\n\n    \/**\n     * \u53d1\u9001\u5ef6\u8fdf\u6d88\u8d39\u77ed\u94fe\u63a5\u7edf\u8ba1\n     *\n     * @param statsRecord \u77ed\u94fe\u63a5\u7edf\u8ba1\u5b9e\u4f53\u53c2\u6570\n     *\/\n    public void send(ShortLinkStatsRecordDTO statsRecord) {\n        RBlockingDeque&lt;ShortLinkStatsRecordDTO&gt; blockingDeque = redissonClient.getBlockingDeque(DELAY_QUEUE_STATS_KEY);\n        RDelayedQueue&lt;ShortLinkStatsRecordDTO&gt; delayedQueue = redissonClient.getDelayedQueue(blockingDeque);\n        delayedQueue.offer(statsRecord, 5, TimeUnit.SECONDS);\n    }\n}\n<\/pre>\n\n\n\n<p>RecycleBinServicelmpl.java&nbsp;<\/p>\n\n\n\n<p>shortLinkImpl\u4fee\u4fee\u8865\u8865\u7684\uff0c\u4e0d\u5199\u4e86\u81ea\u884c\u5728git\u4e2d\u5bfb\u627e<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c06\u8282\uff1a\u77ed\u94fe\u63a5\u521b\u5efa\u548c\u4fee\u6539\u9a8c\u8bc1\u8df3\u8f6c\u94fe\u63a5\u767d\u540d\u5355<\/h2>\n\n\n\n<p>\u524d\u5e74\u6709\u641e\u4e86\u4e00\u4e2aAI\u9879\u76ee\uff0c\u56e0\u4e3a\u6ca1\u6709\u505a\u8bed\u8a00\u6a21\u578b\u7684\u98ce\u63a7\uff0c\u5bfc\u81f4\u51fa\u73b0\u654f\u611f\u95ee\u9898\uff0c\u57df\u540d\u88ab\u98ce\u63a7\u4e86\u2014\u2014\u8fd9\u5c31\u662f\u5178\u578b\u7684\u8eba\u67aa\u6848\u4f8b\uff0c\u6211\u4eec\u8981\u5f15\u4ee5\u4e3a\u6212\u3002\u6bd5\u7adf\u57df\u540d\u5f88\u91cd\u8981\uff0c\u5982\u679c\u6d89\u53ca\u5de5\u4fe1\u90e8\u5907\u6848\u4e4b\u7c7b\u7684\u4f1a\u5f88\u9ebb\u70e6\u3002<\/p>\n\n\n\n<p>\u6240\u4ee5\u6211\u4eec\u8981\u505a\u4e00\u4e2a\u8df3\u8f6c\u94fe\u63a5\u7684\u767d\u540d\u5355\u529f\u80fd\u3002\u8fd9\u662f\u5fc5\u987b\u7684\uff0c\u5982\u679c\u662f\u505aSaaS\u5b98\u7f51\u66f4\u662f\u5fc5\u987b\u7684\u3002\u53e6\u4e00\u79cd\u573a\u666f\u662f\u90e8\u7f72\u5728\u516c\u53f8\u5185\u7f51\u7684\u60c5\u51b5\uff0c\u8fd9\u79cd\u5c31\u4e0d\u662f\u5fc5\u987b\u7684\u4e86\uff0c\u56e0\u4e3a\u8c01\u521b\u5efa\u8c01\u5fc3\u91cc\u6709\u6570\uff0c\u5982\u679c\u521b\u5efa\u8fdd\u6cd5\u94fe\u63a5\uff0c\u8d23\u4efb\u4eba\u660e\u786e\u3002\u8fd8\u6709\u4e00\u79cd\u60c5\u51b5\u662f\u65e0\u9650\u5236\u8df3\u8f6c\u539f\u59cb\u7f51\u7ad9\uff0c\u4f46\u521b\u5efa\u65f6\u8981\u5206\u6790\u5185\u5bb9\u662f\u5426\u8fdd\u6cd5\uff0c\u4f46\u8fd9\u79cd\u6d41\u7a0b\u592a\u590d\u6742\uff0c\u6240\u4ee5\u6211\u4eec\u76f4\u63a5\u7528\u57df\u540d\u767d\u540d\u5355\u3002<\/p>\n\n\n\n<p>\u4ee3\u7801\u5b9e\u73b0\u4e0d\u590d\u6742\uff0c\u5df2\u7ecf\u5199\u597d\u3002\u6211\u4eec\u5728\u914d\u7f6e\u91cc\u52a0\u4e86<code>goto-domain.white-list<\/code>\u53c2\u6570\uff1a<\/p>\n\n\n\n<p>application.yaml\u6dfb\u52a0\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">goto-domain:\n  white-list:\n    enable: true\n    names: '\u62ff\u4e2aoffer,\u77e5\u4e4e,\u6398\u91d1,\u535a\u5ba2\u56ed'\n    details:\n      - nageoffer.com\n      - zhihu.com\n      - juejin.cn\n      - cnblogs.com<\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u521b\u5efa<code>GotoDomainWhiteListConfiguration<\/code>\u914d\u7f6e\u7c7b\u52a0\u8f7d\u53c2\u6570<\/li>\n\n\n\n<li><code>LinkUtil.extractDomain()<\/code>\u65b9\u6cd5\u63d0\u53d6\u539f\u59cb\u94fe\u63a5\u57df\u540d\uff08\u81ea\u52a8\u8fc7\u6ee4www\u524d\u7f00\uff09<\/li>\n\n\n\n<li>\u5728<code>createShortLink<\/code>\u548c<code>updateShortLink<\/code>\u65b9\u6cd5\u524d\u6dfb\u52a0<code>verificationWhitelist()<\/code>\u6821\u9a8c<\/li>\n<\/ol>\n\n\n\n<p>\u5728project\/config\u4e2d\u65b0\u5efaGotoDomainWhiteListConfiguration\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.config;\n\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.stereotype.Component;\n\nimport java.util.List;\n\n\/**\n * \u8df3\u8f6c\u57df\u540d\u767d\u540d\u5355\u914d\u7f6e\u6587\u4ef6\n *\/\n@Data\n@Component\n@ConfigurationProperties(prefix = \"short-link.goto-domain.white-list\")\npublic class GotoDomainWhiteListConfiguration {\n\n    \/**\n     * \u662f\u5426\u5f00\u542f\u8df3\u8f6c\u539f\u59cb\u94fe\u63a5\u57df\u540d\u767d\u540d\u5355\u9a8c\u8bc1\n     *\/\n    private Boolean enable;\n\n    \/**\n     * \u8df3\u8f6c\u539f\u59cb\u57df\u540d\u767d\u540d\u5355\u7f51\u7ad9\u540d\u79f0\u96c6\u5408\n     *\/\n    private String names;\n\n    \/**\n     * \u53ef\u8df3\u8f6c\u7684\u539f\u59cb\u94fe\u63a5\u57df\u540d\n     *\/\n    private List&lt;String&gt; details;\n}<\/pre>\n\n\n\n<p>LinkUtil\u91cc\u9762\u65b0\u5199\u51fd\u6570&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u83b7\u53d6\u539f\u59cb\u94fe\u63a5\u4e2d\u7684\u57df\u540d\n * \u5982\u679c\u539f\u59cb\u94fe\u63a5\u5305\u542b www \u5f00\u5934\u7684\u8bdd\u9700\u8981\u53bb\u6389\n *\n * @param url \u521b\u5efa\u6216\u8005\u4fee\u6539\u77ed\u94fe\u63a5\u7684\u539f\u59cb\u94fe\u63a5\n * @return \u539f\u59cb\u94fe\u63a5\u4e2d\u7684\u57df\u540d\n *\/\npublic static String extractDomain(String url) {\n    String domain = null;\n    try {\n<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">        String host = uri.getHost();\n        if (StrUtil.isNotBlank(host)) {\n            domain = host;\n            if (domain.startsWith(\"www.\")) {\n                domain = host.substring(4);\n            }\n        }\n    } catch (Exception ignored) {\n    }\n    return domain;\n}\n<\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>shortLinkImpl\u91cc\u9762\u6dfb\u52a0    private final GotoDomainWhiteListConfiguration gotoDomainWhiteListConfiguration;\n\n\n\u63a5\u4e0b\u6765createShortLink\u8fd8\u6709updateShortLink\u7b2c\u4e00\u53e5\u524d\u586b\u4e0a        verificationWhitelist(requestParam.getOriginUrl());\n\n\n\n    private void verificationWhitelist(String originUrl) {\n        Boolean enable = gotoDomainWhiteListConfiguration.getEnable();\n        if (enable == null || !enable) {\n            return;\n        }\n        String domain = LinkUtil.extractDomain(originUrl);\n        if (StrUtil.isBlank(domain)) {\n            throw new ClientException(\"\u8df3\u8f6c\u94fe\u63a5\u586b\u5199\u9519\u8bef\");\n        }\n        List&lt;String&gt; details = gotoDomainWhiteListConfiguration.getDetails();\n        if (!details.contains(domain)) {\n            throw new ClientException(\"\u6f14\u793a\u73af\u5883\u4e3a\u907f\u514d\u6076\u610f\u653b\u51fb\uff0c\u8bf7\u751f\u6210\u4ee5\u4e0b\u7f51\u7ad9\u8df3\u8f6c\u94fe\u63a5\uff1a\" + gotoDomainWhiteListConfiguration.getNames());\n        }\n    }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c07\u8282\uff1a\u53d8\u66f4\u7528\u6237\u5df2\u767b\u5f55\u72b6\u6001\u4e0b\u5f02\u5e38\u884c\u4e3a<\/h2>\n\n\n\n<p>\u6211\u4eec\u7684\u7528\u6237\u4ed6\u53ea\u80fd\u5728\u4e00\u4e2a\u5730\u65b9\u767b\u5f55\u5bf9\u5427\uff1f\u4f46\u662f\u540e\u6765\u53d1\u73b0\u60e8\u906d\u6253\u8138\u2014\u2014\u5c31\u662f\u54b1\u4eec\u7684\u77ed\u94fe\u63a5\u5e73\u53f0\uff0c\u6211\u4f1a\u90e8\u7f72\u5230\u516c\u7f51\u4e0a\u9762\u4e00\u4e2a\u670d\u52a1\u5bf9\u5427\uff1f\u8fd9\u6837\u7684\u8bdd\u6211\u662f\u4e0d\u5f00\u653e\u7528\u6237\u6ce8\u518c\u63a5\u53e3\u7684\uff0c\u8fd9\u79cd\u60c5\u51b5\u7684\u8bdd\u6211\u4eec\u5c31\u4f1a\u53ea\u80fd\u7528\u4e00\u4e2a\u7528\u6237\u53bb\u767b\u5f55\u8fd9\u79cd\u60c5\u51b5\u5bf9\u5427\uff1f\u6211\u4eec\u73b0\u6709\u7684\u4f53\u7cfb\u5c31\u4e0d\u600e\u4e48\u652f\u6301\u4e86\uff0c\u652f\u6301\u4e0d\u600e\u4e48\u597d\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u8fdb\u884c\u6539\u9020\u3002\u600e\u4e48\u6539\u9020\uff1f\u9996\u5148\u5b83\u539f\u6765\u4e0d\u662f\u5224\u65ad\u5f53\u524d\u5982\u679c\u6709\u767b\u5f55\u4fe1\u606f\u5c31\u76f4\u63a5\u629b\u5f02\u5e38\uff0c\u6211\u4eec\u73b0\u5728\u9700\u8981\u628a\u5b83\u6539\u6210\uff1a\u5982\u679c\u8bf4\u5b58\u5728\u4e86\uff0cok\u6211\u4eec\u628a\u5b83\u7684 token\u7ed9\u5b83\u8fd4\u56de\u56de\u53bb\u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u8fd9\u8fb9\u6539\u903b\u8f91\u7684\u65f6\u5019\u7528\u4e86Redis\u7684Hash\u7ed3\u6784\uff1a<\/p>\n\n\n\n<p>admin\u91cc\u9762\u7684UserServiceImpl\u4fee\u6539\u5982\u4e0b&nbsp;\uff1a\u7528\u6237\u5df2\u767b\u5f55\u72b6\u6001\u5982\u679c\u91cd\u590d\u767b\u5f55\u8fd4\u56deToken\uff1b\u8fd8\u6709\u7528\u6237\u767b\u5f55\u72b6\u6001\u6709\u6548\u671f\u4fee\u6539\u4e3a30\u5206\u949f<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Override\npublic UserLoginRespDTO login(UserLoginReqDTO requestParam) {\n    LambdaQueryWrapper&lt;UserDO&gt; queryWrapper = Wrappers.lambdaQuery(UserDO.class)\n            .eq(UserDO::getUsername, requestParam.getUsername())\n            .eq(UserDO::getPassword, requestParam.getPassword())\n            .eq(UserDO::getDelFlag, 0);\n    UserDO userDO = baseMapper.selectOne(queryWrapper);\n    if (userDO == null) {\n        throw new ClientException(\"\u7528\u6237\u4e0d\u5b58\u5728\");\n    }\n    \/* \u539f\u6765\u672a\u4fee\u6539\u7684\u591a\u7aef\u767b\u5f55\n    Boolean hasLogin = stringRedisTemplate.hasKey(\"login_\" + requestParam.getUsername());\n    if (hasLogin != null &amp;&amp; hasLogin) {\n        throw new ClientException(\"\u7528\u6237\u5df2\u767b\u5f55\");\n    }\n    *\/\n    Map&lt;Object ,Object&gt; hasLoginMap = stringRedisTemplate.opsForHash().entries(\"login_\" + requestParam.getUsername());\n    if (CollUtil.isNotEmpty(hasLoginMap)) {\n        String token = hasLoginMap.keySet().stream()\n                .findFirst()\n                .map(Object::toString)\n                .orElseThrow(() -&gt; new ClientException(\"\u7528\u6237\u767b\u5f55\u9519\u8bef\"));\n        return new UserLoginRespDTO(token);\n    }\n    \/**\n     * Hash\n     * Key: login_\u7528\u6237\u540d\n     * Value:\n     * Key: token\u6807\u8bc6\n     * Val: JSON \u5b57\u7b26\u4e32\uff08\u7528\u6237\u4fe1\u606f\uff09\n     *\/\n    \/\/ HashOperations\u4e2d\u6ca1\u6709\u53d1\u73b0\u529e\u6cd5\u8bbe\u7f6e\u8fc7\u671f\u65f6\u95f4\n    String uuid = UUID.randomUUID().toString();\n    stringRedisTemplate.opsForHash().put(\"login_\" + requestParam.getUsername(), uuid, JSON.toJSONString(userDO));\n    stringRedisTemplate.expire(\"login_\" + requestParam.getUsername(), 30L, TimeUnit.MINUTES);\/\/\u4e0d\u662fDAYS\u4e86\n    return new UserLoginRespDTO(uuid);\n}\n<\/pre>\n\n\n\n<p>\u8fd9\u90e8\u5206\u4ee3\u7801\u7684\u610f\u601d\u662f\uff1a\u5f53\u7528\u6237\u5df2\u7ecf\u5b58\u5728\u767b\u5f55\u8bb0\u5f55\u65f6\uff08\u5373Redis Hash\u4e2d\u6709\u6570\u636e\uff09\uff0c\u6211\u4eec\u76f4\u63a5\u53d6\u7b2c\u4e00\u4e2atoken\u8fd4\u56de\uff0c\u800c\u4e0d\u662f\u62a5\u9519\u3002\u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86\u5141\u8bb8\u591a\u7aef\u540c\u65f6\u767b\u5f55\u7684\u6548\u679c\u3002<\/p>\n\n\n\n<p>\u7528\u4e86Redis Hash\u5b58\u50a8\u7528\u6237\u7684\u591a\u4e2atoken\uff08key\u662flogin_\u7528\u6237\u540d\uff0cvalue\u662ftoken-&gt;\u7528\u6237\u4fe1\u606f\u7684\u6620\u5c04\uff09\uff0c\u5e76\u4e14\u628a\u8fc7\u671f\u65f6\u95f4\u4ece\u539f\u6765\u768430\u5929\u6539\u6210\u4e8630\u5206\u949f\u3002\u6211\u4eec\u6d4b\u8bd5\u4e0b\u6765\u56e0\u4e3a\u662f\u5728Redis\u7684Hash\u7ed3\u6784\u91cc\u547d\u540d\uff0c\u6240\u4ee5\u76f4\u63a5\u91cd\u542f\u670d\u52a1\u5c31\u80fd\u751f\u6548\u3002&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;1.\u8c01\u80fd\u8bb2\u8bb2\u8fd9\u662f\u548b\u5b9e\u73b0\u7684\u591a\u7aef\u767b\u5f55\uff0c\u60f3\u4e0d\u660e\u767d<\/p>\n\n\n\n<p>\u6211\u7684\u7406\u89e3\u662f\u8fd9\u6837\u7684\uff0c\u4ec5\u4f9b\u53c2\u8003\uff1a\u591a\u7aef\u767b\u5f55\u6307\u7684\u662f\u53ef\u4ee5\u5728\u4e0d\u540c\u8bbe\u5907\u4e0a\u540c\u65f6\u767b\u5f55\u4f7f\u7528\uff0c\u90a3\u4e48\u8fd9\u91cc\u4fee\u6539\u7684\u76ee\u7684\u5c31\u5f88\u6e05\u695a\u4e86\u3002\u5047\u8bbe\u8fd9\u4e48\u4e00\u4e2a\u573a\u666f\uff0c\u4f60\u5df2\u7ecf\u5728\u624b\u673a\u4e0a\u901a\u8fc7\u8d26\u53f7\u548c\u5bc6\u7801\u767b\u5f55\u4e86\uff0c\u5982\u679c\u6309\u7167\u4e4b\u524d\u7684\u4ee3\u7801\uff0c\u90a3\u4e48\u8fd9\u65f6\u4f60\u5728\u7535\u8111\u4e0a\u7d27\u63a5\u7740\u767b\u5f55\u7684\u8bdd\u663e\u7136\u4f1a\u88ab\u629b\u5f02\u5e38\u8bf4\u7528\u6237\u5df2\u7ecf\u767b\u9646\uff0c\u4f46\u662f\u4ee3\u7801\u4fee\u6539\u4e4b\u540e\uff0c\u4e0d\u518d\u629b\u51fa\u7528\u6237\u5df2\u767b\u5f55\u7684\u5f02\u5e38\u800c\u662f\u8fd4\u56de\u7528\u6237token\uff0c\u4f7f\u7528\u6237\u767b\u9646\u6210\u529f\uff0c\u8fd9\u6837\u5c31<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4ee3\u7801\u4e2d\u6bcf\u6b21\u767b\u5f55\u53ea\u4f1a\u751f\u6210<strong>\u4e00\u4e2aToken <\/strong>\uff0c\u5e76\u975e\"\u591a\u7aef\u767b\u5f55\u65f6\u8fd4\u56de\u5df2\u6709Token\"\u3002\u6240\u6709\u8bbe\u5907\u5171\u4eab\u540c\u4e00\u4e2aToken\uff08\u56e0\u4e3a\u6bcf\u6b21\u767b\u5f55\u90fd\u590d\u7528\u5df2\u6709Token\uff09\uff0c\u8fd9\u672c\u8d28\u4e0a\u662f<strong>\u5355Token\u5171\u4eab\u767b\u5f55 <\/strong>\uff0c\u800c\u975e\u771f\u6b63\u7684\u591aToken\u591a\u7aef\u767b\u5f55\uff08\u6bcf\u4e2a\u8bbe\u5907\u72ec\u7acbToken\uff09\u3002\u771f\u6b63\u7684\u591a\u7aef\u767b\u5f55\u5e94\u4e3a\u6bcf\u4e2a\u8bbe\u5907\u751f\u6210\u72ec\u7acbToken\uff0c\u4f46\u6b64\u5904\u8bbe\u8ba1\u9009\u62e9\u4e86\u7b80\u5316\u65b9\u6848\u3002<\/li>\n<\/ul>\n\n\n\n<p>2.\u5b9e\u73b0\u4e86\u591a\u7aef\u767b\u5f55\uff0c\u4e0d\u77e5\u9053\u6211\u6709\u6ca1\u6709\u89e3\u91ca\u6e05\u695a\u3002<\/p>\n\n\n\n<p>\u5982\u679c\u6709\u591a\u4e2a\u7528\u6237\u7684\u8bdd \u90a3\u4e48\u8fd9\u91cc\u8fd4\u56de\u7684\u662f\u54c8\u5e0c\u8868\u4e2d\u7b2c\u4e00\u4e2a\u7528\u6237\u7684token\u4e48 \uff1f<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4ee3\u7801\u4e2d\u4f7f\u7528 <code>hash.keySet().stream().findFirst()<\/code> \u53d6\u51fa\u7684\u662f\u552f\u4e00\u5b58\u5728\u7684Token\uff08\u56e0\u4e3a\u6bcf\u6b21\u767b\u5f55\u53ea\u5b58\u4e00\u4e2a\u952e\u503c\u5bf9\uff09\uff0c\u5e76\u975e\"\u591a\u4e2aToken\u4e2d\u53d6\u7b2c\u4e00\u4e2a\"\u3002<\/li>\n\n\n\n<li><strong>\u7ed3\u8bba <\/strong>\uff1a\u7528\u62372\u7684\u8868\u8ff0\u5b58\u5728\u903b\u8f91\u77db\u76fe\uff1a\u82e5\"map\u4e2d\u7684token\u53ea\u6709\u4e00\u4e2a\"\uff0c\u5219\u4e0d\u5b58\u5728\"\u53d6\u7b2c\u4e00\u4e2a\"\u7684\u6982\u5ff5\uff0c\u5176\u672c\u8d28\u662f<strong>\u590d\u7528\u5df2\u6709Token <\/strong>\u3002<\/li>\n<\/ul>\n\n\n\n<p>3.\u539f\u4ee3\u7801\u8fd8\u6709\u4e00\u4e2a\u5f0a\u7aef\uff0c\u5982\u679c\u4e00\u4e2a\u7528\u6237\u5df2\u7ecf\u767b\u5f55\uff0c\u5982\u679c\u4ed6\u76f4\u63a5\u5173\u95ed\u7f51\u9875\uff0c\u90a3\u4e48\u4ed6\u8fd8\u662f\u767b\u5f55\u72b6\u6001\uff0c\u4e0b\u6b21\u767b\u5f55\u5982\u679ctoken\u6ca1\u8fc7\u671f\u7684\u8bdd\uff0c\u4ed6\u5c31\u767b\u5f55\u4e0d\u4e0a\u53bb\u4e86\uff1b\u6bcf\u6b21\u64cd\u4f5c\u90fd\u5237\u65b0\u7f13\u5b58\u8fc7\u671f\u65f6\u95f4\u662f\u4e0d\u662f\u6bd4\u8f83\u597d\uff1f\uff08login\u65b9\u6cd5\u91cc\u9762\u53ea\u662f\u8fdb\u884c\u767b\u5f55\u64cd\u4f5c\uff0c\u4e0d\u8fdb\u884c\u68c0\u67e5\u767b\u5f55\u7684\u64cd\u4f5c\uff0c\u68c0\u67e5\u767b\u5f55\u7684\u64cd\u4f5c\u5728checkLogin\u65b9\u6cd5\u4e2d\u6267\u884c\u3002\u76ee\u524d\u770b\u6765\u597d\u50cf\u662f\u5141\u8bb8\u91cd\u590d\u767b\u5f55\u7684-&gt;\u5141\u8bb8\u591a\u7aef\u767b\u5f55\uff1f\uff09<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5e94\u5728\u6bcf\u6b21\u8bf7\u6c42\u6821\u9a8c\u767b\u5f55\u72b6\u6001\u65f6\uff08\u5982<code>checkLogin<\/code>\u65b9\u6cd5\uff09\u901a\u8fc7 <code>stringRedisTemplate.expire(...)<\/code> \u5237\u65b0Token\u8fc7\u671f\u65f6\u95f4\uff0c\u5b9e\u73b0\"\u6ed1\u52a8\u8fc7\u671f\"\u673a\u5236\u3002<\/li>\n\n\n\n<li>\u5f53\u524d\u4ee3\u7801\u4ec5\u5728\u767b\u5f55\u65f6\u8bbe\u7f6e\u4e00\u6b21\u8fc7\u671f\u65f6\u95f4\uff0c\u65e0\u6cd5\u52a8\u6001\u5ef6\u957f\u6709\u6548\u671f\uff0c\u7528\u6237\u4f53\u9a8c\u8f83\u5dee\u3002<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c08\u8282\uff1a\u7528\u6237\u521b\u5efa\u5206\u7ec4\u9650\u5236\u6700\u5927\u6570\u91cf<\/h2>\n\n\n\n<p>&nbsp;\u8fd9\u8282\u8bfe\u6765\u8ddf\u5927\u5bb6\u8bf4\u4e00\u4e0b\u5173\u4e8e\u521b\u5efa\u77ed\u94fe\u63a5\u5206\u7ec4\u7684\u4e00\u4e2a\u9650\u5236\u95ee\u9898\uff0c\u5927\u5bb6\u90fd\u77e5\u9053\u6211\u4eec\u8fd9\u8fb9\u7ed9\u4ed6\u53bb\u505a\uff0c\u7a0d\u7b49\u6211\u767b\u5f55\u4e00\u4e0b\u3002\u6211\u4eec\u8fd9\u8fb9\u53bb\u521b\u5efa\u8fd9\u4e9b\u77ed\u94fe\u63a5\u5206\u7ec4\u7684\u8bdd\uff0c\u5b83\u4e0d\u53ef\u80fd\u662f\u53ef\u4ee5\u65e0\u9650\u521b\u5efa\u5bf9\u5427\uff1f\u8fd9\u4e2a\u80af\u5b9a\u662f\u8981\u52a0\u4e00\u4e9b\u9650\u5236\u7684\uff0c\u6211\u4eec\u8fd9\u8fb9\u5728\u521a\u5f00\u59cb\u9650\u5236\u7684\u8bdd\uff0c\u6211\u4eec\u53ef\u4ee5\u7ed9\u4ed6\u9650\u5236\uff0c\u5c31\u662f\u4e00\u4e2a\u7528\u6237\u4e0b\u9762\u53ef\u4ee5\u670920\u4e2a\u5206\u7ec4\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u56e0\u4e3a\u6211\u4eec\u90fd\u77e5\u9053\u6211\u4eec\u662f\u4f5c\u4e3a\u8fd9\u79cd\u5206\u5e03\u5f0f\u5e94\u7528\u53bb\u90e8\u7f72\u7684\uff0c\u5bf9\u5427\uff1f\u4f60\u8fd9\u6837\u666e\u901a\u7684single \u5948\u65af\u6216\u8005\u8fdc\u7a0block\u5c31\u80af\u5b9a\u4e0d\u884c\u4e86\uff0c\u7136\u540e\u57fa\u4e8e\u8fd9\u79cd\u60c5\u51b5\u6211\u4eec\u5e94\u8be5\u5206\u5e03\u5f0f\u9501\u53bb\u505a\u5168\u5c40\u7ba1\u63a7\u5e76\u4e14\u901a\u8fc7count\u7684\u5f62\u5f0f\u5224\u65ad\u5b83\u6709\u591a\u5c11\u4e2a\u8fd9\u79cd\u5206\u7ec4\uff0c\u7136\u540e\u5982\u679c\u8bf4\u5c0f\u4e8e20\u4e2a\u624d\u53ef\u4ee5\u521b\u5efa\u5982\u679c\u8bf4\uff0c\u7b49\u4e8e20\u4e2a\u5c31\u4e0d\u5141\u8bb8\u521b\u5efa\u4e86\uff0cok\u8fd9\u8fb9\u7684\u8bdd\u6211\u4eec\u5c31\u53ef\u4ee5\u7ed9\u4ed6\u628aRedissonClient\u5148\u5f15\u8fdb\u6765\u3002\u4e09\u697c\u7136\u540e\u4e00\u4e2a\u5c31\u7b2c\u4e00\u6b21\u770b\uff0c\u5c31\u770b\u5230\u4e86\u3002\u7136\u540e get\u5230\u7684\u8bdd\u6211\u4eec\u5c31\u4ee5\u5c31\u5728\u8fd9\u8fb9\u641e\u8fd9\u91cc\u5f00\u59cb\u3002&nbsp;user\u5e94\u8be5\u662fgo\u7528\u6237\u6ce8\u518c\u5206\u5e03\u5f0f\u9501\uff0c\u5206\u7ec4\u521b\u5efa\uff0cshort-link:lock_group-create:%s\u3002\u7136\u540e\u8fd9\u8fb9\u8fd8\u8981\u7ed9\u5b83\u52a0\u4e00\u4e2a\u4ec0\u4e48\uff1f\u52a0\u4e00\u4e2a\u52a0\u4e0a%S\uff0c\u56e0\u4e3a\u5b83\u662f\u8981\u53bb\u8ddf\u7528\u6237\u662f\u6302\u94a9\u7684\uff0c\u6709\u7684\u5185\u5bb9\u3002Ok\u5728\u8fd9\u91cc\u7684\u8bdd\u6211\u4eec\u9996\u5148\u8981\u57fa\u4e8e\u4ec0\u4e48\uff1f\u8981\u57fa\u4e8e\u6211\u4eec\u8981\u57fa\u4e8e\u4e00\u4e2awrappers.lambdaquery\u3002EQ\u4e00\u4e0b\u5f53\u524d\u7528\u6237\uff0c<\/p>\n\n\n\n<p>.eq(GroupDO::getUsername, username)<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .eq(GroupDO::getDelFlag, 0);<\/p>\n\n\n\n<p>\uff0c\u7136\u540e\u6211\u4eec\u8fd9\u8fb9\u5c31\u76f4\u63a5\u7a0d\u7b49\u4e00\u4e0b\u3002\u6211\u4eec\u8fd9\u8fb9\u6211\u60f3\u60f3\u76f4\u63a5\u5c31\u6765\u4e86\u4e00\u4e2a&nbsp;List&lt;GroupDO&gt; groupDOList = baseMapper.selectList(queryWrapper);\uff0cif\u7b2c\u4e8c\u5f00\u59cb\uff0c\u5e76\u4e14\u5c4c\u585e\u5b50\u3002\u7b49\u4e8e20\uff1b\u4e0d\u80fd\u53eb\u5927\u4e8e20.\u5982\u679c\u8bf4\u4e0d\u80fd\u5927\u4e8e\u5982\u679c\u8bf4\u7b4920\u300220\u80af\u5b9a\u662f\u4e0d\u80fd\u591f\u5728\u8fd9\u8fb9\u53bb\u76f4\u63a5\u53bb\u6307\u5b9a\u7684\u8fd9\u79cd\u7684\uff0c\u8bdd\u4e00\u822c\u7684\u8bdd\u6211\u4eec\u5e94\u8be5\u5728\u5c31\u914d\u6587\u4ef6\u91cc\u9762\u5c31\u7ed9\u4ed6\u786e\u5b9a\uff0c<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u6301\u7eed\u521b\u5efa\u5206\u7ec4\u523018\/19\/20\u4e2a<\/li>\n\n\n\n<li>\u7b2c21\u6b21\u521b\u5efa\u65f6\u629b\u51fa\"\u5df2\u8d85\u51fa\u6700\u5927\u5206\u7ec4\u6570\uff1a20\"\u5f02\u5e38<\/li>\n\n\n\n<li>\u622a\u56fe\u9a8c\u8bc1\u529f\u80fd\u751f\u6548<\/li>\n<\/ol>\n\n\n\n<p>\u8fd9\u4e2a\u529f\u80fd\u5c5e\u4e8e\u57fa\u7840\u98ce\u63a7\u63aa\u65bd\uff0c\u5efa\u8bae\u6240\u6709\u9700\u8981\u9650\u5236\u7528\u6237\u8d44\u6e90\u6570\u91cf\u7684\u573a\u666f\u90fd\u91c7\u7528\u7c7b\u4f3c\u65b9\u6848\u3002\u901a\u8fc7\u914d\u7f6e\u4e2d\u5fc3\u7ba1\u7406max-num\u53c2\u6570\u53ef\u7075\u6d3b\u8c03\u6574\u9650\u5236\u6570\u91cf\uff0c\u65e0\u9700\u4fee\u6539\u4ee3\u7801\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.common.constant;\n\n\/**\n * redisson \u7684\u5e38\u91cf\u547d\u540d\n *\/\npublic class RedisCacheConstant {\n    \/**\n     * \u7528\u6237\u6ce8\u518c\u5206\u5e03\u5f0f\u9501\n     *\/\n    public static final String LOCK_USER_REGISTER_KEY = \"short-link:lock-user-register:\";\n\n    \/**\n     * \u5206\u7ec4\u521b\u5efa\u5206\u5e03\u5f0f\u9501\n     *\/\n    public static final String LOCK_GROUP_CREATE_KEY = \"short-link:lock_group-create:%s\";\n\n}<\/pre>\n\n\n\n<p>admin\u7684GroupServicelmpl.java\u5982\u4e0b&nbsp;\u8fd8\u6709application.yaml \u91cc\u9762\u6dfb\u52a0\u4e0a\u8fd9\u4e9b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">short-link:\n  group:\n    max-num: 20\n<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.service.impl;\n\n\nimport cn.hutool.core.bean.BeanUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport com.nageoffer.shortlink.admin.common.biz.user.UserContext;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.dao.entiry.GroupDO;\nimport com.nageoffer.shortlink.admin.dao.mapper.GroupMapper;\nimport com.nageoffer.shortlink.admin.dto.req.ShortLinkGroupSortReqDTO;\nimport com.nageoffer.shortlink.admin.dto.req.ShortLinkGroupUpdateReqDTO;\nimport com.nageoffer.shortlink.admin.dto.resq.ShortLinkGroupRespDTO;\nimport com.nageoffer.shortlink.admin.remote.ShortLinkRemoteService;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkCreateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkCreateRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkGroupCountQueryRespDTO;\nimport com.nageoffer.shortlink.admin.service.GroupService;\nimport com.nageoffer.shortlink.admin.toolkit.RandomGenerator;\nimport lombok.RequiredArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.stereotype.Service;\nimport lombok.RequiredArgsConstructor;\nimport com.nageoffer.shortlink.admin.common.convention.exception.ClientException;\nimport cn.hutool.core.collection.CollUtil;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.redisson.api.RLock;\nimport org.redisson.api.RedissonClient;\nimport org.springframework.beans.factory.annotation.Value;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.Optional;\nimport static com.nageoffer.shortlink.admin.common.constant.RedisCacheConstant.LOCK_GROUP_CREATE_KEY;\n\n\/**\n * \u77ed\u94fe\u63a5\u5206\u7ec4\u63a5\u53e3\u5b9e\u73b0\u5c42\n *\/\n@Slf4j\n@Service\n@RequiredArgsConstructor\n\npublic class GroupServiceImpl extends ServiceImpl&lt;GroupMapper, GroupDO&gt; implements GroupService {\n\n\n    private final RedissonClient redissonClient;\n\n    @Value(\"${short-link.group.max-num}\")\n    private Integer groupMaxNum;\n\n    ShortLinkRemoteService shortLinkRemoteService = new ShortLinkRemoteService() {\n    };\n\n    @Override\n    public void saveGroup(String groupName) {\n        saveGroup(UserContext.getUsername(), groupName);\n    }\n    @Override\n    public void saveGroup(String username, String groupName) {\n        RLock lock = redissonClient.getLock(String.format(LOCK_GROUP_CREATE_KEY, username));\n        lock.lock();\n        try {\n            LambdaQueryWrapper&lt;GroupDO&gt; queryWrapper = Wrappers.lambdaQuery(GroupDO.class)\n                    .eq(GroupDO::getUsername, username)\n                    .eq(GroupDO::getDelFlag, 0);\n            List&lt;GroupDO&gt; groupDOList = baseMapper.selectList(queryWrapper);\n            if (CollUtil.isNotEmpty(groupDOList) &amp;&amp; groupDOList.size() == groupMaxNum) {\n                throw new ClientException(String.format(\"\u5df2\u8d85\u51fa\u6700\u5927\u5206\u7ec4\u6570\uff1a%d\", groupMaxNum));\n            }\n        String gid;\n        do {\n            gid = RandomGenerator.generateRandom();\n        } while (!hasGid(username,gid));\n        GroupDO groupDO = GroupDO.builder()\n                .gid(gid)\n                .sortOrder(0)\n                .username(username)\n                .name(groupName)\n                .build();\n        baseMapper.insert(groupDO);\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    private boolean hasGid(String username,String gid) {\n        LambdaQueryWrapper&lt;GroupDO&gt; queryWrapper = Wrappers.lambdaQuery(GroupDO.class)\n                .eq(GroupDO::getGid, gid)\n                .eq(GroupDO::getUsername, Optional.ofNullable(username).orElse(UserContext.getUsername()));\n        GroupDO hasGroupFlag = baseMapper.selectOne(queryWrapper);\n        return hasGroupFlag == null;\n    }\n\n    @Override\n    public List&lt;ShortLinkGroupRespDTO&gt; listGroup() {\n        LambdaQueryWrapper&lt;GroupDO&gt; queryWrapper = Wrappers.lambdaQuery(GroupDO.class)\n                .eq(GroupDO::getDelFlag, 0)\n                .eq(GroupDO::getUsername, UserContext.getUsername())\n                .orderByDesc(GroupDO::getSortOrder, GroupDO::getUpdateTime);\n        List&lt;GroupDO&gt; groupDOList = baseMapper.selectList(queryWrapper);\n        Result&lt;List&lt;ShortLinkGroupCountQueryRespDTO&gt;&gt; listResult = shortLinkRemoteService\n                .listGroupShortLinkCount(groupDOList.stream().map(GroupDO::getGid).toList());\n        List&lt;ShortLinkGroupRespDTO&gt; shortLinkGroupRespDTOList = BeanUtil.copyToList(groupDOList, ShortLinkGroupRespDTO.class);\n        shortLinkGroupRespDTOList.forEach(each -&gt; {\n            Optional&lt;ShortLinkGroupCountQueryRespDTO&gt; first = listResult.getData().stream()\n                    .filter(item -&gt; Objects.equals(item.getGid(), each.getGid()))\n                    .findFirst();\n            first.ifPresent(item -&gt; each.setShortLinkCount(first.get().getShortLinkCount()));\n        });\n        return shortLinkGroupRespDTOList;\n    }\n\n    @Override\n    public void updateGroup(ShortLinkGroupUpdateReqDTO requestParam) {\n        LambdaUpdateWrapper&lt;GroupDO&gt; updateWrapper = Wrappers.lambdaUpdate(GroupDO.class)\n                .eq(GroupDO::getUsername, UserContext.getUsername())\n                .eq(GroupDO::getGid, requestParam.getGid())\n                .eq(GroupDO::getDelFlag, 0);\n        GroupDO groupDO = new GroupDO();\n        groupDO.setName(requestParam.getName());\n        baseMapper.update(groupDO, updateWrapper);\n    }\n\n    @Override\n    public void deleteGroup(String gid) {\n        LambdaUpdateWrapper&lt;GroupDO&gt; updateWrapper = Wrappers.lambdaUpdate(GroupDO.class)\n                .eq(GroupDO::getUsername, UserContext.getUsername())\n                .eq(GroupDO::getGid, gid)\n                .eq(GroupDO::getDelFlag, 0);\n        GroupDO groupDO = new GroupDO();\n        groupDO.setDelFlag(1);\n        baseMapper.update(groupDO, updateWrapper);\n    }\n\n    @Override\n    public void sortGroup(List&lt;ShortLinkGroupSortReqDTO&gt; requestParam) {\n        requestParam.forEach(each -&gt; {\n            GroupDO groupDO = GroupDO.builder()\n                    .sortOrder(each.getSortOrder())\n                    .build();\n            LambdaUpdateWrapper&lt;GroupDO&gt; updateWrapper = Wrappers.lambdaUpdate(GroupDO.class)\n                    .eq(GroupDO::getUsername, UserContext.getUsername())\n                    .eq(GroupDO::getGid, each.getGid())\n                    .eq(GroupDO::getDelFlag, 0);\n            baseMapper.update(groupDO, updateWrapper);\n        });\n    }\n}\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>&nbsp;\u4f60\u4ece\u6811\u6797\u6df1\u5904\u8d70\u51fa\u96fe\uff1a\u8fd9\u91cc\u4e3a\u4ec0\u4e48\u9700\u8981\u52a0\u9501\u54c7\uff0c\u6ca1\u592a\u7406\u89e3\u3002\u867d\u7136\u662f\u5206\u5e03\u5f0f\u4f46\u5f53\u524d\u7528\u6237\u4e0d\u662f\u53ea\u80fd\u64cd\u4f5c\u81ea\u5df1\u7684\u5206\u7ec4\u4e48\uff0c\u800c\u4e14\u6dfb\u52a0\u5206\u7ec4\u64cd\u4f5c\u4e0d\u662f\u53ea\u5728admin\u9879\u76ee\u4e2d\u6709\u561b\uff0c\u662f\u54ea\u91cc\u4f1a\u5f15\u8d77\u51b2\u7a81\u4e48\uff1f<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5e76\u53d1\u573a\u666f\u672a\u8003\u8651 <\/strong>\uff1a\u5373\u4f7f\u7528\u6237\u53ea\u80fd\u64cd\u4f5c\u81ea\u5df1\u7684\u5206\u7ec4\uff0c\u540c\u4e00\u7528\u6237\u53ef\u80fd\u901a\u8fc7\u591a\u7aef\u767b\u5f55\uff08\u5982\u624b\u673a\u3001\u7535\u8111\uff09<strong>\u5e76\u53d1 <\/strong>\u521b\u5efa\u5206\u7ec4\u3002\u4f8b\u5982\uff0c\u4e24\u4e2a\u8bf7\u6c42\u540c\u65f6\u68c0\u67e5\u5230\u5f53\u524d\u5206\u7ec4\u6570\u4e3a19\uff08\u5c0f\u4e8e20\uff09\uff0c\u5747\u8ba4\u4e3a\u53ef\u4ee5\u521b\u5efa\u65b0\u5206\u7ec4\uff0c\u5bfc\u81f4\u6700\u7ec8\u521b\u5efa21\u4e2a\u5206\u7ec4\uff0c<strong>\u7a81\u7834\u9650\u5236 <\/strong>\u3002<\/li>\n\n\n\n<li><strong>\u5206\u5e03\u5f0f\u9501\u7684\u5fc5\u8981\u6027 <\/strong>\uff1a\u4ee3\u7801\u4e2d\u4f7f\u7528 <code>RedissonClient<\/code> \u7684\u5206\u5e03\u5f0f\u9501\uff08<code>RLock<\/code>\uff09\u662f\u4e3a\u4e86\u786e\u4fdd <strong>\u201c\u68c0\u67e5\u5206\u7ec4\u6570 + \u521b\u5efa\u5206\u7ec4\u201d <\/strong>\u7684\u64cd\u4f5c\u5177\u6709\u539f\u5b50\u6027\uff0c\u9632\u6b62\u5e76\u53d1\u5bfc\u81f4\u7684\u8d85\u9650\u95ee\u9898\u3002<\/li>\n\n\n\n<li><strong>\u5355\u8282\u70b9\u9501\u65e0\u6cd5\u89e3\u51b3\u5206\u5e03\u5f0f\u95ee\u9898 <\/strong>\uff1a\u5982\u679c\u4ec5\u4f7f\u7528\u672c\u5730\u9501\uff08\u5982 <code>synchronized<\/code>\uff09\uff0c\u5728\u5206\u5e03\u5f0f\u90e8\u7f72\u4e0b\uff0c\u4e0d\u540c\u8282\u70b9\u7684\u8bf7\u6c42\u4ecd\u53ef\u80fd\u540c\u65f6\u6267\u884c\u68c0\u67e5\u548c\u521b\u5efa\u64cd\u4f5c\uff0c\u5bfc\u81f4\u8d85\u9650\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u52ff\u8fdb\u8349&nbsp;\u56de\u590d&nbsp;\u4f60\u4ece\u6811\u6797\u6df1\u5904\u8d70\u51fa\u96fe\uff1a\u8fd9\u662f\u4e3a\u4e86\u9632\u6b62\u540c\u4e00\u7528\u6237\u5728\u4e0d\u540c\u7ebf\u7a0b\uff08\u53ef\u80fd\u540c\u4e00\u7528\u6237\u5728\u591a\u4e2a\u8bbe\u5907\uff09\u540c\u65f6\u65b0\u589e\u5206\u7ec4\uff0c\u800c\u8d85\u51fa\u6700\u5927\u5206\u7ec4\u6570\u5427\u3002<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;\u52ff\u8fdb\u8349\uff1a\u6b63\u89e3<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\n<ul class=\"wp-block-list\">\n<li><strong>\u5e76\u53d1\u573a\u666f\u4e0b\u7684\u8d85\u9650\u98ce\u9669 <\/strong>\uff08\u52ff\u8fdb\u8349\u3001\u9a6c\u4e01\uff09\uff1a<br>\u540c\u4e00\u7528\u6237\u5728\u4e0d\u540c\u8bbe\u5907\uff08\u591a\u7aef\u767b\u5f55\uff09\u6216\u540c\u4e00\u8bbe\u5907\u7684\u591a\u4e2a\u8bf7\u6c42\uff08\u5982\u6d4f\u89c8\u5668\u591a\u6807\u7b7e\u9875\uff09\u540c\u65f6\u89e6\u53d1\u5206\u7ec4\u521b\u5efa\u65f6\uff0c\u672a\u52a0\u9501\u4f1a\u5bfc\u81f4\u5e76\u53d1\u8d85\u9650\u3002<\/li>\n\n\n\n<li><strong>\u591a\u7aef\u767b\u5f55\u7684\u80cc\u666f <\/strong>\uff08TheTurtle\uff09\uff1a<br>\u524d\u6587\u63d0\u5230\u7528\u6237\u5141\u8bb8\u591a\u7aef\u767b\u5f55\uff08\u5171\u4eab\u540c\u4e00Token\uff09\uff0c\u56e0\u6b64\u540c\u4e00\u8d26\u53f7\u53ef\u80fd\u88ab\u591a\u4e2a\u8bbe\u5907\u540c\u65f6\u64cd\u4f5c\uff0c\u8fdb\u4e00\u6b65\u52a0\u5267\u5e76\u53d1\u98ce\u9669\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8865\u5145\u8bf4\u660e <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u5206\u5e03\u5f0f\u9501\u7684\u4f5c\u7528 <\/strong>\uff1a\u786e\u4fdd\u6574\u4e2a\u64cd\u4f5c\uff08\u67e5\u8be2\u5f53\u524d\u5206\u7ec4\u6570 + \u5224\u65ad\u662f\u5426\u8d85\u9650 + \u63d2\u5165\u65b0\u5206\u7ec4\uff09\u5728\u5206\u5e03\u5f0f\u73af\u5883\u4e0b<strong>\u4e32\u884c\u5316\u6267\u884c <\/strong>\uff0c\u907f\u514d\u591a\u4e2a\u8bf7\u6c42\u540c\u65f6\u901a\u8fc7\u68c0\u67e5\u6761\u4ef6\u3002<\/li>\n\n\n\n<li><strong>\u9501\u7684\u7c92\u5ea6 <\/strong>\uff1a\u4ee3\u7801\u4e2d\u9501\u7684 Key \u662f\u6309\u7528\u6237\u7ed1\u5b9a\u7684\uff08<code>LOCK_GROUP_CREATE_KEY = \"short-link:lock_group-create:%s\"<\/code>\uff09\uff0c\u5373<strong>\u7528\u6237\u7ea7\u522b\u9501 <\/strong>\uff0c\u4ec5\u963b\u585e\u540c\u4e00\u7528\u6237\u7684\u5e76\u53d1\u8bf7\u6c42\uff0c\u4e0d\u5f71\u54cd\u5176\u4ed6\u7528\u6237\u7684\u64cd\u4f5c\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;\u4f60\u4ece\u6811\u6797\u6df1\u5904\u8d70\u51fa\u96fe\uff1a\u800c\u4e14 Saas \u5e94\u7528\u6ca1\u6709\u5f00\u53d1\u6ce8\u518c\u63a5\u53e3\uff0c\u5927\u5bb6\u767b\u7684\u90fd\u662f\u540c\u4e00\u4e2a\u53f7\uff0c\u4e4b\u524d<a href=\"https:\/\/t.zsxq.com\/19ZbImhrA\" target=\"_blank\"  rel=\"nofollow\" >https:\/\/t.zsxq.com\/19ZbImhrA<\/a>\u4e2d\u8fd8\u7279\u5730\u5141\u8bb8\u4e86\u591a\u7aef\u767b\u5f55\uff0c\u56e0\u6b64\u4e0d\u540c\u4f7f\u7528\u8005\uff08\u4f46\u4ed6\u4eec\u662f\u540c\u4e00\u4e2a\u53f7\uff0c\u540c\u4e00\u4e2a\u7528\u6237\uff09\u5f88\u53ef\u80fd\u5728\u540c\u65f6\u6dfb\u52a0\u5206\u7ec4\u3002<\/p>\n\n\n\n<p>\u5c0f\u51e1\u540c\u5b66&nbsp;\u56de\u590d&nbsp;TheTurtle\uff1a\u591a\u7aef\u7528\u6237\u5e94\u8be5\u662f\u540c\u4e00\u4e2a\u7528\u6237\u4e0d\u540c\u8bbe\u5907\u5427 \u4e0d\u540c\u7528\u6237\u548b\u4f1a\u7528\u4e00\u4e2a\u8d26\u53f7TheTurtle\uff1aagree\uff0c\u6211\u9519\u4e86<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5e76\u53d1\u8d85\u9650\u7684\u6a21\u62df <\/strong>\uff1a<br>\u5047\u8bbe\u5f53\u524d\u7528\u6237\u5df2\u670919\u4e2a\u5206\u7ec4\uff0c\u4e24\u4e2a\u5e76\u53d1\u8bf7\u6c42\u540c\u65f6\u6267\u884c\u4ee5\u4e0b\u6b65\u9aa4\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u8bf7\u6c42A <\/strong>\uff1a\u67e5\u8be2\u5230 <code>groupDOList.size()=19<\/code> \u2192 \u5141\u8bb8\u521b\u5efa\u3002<\/li>\n\n\n\n<li><strong>\u8bf7\u6c42B <\/strong>\uff1a\u67e5\u8be2\u5230 <code>groupDOList.size()=19<\/code> \u2192 \u5141\u8bb8\u521b\u5efa\u3002<\/li>\n\n\n\n<li><strong>\u7ed3\u679c <\/strong>\uff1a\u4e24\u4e2a\u8bf7\u6c42\u5747\u63d2\u5165\u65b0\u5206\u7ec4\uff0c\u603b\u6570\u53d8\u4e3a21\uff0c\u7a81\u7834\u9650\u5236\u3002<br>\u52a0\u9501\u540e\uff0c\u4e24\u4e2a\u8bf7\u6c42\u4f1a\u4e32\u884c\u6267\u884c\uff0c\u7b2c\u4e8c\u4e2a\u8bf7\u6c42\u5728\u68c0\u67e5\u65f6\u4f1a\u53d1\u73b0\u5206\u7ec4\u6570\u5df2\u53d8\u4e3a20\uff0c\u4ece\u800c\u629b\u51fa\u5f02\u5e38\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u9501\u7684\u7c92\u5ea6\u8bbe\u8ba1 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u7528\u6237\u7ea7\u522b\u9501 <\/strong>\uff08<code>LOCK_GROUP_CREATE_KEY = \"short-link:lock_group-create:%s\"<\/code>\uff09\u5408\u7406\uff1a\n<ul class=\"wp-block-list\">\n<li>\u907f\u514d\u5168\u5c40\u9501\uff08\u5982 <code>short-link:lock_group-create<\/code>\uff09\u5bfc\u81f4\u6240\u6709\u7528\u6237\u7684\u5206\u7ec4\u64cd\u4f5c\u4e32\u884c\u5316\uff0c\u5f71\u54cd\u6027\u80fd\u3002<\/li>\n\n\n\n<li>\u4ec5\u9488\u5bf9\u540c\u4e00\u7528\u6237\u7684\u5e76\u53d1\u8bf7\u6c42\u52a0\u9501\uff0c\u5176\u4ed6\u7528\u6237\u7684\u64cd\u4f5c\u4e0d\u53d7\u5f71\u54cd\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u66ff\u4ee3\u65b9\u6848\u7684\u5c40\u9650\u6027 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u6570\u636e\u5e93\u552f\u4e00\u7ea6\u675f <\/strong>\uff1a\u65e0\u6cd5\u76f4\u63a5\u9650\u5236\u5206\u7ec4\u6570\u91cf\uff08\u9700\u7ed3\u5408\u89e6\u53d1\u5668\u6216\u989d\u5916\u8868\uff0c\u590d\u6742\u5ea6\u9ad8\uff09\u3002<\/li>\n\n\n\n<li><strong>CAS\uff08Compare and Set\uff09 <\/strong>\uff1a\u9700\u5728\u63d2\u5165\u5206\u7ec4\u65f6\u68c0\u67e5\u6570\u91cf\uff0c\u4f46\u5b9e\u73b0\u590d\u6742\u4e14\u53ef\u80fd\u5f15\u53d1\u591a\u6b21\u91cd\u8bd5\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c09\u8282\uff1a\u77ed\u94fe\u63a5\u9a8c\u8bc1\u5e03\u9686\u8fc7\u6ee4\u5668\u57df\u540d\u51b2\u7a81<img loading=\"lazy\" decoding=\"async\" height=\"319\" width=\"661\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/8cb8155409ab4b3a99c3577e31deb6fc.png\" alt=\"\"><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u539f\u4ee3\u7801\u901a\u8fc7\u5e03\u9686\u8fc7\u6ee4\u5668\u5224\u65ad\u77ed\u94fe\u63a5\u662f\u5426\u5b58\u5728\u65f6\uff0c\u4f7f\u7528\u4e86<code>requestParam.getDomain()<\/code>\u83b7\u53d6\u57df\u540d<\/li>\n\n\n\n<li>\u4f46\u5f53\u524d\u524d\u7aef\u5df2\u4e0d\u518d\u4f20\u9012domain\u53c2\u6570\uff0c\u5bfc\u81f4\u751f\u6210\u77ed\u94fe\u63a5\u65f6\u53ef\u80fd\u51fa\u73b0\u91cd\u590d\u6216\u5f02\u5e38<\/li>\n<\/ul>\n\n\n\n<p>\u73b0\u5728\u5c06\u5e03\u9686\u8fc7\u6ee4\u5668\u6821\u9a8c\u7684\u57df\u540d\u4ece<code>requestParam.getDomain()<\/code>\u6539\u4e3a<code>createShortLinkDefaultDomain<\/code>\uff08\u914d\u7f6e\u6587\u4ef6\u6307\u5b9a\u7684\u9ed8\u8ba4\u57df\u540d\uff09\uff1b\u4fdd\u8bc1\u5373\u4f7f\u524d\u7aef\u4e0d\u4f20domain\u53c2\u6570\uff0c\u4ecd\u80fd\u901a\u8fc7\u9ed8\u8ba4\u57df\u540d\u6b63\u786e\u5224\u65ad\u77ed\u94fe\u63a5\u662f\u5426\u5b58\u5728\uff1b\u4fdd\u7559\u539f\u6709\u7684\u65f6\u95f4\u6233\u62fc\u63a5\u903b\u8f91\uff0c\u9632\u6b62\u76f8\u540cURL\u77ac\u95f4\u91cd\u590d\u751f\u6210<\/p>\n\n\n\n<p>&nbsp;ShortLinkServicelmpl.java\u4fee\u6539<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">private String generateSuffix(ShortLinkCreateReqDTO requestParam) {\n\n    \/*\u53bb\u91cd\u8bd5\uff0c\u5148\u7ed9\u5b83get\u4e00\u4e2a\u539f\u59cb\u7684\u4e00\u4e2a\u94fe\u63a5\uff0c\u7136\u540e\u6211\u4eec\u8981\u5b9a\u4e49\u4e00\u4e2a\u81ea\u5b9a\u4e49\u751f\u6210\u6b21\u6570*\/\n    int customGenerateCount = 0;\n    String shortUri;\n    while (true) {\n        if (customGenerateCount &gt; 10) {\n            throw new ServiceException(\"\u77ed\u94fe\u63a5\u9891\u7e41\u751f\u6210\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5\");\n        }\n        String originUrl = requestParam.getOriginUrl();\n        originUrl += System.currentTimeMillis();\n        shortUri = HashUtil.hashToBase62(originUrl);\n        \/\/\u539f\u4e3aif (!shortUriCreateCachePenetrationBloomFilter.contains(requestParam.getDomain() + \"\/\" + shortUri)) {\n        if (!shortUriCreateCachePenetrationBloomFilter.contains(createShortLinkDefaultDomain + \"\/\" + shortUri)) {\n\n            break;\n        }\n        customGenerateCount++;\n\n    }\n    return shortUri;\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c10\u8282\uff1a\u516c\u7f51\u73af\u5883\u90e8\u7f72\u7cfb\u7edf\u5982\u4f55\u505a\u6d41\u91cf\u98ce\u63a7\uff08\u4e0a\uff09<\/h2>\n\n\n\n<p>\u9488\u5bf9\u77ed\u94fe\u63a5\u540e\u53f0\u7cfb\u7edf\u7684\u8bbf\u95ee\uff0c\u6839\u636e\u767b\u5f55\u7528\u6237\u505a\u9891\u7387\u9650\u5236\u3002\u4f8b\u5982\uff1a\u6bcf\u79d2\u5185\u5355\u4e2a\u7528\u6237\u7684\u8bf7\u6c42\u6b21\u6570\u4e0d\u8d85\u8fc7\u6307\u5b9a\u9608\u503c\u3002\u5b9e\u73b0\u539f\u7406\u5982\u4e0b\u4f7f\u7528Lua\u811a\u672c\u4fdd\u8bc1<code>INCR<\/code>\u548c<code>EXPIRE<\/code>\u7684\u539f\u5b50\u6027<\/p>\n\n\n\n<p><strong>\u7528\u6237\u4e0a\u4e0b\u6587\u83b7\u53d6<\/strong>\u4f9d\u8d56\u524d\u7f6e\u7684<code>UserContextFilter<\/code>\u5c06\u7528\u6237\u540d\u5b58\u5165\u4e0a\u4e0b\u6587\uff1b\u9ed8\u8ba4\u503c\u8bbe\u4e3a\"other\"\u5904\u7406\u533f\u540d\u8bbf\u95ee\u573a\u666f<\/p>\n\n\n\n<p>\u4f7f\u7528<code>setOrder(10)<\/code>\u9884\u7559\u6269\u5c55\u7a7a\u95f4\uff08\u540e\u7eed\u53ef\u63d2\u51655\/15\u7b49\u4e2d\u95f4\u503c\uff09<strong>\u8fc7\u6ee4\u5668\u987a\u5e8f<\/strong>\u4fdd\u8bc1\u5728\u4e1a\u52a1\u903b\u8f91\u524d\u6267\u884c<\/p>\n\n\n\n<p>\u786e\u4fdd\u5728\u7528\u6237\u4fe1\u606f\u8fc7\u6ee4\u5668\u4e4b\u540e\u6267\u884c\uff0c\u80fd\u6b63\u786e\u83b7\u53d6\u7528\u6237\u4e0a\u4e0b\u6587\uff1b\u672a\u767b\u5f55\u7528\u6237\u7edf\u4e00\u5f52\u4e3a\"other\"\u6807\u8bc6\uff0c\u9632\u6b62\u7a7a\u6307\u9488\u5f02\u5e38<\/p>\n\n\n\n<p><strong>\u52a8\u6001\u914d\u7f6e\u7ba1\u7406 <\/strong>\uff1a\u901a\u8fc7<code>@ConditionalOnProperty<\/code>\u63a7\u5236\u529f\u80fd\u5f00\u5173\uff1b\u540e\u7eed\u53ef\u901a\u8fc7\u52a8\u6001\u914d\u7f6e\u4e2d\u5fc3\u5b9e\u73b0\u8fd0\u884c\u65f6\u53c2\u6570\u8c03\u6574<\/p>\n\n\n\n<p>Redis\u5f02\u5e38\u6355\u83b7\u540e\u8fd4\u56de\u7edf\u4e00\u9519\u8bef\u7801A000300<\/p>\n\n\n\n<p>1\u79d2\u5185\u8fde\u7eed\u53d1\u900120\u6b21\u8bf7\u6c42 \u2192 \u6210\u529f\uff1b\u7b2c21\u6b21\u8bf7\u6c42 \u2192 \u8fd4\u56de\"\u5f53\u524d\u7cfb\u7edf\u7e41\u5fd9\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5\"\uff1bRedis\u670d\u52a1\u5f02\u5e38 \u2192 \u8bb0\u5f55\u9519\u8bef\u65e5\u5fd7\u5e76\u62d2\u7edd\u8bf7\u6c42\uff1b\u914d\u7f6e\u5173\u95ed(<code>enable: false<\/code>) \u2192 \u4e0d\u89e6\u53d1\u9650\u6d41\u903b\u8f91<\/p>\n\n\n\n<p>\u5728(admin\\common\\biz\\user\u65b0\u5efaUserFlowRiskControlFilter<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.common.biz.user;\n\nimport com.alibaba.fastjson2.JSON;\nimport com.google.common.collect.Lists;\nimport com.nageoffer.shortlink.admin.common.convention.exception.ClientException;\nimport com.nageoffer.shortlink.admin.common.convention.result.Results;\nimport com.nageoffer.shortlink.admin.config.UserFlowRiskControlConfiguration;\nimport jakarta.servlet.Filter;\nimport jakarta.servlet.FilterChain;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\nimport jakarta.servlet.http.HttpServletResponse;\nimport lombok.RequiredArgsConstructor;\nimport lombok.SneakyThrows;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.core.io.ClassPathResource;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.data.redis.core.script.DefaultRedisScript;\nimport org.springframework.scripting.support.ResourceScriptSource;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.util.Optional;\n\nimport static com.nageoffer.shortlink.admin.common.convention.errorCode.BaseErrorCode.FLOW_LIMIT_ERROR;\n\n\/**\n * \u7528\u6237\u64cd\u4f5c\u6d41\u91cf\u98ce\u63a7\u8fc7\u6ee4\u5668\n *\/\n@Slf4j\n@RequiredArgsConstructor\npublic class UserFlowRiskControlFilter implements Filter {\n\n    private final StringRedisTemplate stringRedisTemplate;\n    private final UserFlowRiskControlConfiguration userFlowRiskControlConfiguration;\n\n    private static final String USER_FLOW_RISK_CONTROL_LUA_SCRIPT_PATH = \"lua\/user_flow_risk_control.lua\";\n\n    @SneakyThrows\n    @Override\n    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {\n        DefaultRedisScript&lt;Long&gt; redisScript = new DefaultRedisScript&lt;&gt;();\n        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource(USER_FLOW_RISK_CONTROL_LUA_SCRIPT_PATH)));\n        redisScript.setResultType(Long.class);\n        String username = Optional.ofNullable(UserContext.getUsername()).orElse(\"other\");\n        Long result = null;\n        try {\n            result = stringRedisTemplate.execute(redisScript, Lists.newArrayList(username), userFlowRiskControlConfiguration.getTimeWindow());\n        } catch (Throwable ex) {\n            log.error(\"\u6267\u884c\u7528\u6237\u8bf7\u6c42\u6d41\u91cf\u9650\u5236LUA\u811a\u672c\u51fa\u9519\", ex);\n            returnJson((HttpServletResponse) response, JSON.toJSONString(Results.failure(new ClientException(FLOW_LIMIT_ERROR))));\n        }\n        if (result == null || result &gt; userFlowRiskControlConfiguration.getMaxAccessCount()) {\n            returnJson((HttpServletResponse) response, JSON.toJSONString(Results.failure(new ClientException(FLOW_LIMIT_ERROR))));\n        }\n        filterChain.doFilter(request, response);\n    }\n\n    private void returnJson(HttpServletResponse response, String json) throws Exception {\n        response.setCharacterEncoding(\"UTF-8\");\n        response.setContentType(\"text\/html; charset=utf-8\");\n        try (PrintWriter writer = response.getWriter()) {\n            writer.print(json);\n        }\n    }\n}\n<\/pre>\n\n\n\n<p>ladmin\\common\\convention\\errorcode\u91cc\u9762BaseErrorCode.java\u6dfb\u52a0\u9519\u8bef\u7801<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ ========== \u4e8c\u7ea7\u5b8f\u89c2\u9519\u8bef\u7801 \u7cfb\u7edf\u8bf7\u6c42\u64cd\u4f5c\u9891\u7e41 ==========\nFLOW_LIMIT_ERROR(\"A000300\", \"\u5f53\u524d\u7cfb\u7edf\u7e41\u5fd9\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5\"),<\/pre>\n\n\n\n<p>UserConfiguration.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/**\n * \u7528\u6237\u64cd\u4f5c\u6d41\u91cf\u98ce\u63a7\u8fc7\u6ee4\u5668\n *\/\n@Bean\n@ConditionalOnProperty(name = \"short-link.flow-limit.enable\", havingValue = \"true\")\npublic FilterRegistrationBean&lt;UserFlowRiskControlFilter&gt; globalUserFlowRiskControlFilter(\n        StringRedisTemplate stringRedisTemplate,\n        UserFlowRiskControlConfiguration userFlowRiskControlConfiguration) {\n    FilterRegistrationBean&lt;UserFlowRiskControlFilter&gt; registration = new FilterRegistrationBean&lt;&gt;();\n    registration.setFilter(new UserFlowRiskControlFilter(stringRedisTemplate, userFlowRiskControlConfiguration));\n    registration.addUrlPatterns(\"\/*\");\n    registration.setOrder(10);\n    return registration;\n}<\/pre>\n\n\n\n<p>admin\\config\u91cc\u9762\u65b0\u5efa&nbsp;UserFlowRiskControlConfiguration.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.config;\n\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\nimport org.springframework.stereotype.Component;\n\n\/**\n * \u7528\u6237\u64cd\u4f5c\u6d41\u91cf\u98ce\u63a7\u914d\u7f6e\u6587\u4ef6\n *\/\n@Data\n@Component\n@ConfigurationProperties(prefix = \"short-link.flow-limit\")\npublic class UserFlowRiskControlConfiguration {\n\n    \/**\n     * \u662f\u5426\u5f00\u542f\u7528\u6237\u6d41\u91cf\u98ce\u63a7\u9a8c\u8bc1\n     *\/\n    private Boolean enable;\n\n    \/**\n     * \u6d41\u91cf\u98ce\u63a7\u65f6\u95f4\u7a97\u53e3\uff0c\u5355\u4f4d\uff1a\u79d2\n     *\/\n    private String timeWindow;\n\n    \/**\n     * \u6d41\u91cf\u98ce\u63a7\u65f6\u95f4\u7a97\u53e3\u5185\u53ef\u8bbf\u95ee\u6b21\u6570\n     *\/\n    private Long maxAccessCount;\n}\n<\/pre>\n\n\n\n<p>application.yaml\u8865\u5145<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">flow-limit:\n  enable: true\n  time-window: 1\n  max-access-count: 20<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Q8Q7d\">\u77ed\u94fe\u63a5\u540e\u7ba1<\/h3>\n\n\n\n<p id=\"uba77d5b1\">\u6839\u636e\u767b\u5f55\u7528\u6237\u505a\u51fa\u63a7\u5236\uff0c\u6bd4\u5982 x \u79d2\u8bf7\u6c42\u540e\u7ba1\u7cfb\u7edf\u7684\u9891\u7387\u6700\u591a x \u6b21\u3002<\/p>\n\n\n\n<p id=\"ua6834103\">\u5b9e\u73b0\u539f\u7406\u4e5f\u6bd4\u8f83\u7b80\u5355\uff0c\u901a\u8fc7 Redis <code>increment<\/code> \u547d\u4ee4\u5bf9\u4e00\u4e2a\u6570\u636e\u8fdb\u884c\u9012\u589e\uff0c\u5982\u679c\u8d85\u8fc7 x \u6b21\u5c31\u4f1a\u8fd4\u56de\u5931\u8d25\u3002\u8fd9\u91cc\u6709\u4e2a\u7ec6\u8282\u5c31\u662f\u6211\u4eec\u7684\u8fd9\u4e2a\u5468\u671f\u662f x \u79d2\uff0c\u9700\u8981\u5bf9 Redis \u7684 Key \u8bbe\u7f6e x \u79d2\u6709\u6548\u671f\u3002<\/p>\n\n\n\n<p id=\"ua01d34bc\">\u4f46\u662f Redis \u4e2d\u5bf9\u4e8e <code>increment<\/code> \u547d\u4ee4\u662f\u6ca1\u6709\u63d0\u4f9b\u8fc7\u671f\u547d\u4ee4\u7684\uff0c\u8fd9\u5c31\u9700\u8981\u4e24\u6b65\u64cd\u4f5c\uff0c\u8fdb\u800c\u51fa\u73b0\u539f\u5b50\u6027\u95ee\u9898\u3002<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"682\" width=\"1602\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/077d676023a66b8893277295cff7feb5.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"u57a632c1\">\u4e3a\u6b64\uff0c\u6211\u4eec\u9700\u8981\u901a\u8fc7 LUA \u811a\u672c\u6765\u4fdd\u8bc1\u539f\u5b50\u6027\u3002<\/p>\n\n\n\n<pre id=\"cHIVQ\" class=\"wp-block-code\"><code>-- \u8bbe\u7f6e\u7528\u6237\u8bbf\u95ee\u9891\u7387\u9650\u5236\u7684\u53c2\u6570\nlocal username = KEYS&#91;1]\nlocal timeWindow = tonumber(ARGV&#91;1]) -- \u65f6\u95f4\u7a97\u53e3\uff0c\u5355\u4f4d\uff1a\u79d2\n\n-- \u6784\u9020 Redis \u4e2d\u5b58\u50a8\u7528\u6237\u8bbf\u95ee\u6b21\u6570\u7684\u952e\u540d\nlocal accessKey = \"short-link:user-flow-risk-control:\" .. username\n\n-- \u539f\u5b50\u9012\u589e\u8bbf\u95ee\u6b21\u6570\uff0c\u5e76\u83b7\u53d6\u9012\u589e\u540e\u7684\u503c\nlocal currentAccessCount = redis.call(\"INCR\", accessKey)\n\n-- \u8bbe\u7f6e\u952e\u7684\u8fc7\u671f\u65f6\u95f4\nredis.call(\"EXPIRE\", accessKey, timeWindow)\n\n-- \u8fd4\u56de\u5f53\u524d\u8bbf\u95ee\u6b21\u6570\nreturn currentAccessCount<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>1. \u8fd4\u56de\u9519\u8bef\u6570\u636e\u540e\u5fd8\u8bb0\u52a0 return \u4e86\uff0c\u6211\u7684\u9505\u3002\u8fd9\u4e2a\u4ee3\u7801\u91cc\u63d0\u4ea4\u4e86\u4e24\u4e2a\u8fd4\u56de\u5173\u952e\u5b57\uff1areturn<a href=\"https:\/\/gitee.com\/nageoffer\/shortlink\/commit\/c6e43cc809a0c2e964e762df8f47d8e944d64c41\" target=\"_blank\"  rel=\"nofollow\" >\u767b\u5f55 - Gitee.com<\/a><\/p>\n\n\n\n<p>\u5728 Servlet \u4e2d\uff0c\u4e00\u65e6\u8c03\u7528 response.getWriter() \u5e76\u5199\u5165\u54cd\u5e94\u4f53\uff0c\u54cd\u5e94\u5373\u88ab\u63d0\u4ea4\uff08committed\uff09\u3002\u540e\u7eed\u82e5\u8c03\u7528 filterChain.doFilter\uff0c\u4f1a\u629b\u51fa IllegalStateException\uff08\u56e0\u4e3a\u54cd\u5e94\u5df2\u63d0\u4ea4\uff09\u3002<br>\u867d\u7136\u6846\u67b6\u4f1a\u963b\u6b62\u540e\u7eed\u6267\u884c\uff0c\u4f46\u663e\u5f0f return \u66f4\u6e05\u6670\uff0c\u907f\u514d\u6f5c\u5728\u95ee\u9898\uff08\u5982\u65e5\u5fd7\u8bb0\u5f55\u3001\u8c03\u8bd5\u6df7\u4e71\uff09\u3002\u8865\u5145 return \u63d0\u5347\u4e86\u53ef\u7ef4\u62a4\u6027\u3002<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>2. \u738b\u5c0f\u660e\uff1a\u8fd9\u91cc\u62ff\u4e0d\u5230UserContext\u4e2d\u7684username\u5c31\u7528others\uff0c\u5c82\u4e0d\u662f\u591a\u4e2a\u7528\u6237\u6ce8\u518c\u7684\u65f6\u5019\u5c31\u88ab\u9650\u6d41\u4e86\uff1f<\/p>\n\n\n\n<p>\u4e00\u5207\u968f\u7f18&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u8d5e\u540c<\/p>\n\n\n\n<p>\u7ed9\u8da3\u591a\u591a\u5de7\u514b\u529b\u8c46&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u611f\u89c9\u6ca1\u529e\u6cd5\u907f\u514d\u8fd9\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u5bf9\u8fd9\u4e2a\u63a5\u53e3\u5f00\u653e\u7684\u8bdd\uff0c\u53ef\u80fd\u574f\u4eba\u4e5f\u4f1a\u902e\u7740\u8fd9\u4e2a\u63a5\u53e3\u4e0d\u505c\u8bf7\u6c42<\/p>\n\n\n\n<p>B1n_&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u6211\u4eec\u4e0d\u662f\u5c4f\u853d\u4e86\u7528\u6237\u6ce8\u518c\u63a5\u53e3\u4e86\u5417<\/p>\n\n\n\n<p>\u65e9\u7761\u65e9\u8d77\u8eab\u4f53\u597d&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u5c4f\u853d\u7528\u6237\u63a5\u53e3\u4e86<\/p>\n\n\n\n<p>\ud83c\udf83 \ud83c\udf83 \ud83c\udf83&nbsp;\u56de\u590d&nbsp;B1n_\uff1a\u5728\u54ea\u5c4f\u853d\u7684\u5440 \u914d\u7f6e\u6ce8\u518c\u5668\u65f6\u4e5f\u6ca1\u770b\u5230\u5c4f\u853d\u6ce8\u518c\u8def\u5f84\u554a<\/p>\n\n\n\n<p>\u795e\u7ecf\u86d9&nbsp;\u56de\u590d&nbsp;B1n_\uff1a\u6ca1\u6709\u53ea\u662f\u7b2c\u4e00\u4e2a\u8fc7\u6ee4\u5668\u8fdb\u884c\u4e86\u653e\u884c\uff0c\u697c\u4e3b\u8bf4\u7684\u7b2c\u4e8c\u4e2a\u8fc7\u6ee4\u5668\u5e76\u6ca1\u6709\u8fdb\u884c\u653e\u884c\uff0c\u4f60\u53ef\u4ee5\u8fdb\u884c\u8c03\u8bd5\u4e00\u4e0b<\/p>\n\n\n\n<p>\u795e\u7ecf\u86d9&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u6216\u8bb8other\u540e\u9762\u62fc\u63a5\u4e00\u4e2auuid?<\/p>\n<\/blockquote>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u82e5\u7cfb\u7edf\u5141\u8bb8\u533f\u540d\u8bbf\u95ee\uff08\u5982\u672a\u767b\u5f55\u7528\u6237\u53ef\u521b\u5efa\u77ed\u94fe\u63a5\uff09\uff0c\u6240\u6709\u533f\u540d\u7528\u6237\u7684\u8bf7\u6c42\u4f1a\u88ab\u89c6\u4e3a\u540c\u4e00\u7528\u6237\uff08<code>\"other\"<\/code>\uff09\uff0c\u5bfc\u81f4\u9650\u6d41\u9608\u503c\u88ab\u5171\u4eab\u5360\u7528\u3002<\/li>\n\n\n\n<li>\u4f8b\u5982\uff1a20\u4e2a\u533f\u540d\u7528\u6237\u5e76\u53d1\u8bf7\u6c42\uff0c\u6bcf\u4e2a\u7528\u6237\u8bf7\u6c421\u6b21\uff0c<code>\"other\"<\/code> \u952e\u7684\u8ba1\u6570\u5668\u8fbe\u523020\uff0c\u540e\u7eed\u6240\u6709\u533f\u540d\u7528\u6237\u5747\u88ab\u9650\u6d41\u3002\u82e5\u9700\u533a\u5206\u533f\u540d\u7528\u6237\uff0c\u53ef\u7528 IP \u5730\u5740\u6216\u8bbe\u5907\u6307\u7eb9\u751f\u6210\u552f\u4e00\u6807\u8bc6\uff08\u5982 <code>other_${ip}<\/code>\uff09\u3002\u4f46\u82e5\u4e1a\u52a1\u5df2\u7981\u6b62\u533f\u540d\u8bbf\u95ee\uff08\u5982\u5f3a\u5236\u767b\u5f55\uff09\uff0c\u6b64\u95ee\u9898\u4e0d\u5b58\u5728\u3002<\/li>\n\n\n\n<li><strong>\u7ed3\u8bba <\/strong>\uff1a\u738b\u5c0f\u660e\u6307\u51fa\u6f5c\u5728\u8bbe\u8ba1\u7f3a\u9677\uff0c\u56de\u590d\u4e2d <code>B1n_<\/code> \u548c <code>\u65e9\u7761\u65e9\u8d77\u8eab\u4f53\u597d<\/code> \u7684\u201c\u5c4f\u853d\u6ce8\u518c\u63a5\u53e3\u201d\u8bf4\u6cd5\u4e0d\u6210\u7acb\uff08\u533f\u540d\u8bbf\u95ee\u2260\u6ce8\u518c\u63a5\u53e3\uff09\uff0c\u9700\u660e\u786e\u4e1a\u52a1\u573a\u666f<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>3. \uff1a\u8fd9\u4e2alua\u811a\u672c\u91cc\u9762\u6bcf\u6b21\u8bbf\u95ee\u90fd\u66f4\u65b0\u8fc7\u671f\u65f6\u95f4\uff0c\u5982\u679c\u6bcf\u6b21\u90fd\u5728\u5373\u5c06\u8fc7\u671f\u7684\u65f6\u5019\u8bbf\u95ee\u4e86\u5237\u65b0\u4e86\u8fc7\u671f\u65f6\u95f4\uff0c\u4e00\u76f4\u9012\u589e\u4f1a\u62a5\u9519\u5427\u3002\u6539\u6210\u5982\u679c\u5b58\u5728key\u4e0d\u5237\u65b0\u65f6\u95f4\uff0c\u4e0d\u5b58\u5728key\u65b0\u589e\u5e76\u4e14\u8bbe\u7f6e\u8fc7\u671f\u65f6\u95f4\u662f\u4e0d\u662f\u66f4\u5408\u7406<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>--\u8bbe\u7f6e\u7528\u6237\u8bbf\u95ee\u9891\u7387\u9650\u5236\u7684\u53c2\u6570\nlocal username = KEYS&#91;1]\nlocal timeWindow =tonumber\uff08ARGV&#91;1]\uff09--\u65f6\u95f4\u7a97\u53e3\uff0c\u5355\u4f4d\uff1a\u79d2\n\n--\u6784\u9020Redis\u4e2d\u5b58\u50a8\u7528\u6237\u8bbf\u95ee\u6b21\u6570\u7684\u952e\u540d\nlocal accessKey = \"short-link:user-flow-risk-control:\" .. Username\n\n--\u539f\u5b50\u9012\u589e\u8bbf\u95ee\u6b21\u6570\uff0c\u5e76\u83b7\u53d6\u9012\u589e\u540e\u7684\u503c\nlocal currentAccessCount = redis.call(\"INcR\", accessKey)\n\n--\u8bbe\u7f6e\u952e\u7684\u8fc7\u671f\u65f6\u95f4\nredis.call(\"EXPIRE\", accessKey, timeWindow)\n\n--\u8fd4\u56de\u5f53\u524d\u8bbf\u95ee\u6b21\u6570\nreturn currentAccessCount<\/code><\/pre>\n\n\n\n<p>\u5f88\u5bf9\uff0c\u540e\u9762\u4f1a\u91cd\u6784\uff1b\u6709\u95ee\u9898\u7684\u3002\u3010\u4e00\u79cd\u8fb9\u754c\u60c5\u51b5\u3011\u5047\u8bbe\u8fc7\u671f\u65f6\u95f4\u662f1s\uff0c\u9650\u52361s\u5185\u53ea\u80fd\u8bbf\u95ee20\u6b21\u3002\u5982\u679c\u5728\u5373\u5c06\u8fc7\u671f\u7684\u65f6\u5019\u5237\u65b0\u4e86\u8fc7\u671f\u65f6\u95f4\uff0c\u5373\u53c8\u83b7\u5f97\u4e861s\uff0c\u90a3\u4e48\u4f1a\u7ee7\u7eed\u5728\u4e4b\u524d\u8ba1\u6570\u503c\u7684\u57fa\u7840\u4e0a\u9012\u589e\uff0c\u5047\u8bbe\u4e4b\u524d\u9012\u589e\u523019\u4e86\uff0c\u90a3\u4e48\u4e4b\u540e\u76841s\u5185\u7684\u8bf7\u6c42\u5168\u90e8\u90fd\u4f1a\u88ab\u8fc7\u6ee4\u6389\uff0c\u56e0\u4e3a\u8fd9\u4e2akey\u88ab\u7eed\u65f6\u957f\u4e86\uff0c\u4f46\u5176\u5b9e\u65b0\u76841s\u5e94\u8be5\u91cd\u65b0\u8ba1\u6570\u7684\u3002<\/p>\n<\/blockquote>\n\n\n\n<p><strong>\u5b8c\u5168\u6b63\u786e<\/strong>&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>4.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u6539\u8fc7\u7684lua\u811a\u672c  \u597d\uff01\n\nlocal username = KEYS&#91;1]\nlocal timeWindow = tonumber(ARGV&#91;1]) -- \u65f6\u95f4\u7a97\u53e3\uff0c\u5355\u4f4d\uff1a\u79d2\n-- \u6784\u9020 Redis \u4e2d\u5b58\u50a8\u7528\u6237\u8bbf\u95ee\u6b21\u6570\u7684\u952e\u540d\nlocal accessKey = \"short-link:user-flow-risk-control:\" .. username\n-- \u68c0\u67e5\u952e\u662f\u5426\u5b58\u5728\nlocal keyExists = redis.call(\"EXISTS\", accessKey)\n-- \u82e5\u952e\u5df2\u5b58\u5728\uff0c\u539f\u5b50\u9012\u589e\u8bbf\u95ee\u6b21\u6570\u5e76\u8fd4\u56de\u9012\u589e\u540e\u7684\u503c\nif keyExists == 1 then\n    local currentAccessCount = redis.call(\"INCR\", accessKey)\nreturn currentAccessCount\nelse    -- \u82e5\u952e\u4e0d\u5b58\u5728\uff0c\u521b\u5efa\u952e\u5e76\u8bbe\u7f6e\u8fc7\u671f\u65f6\u95f4\uff0c\u7136\u540e\u539f\u5b50\u9012\u589e\u8bbf\u95ee\u6b21\u6570\u5e76\u8fd4\u56de\u9012\u589e\u540e\u7684\u503c\n    redis.call(\"SET\", accessKey, 1, \"EX\", timeWindow)\n    local currentAccessCount = redis.call(\"INCR\", accessKey)\n    return currentAccessCount\nend<\/code><\/pre>\n\n\n\n<p>\u6839\u636e\u6211\u7684\u6700\u65b0\u91cd\u6784\u903b\u8f91\uff0c\u8981\u6bd4\u8fd9\u4e2a\u7b80\u5355\u4e00\u4e9b\u3002\u91cd\u70b9\u5728\u4e8e\uff0c\u5982\u679c\u8fd4\u56de\u81ea\u589e\u4e3a 1\u5c31\u8bc1\u660e\u662f\u65b0\u7684\u6570\u636e\uff0c\u5982\u4e0b\u6240\u793a\uff0c\u4f9b\u53c2\u8003\uff1a -- \u539f\u5b50\u9012\u589e\u8bbf\u95ee\u6b21\u6570\uff0c\u5e76\u83b7\u53d6\u9012\u589e\u540e\u7684\u503c local currentAccessCount = redis.call(\"INCR\", accessKey) -- \u8bbe\u7f6e\u952e\u7684\u8fc7\u671f\u65f6\u95f4 if currentAccessCount == 1 then redis.call(\"EXPIRE\", accessKey, timeWindow) end<\/p>\n\n\n\n<p>redis\u5b98\u65b9\u4e5f\u63d0\u4f9b\u4e86\u51e0\u79cd\u65b9\u6848\uff1a<a href=\"https:\/\/redis.io\/docs\/latest\/commands\/incr\/\" target=\"_blank\"  rel=\"nofollow\" >INCR | Docs<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>\u5b9e\u9645\u4e0a\u65b9\u6848\u4e8c\u7684<code>EXISTS<\/code> + <code>INCR<\/code> + <code>SET<\/code> \u7ec4\u5408\u903b\u8f91\u590d\u6742\uff0c\u4e14 <code>SET<\/code> \u548c <code>INCR<\/code> \u4e4b\u95f4\u5b58\u5728\u7ade\u4e89\u6761\u4ef6\uff08\u53ef\u80fd\u5bfc\u81f4\u8ba1\u6570\u9519\u8bef\uff09\u8fd8\u662f\u5f00\u59cb\u90a3\u4e2a\u201c \u6539\u8fc7\u7684lua\u811a\u672c\u201d \u597d<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>5..\u6709\u70b9\u50cf\u9650\u6d41\uff0c\u53ef\u4ee5\u7528zset\u6ed1\u52a8\u7a97\u53e3\u7684\u65b9\u6cd5\u8fdb\u884c\u9650\u6d41\u5417<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ZSet<\/code> \u53ef\u5b58\u50a8\u6bcf\u4e2a\u8bf7\u6c42\u7684\u65f6\u95f4\u6233\uff0c\u901a\u8fc7\u79fb\u9664\u8fc7\u671f\u65f6\u95f4\u6233\u5b9e\u73b0\u7cbe\u786e\u9650\u6d41\uff08\u5982\u201c\u6bcf\u79d2\u6700\u591a20\u6b21\u201d\u4e25\u683c\u6309\u65f6\u95f4\u7a97\u53e3\u8ba1\u7b97\uff09\u3002\u9002\u7528\u4e8e\u5bf9\u9650\u6d41\u7cbe\u5ea6\u8981\u6c42\u9ad8\u7684\u573a\u666f\uff0c\u4f46\u9700\u8bc4\u4f30\u6027\u80fd\u5f00\u9500<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c11\u8282\uff1a\u516c\u7f51\u73af\u5883\u90e8\u7f72\u7cfb\u7edf\u5982\u4f55\u505a\u6d41\u91cf\u98ce\u63a7\uff08\u4e0b\uff09<\/h2>\n\n\n\n<p id=\"ua950e0f8\">\u6839\u636e\u63a5\u53e3\u8fdb\u884c\u6d41\u63a7\uff0c\u6bd4\u5982\u540c\u4e00\u63a5\u53e3\u6700\u5927\u63a5\u53d7 20 QPS\u3002<\/p>\n\n\n\n<p id=\"ud0798377\">Sentinel \u5b98\u7f51\u5730\u5740\uff0c\u5176\u4e2d\u7684\u5fae\u670d\u52a1\u751f\u6001\u56fe\u8fd8\u4e0d\u9519\u3002<a href=\"https:\/\/sentinelguard.io\/zh-cn\/\" target=\"_blank\"  rel=\"nofollow\" >home | Sentinel<\/a><\/p>\n\n\n\n<p>Sentinel \u662f\u9762\u5411\u5206\u5e03\u5f0f\u3001\u591a\u8bed\u8a00\u5f02\u6784\u5316\u670d\u52a1\u67b6\u6784\u7684\u6d41\u91cf\u6cbb\u7406\u7ec4\u4ef6\uff0c\u4e3b\u8981\u4ee5\u6d41\u91cf\u4e3a\u5207\u5165\u70b9\uff0c\u4ece\u6d41\u91cf\u63a7\u5236\u3001\u6d41\u91cf\u8def\u7531\u3001\u7194\u65ad\u964d\u7ea7\u3001\u7cfb\u7edf\u81ea\u9002\u5e94\u4fdd\u62a4\u7b49\u591a\u4e2a\u7ef4\u5ea6\u6765\u5e2e\u52a9\u7528\u6237\u4fdd\u969c\u5fae\u670d\u52a1\u7684\u7a33\u5b9a\u6027\u3002<br>\u7b80\u5355\u7684\u4e00\u53e5\u8bdd\u5c31\u662f\u5f53\u4f60\u7684\u670d\u52a1\u6216\u8005\u4f60\u7684\u67d0\u4e2a\u63a5\u53e3\u5b83\u4eec\u7edf\u4e00\u53eb\u505a\u8d44\u6e90\uff1b\u4e00\u4e2a\u4e0a\u9650\u503c\uff0c\u5982\u679c\u8d85\u8fc7\u4e0a\u9650\u5b83\u53ef\u4ee5\u901a\u8fc7\u5e72\u4ec0\u4e48\uff1f\u7ed9\u4f60\u628a\u8981\u4e48\u53ef\u4ee5\u76f4\u63a5\u628a\u5b83\u6390\u65ad\u6389\uff0c\u76f4\u63a5\u5feb\u901f\u8fd4\u56de\u5931\u8d25\u8981\u4e48\u53ef\u4ee5\u7ed9\u4f60\u964d\u7ea7\u6bd4\u5982\u8bf4\u4f60\u4e4b\u524d\u5bf9\u5427\uff1f\u662f\u9700\u8981\u8c03\u7528\u591a\u4e2a\u670d\u52a1\u53bb\u7ec4\u88c5\u4f60\u7684\u6570\u636e\uff0c\u4f46\u662f\u5982\u679c\u8bf4kps\u8d85\u4e86\u4e4b\u540e\uff0c\u4f60\u7684\u7cfb\u7edf\u7684\u8d1f\u8f7d\u91cf\u5bf9\u5427\uff1f\u4f1a\u6bd4\u8f83\u62c9\u9ad8\uff0c\u8fd9\u4e2a\u60c5\u51b5\u4e0b\u6211\u4eec\u5c31\u53ef\u4ee5\u5e72\u4ec0\u4e48\uff1f\u7ed9\u4ed6\u76f4\u63a5\u8fd4\u56de\u4e00\u4e2a\u9759\u6001\u7684\u6570\u636e\uff0c\u6216\u8005\u8bf4\u4e00\u4e2a\u6ca1\u90a3\u4e48\u51c6\u786e\u7684\u6570\u636e\u76f4\u63a5\u53cd\u9988\u51fa\u53bb\uff0c\u8fd9\u6837\u7684\u8bdd\u5176\u5b9e\u4f60\u7684\u7cfb\u7edf\u8d1f\u8f7d\u5c31\u4f1a\u964d\u5230\u5f88\u4f4e<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"1162\" width=\"1794\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c4a0e8813b644bb9ad44589a3b1f026b.png\" alt=\"\"><\/p>\n\n\n\n<p>\u770b\u4e00\u4e0b\u5b83\u8fd9\u91cc\u753b\u4e00\u5f20\u56fe\u6211\u89c9\u5f97\u633a\u8003\u7a76\u7684\uff0c\u5c31\u662f\u4ece\u6211\u4eec\u7684IOT PC MOBILE\u5bf9\u5427\uff1f\u4e5f\u5c31\u662f lt\u597d\u50cf\u662f\u548c\u54ea\u4e2a\u6982\u5ff5\u6709\u5173\u7684\uff0c\u6211\u6709\u70b9\u5fd8\u4e86\uff0c\u4f46\u662fpc\u5c31\u662f\u6211\u4eec\u7684\u7f51\u9875\u7aef\u8fd8\u6709\u624b\u673a\uff0c\u7136\u540e\u901a\u8fc7\u8bbf\u95ee\uff0c\u7136\u540e\u8bbf\u95ee\u7684\u7b2c\u4e00\u5173\u5148\u8fc7\u7f51\u5173\uff0c\u8fd9\u4e2a\u7f51\u5173\u53ef\u4ee5\u662fspringcloud\uff0c\u4e5f\u53ef\u4ee5\u662fnginx\uff0c\u4e5f\u53ef\u4ee5\u662f\u4efb\u4f55\u7684\u7f51\u5173\u4ea7\u54c1\uff0c\u4f46\u662f\u8fd9\u91cc\u9762\u662f\u963f\u91cc\u81ea\u5df1\u5f00\u5c55\u7684higress\u7136\u540e\u6211\u4eec\u7ee7\u7eed\u7136\u540e\u5230\u8fd9\u8fb9\u7684\u8bdd\u662f\u5230springcloud\u6216\u8005\u8bf4dubbo\u4e00\u4e2a\u96c6\u7fa4\uff0c\u7136\u540e\u8fd9\u662f\u4e00\u4e2aab\u96c6\u7fa4\u5bf9\u5427\uff1f\u53ef\u80fd\u6bd4\u5982\u8bf4\u662f\u5546\u54c1\u670d\u52a1\uff0c\u53ef\u80fd\u662f\u8ba2\u5355\u670d\u52a1\u7b49\u7b49\uff0c\u7136\u540e\u5f02\u6b65\u670d\u52a1\u7684\u5e94rabbitMQ\uff0c\u7136\u540e\u8fd9\u8fb9\u6570\u636e\u53ef\u80fd\u8fd9\u4e2a\u4e1c\u897f\u7136\u540e\u662fmysql\uff0cPG\u7b49\u4e1c\u897f\uff0c\u7136\u540e\u5206\u5e03\u5f0f\u670d\u52a1\u662fSeata\uff0c\u7136\u540e\u8fd9\u8fb9\u7684\u8bdd\u662fsentinel\u7cfb\u7edf\u4e5f\u5c31\u662f\u8d77\u5230\u6bd4\u8f83\u91cd\u8981\u7684\u4f5c\u7528\uff0c\u6df7\u6c8c\u5de5\u7a0bchaosblade\u653e\u5728\u8fd9\u91cc\u8fb9\u7684\u4e00\u4e2a\u8fc7\u7a0b\u5927\u5bb6\u53ef\u4ee5\u53bb\u4e86\u89e3\u4e00\u4e0b\uff0c\u76f8\u5f53\u4e8e\u6bd4\u5982\u8bf4\u4f60\u670910\u4e2a\u670d\u52a1\u5728\u6b63\u5e38\u7684\u8fd0\u884c\uff0c\u7136\u540e\u6846\u5bf9\u5427\uff1f\u542f\u52a8\u8fd9\u6837\u7684\u670d\u52a1\u6216\u8005\u4ec0\u4e48\u7684\u6a21\u62df\u76f4\u63a5\u628a\u4e24\u4e2a\u670d\u52a1\u7ed9\u5e72\u6389\u6216\u8005\u8bf4\u6a21\u62df\u7684\u7f51\u901f\u9650\u5236\u7b49\u7b49\u90fd\u53ef\u4ee5\u901a\u8fc7\u53bb\u505a\uff0c\u76f8\u5f53\u4e8e\u81ea\u5df1\u7ed9\u81ea\u5df1\u627e\u4e8b\u60c5\u6765\u6a21\u62df\u6b63\u5e38\u60c5\u51b5\uff0c\u7136\u540e\u907f\u514d\u4f60\u518d\u9047\u5230\u8fd9\u79cd\u60c5\u51b5\u7684\u65f6\u5019\u624b\u8db3\u65e0\u63aa\uff0c\u6216\u8005\u8bf4\u901a\u8fc7\u8fd9\u79cd\u5f02\u5e38\u7684\u60c5\u51b5\u6765\u8bf4\uff0c\u4f60\u4eec\u7cfb\u7edf\u7a33\u5b9a\u6027\u5bf9\u5427\uff1f\u80fd\u4e0d\u80fd\u5feb\u901f\u7684\u56de\u6eda\uff0c\u6216\u8005\u8bf4\u5feb\u901f\u7684\u628a\u95ee\u9898\u4fee\u590d\u6389\u7b49\u7b49\uff0c\u7136\u540e\u662f\u4ec0\u4e48\u6211\u770b\u4e00\u4e0b\u3002\u6211\u8fd8\u6ca1\u592a\u4e86\u89e3\u8fc7\u5927\u5bb6\u6709\u5174\u8da3\u53ef\u4ee5\u81ea\u5df1\uff1b\u7136\u540e\u8fd9\u8fb9\u7684\u8bdd\u5c31\u662f\u4e00\u4e2a\u4ea4\u4e92\u8f6f\u4ef6kubevela\uff0c\u53ef\u4ee5\u76f8\u5f53\u4e8e\u662f\u7c7b\u4f3c\u4e8e\u4ec0\u4e48 csd\u7684 k8S\uff0c\u7136\u540e\u8fd9\u8fb9\u7684\u8bdd\u53ef\u89c2\u6d4bskywalking\uff0c\u7136\u540e\u62c9\u514b\u65af\u5c31\u662f\u6211\u4eec\u7684\u6ce8\u518c\u4e2d\u5fc3\u548c\u914d\u5957\u4e2d\u5fc3\uff0c\u7136\u540e opensergo\u8fd9\u4e2a\u4e1c\u897f\u600e\u4e48\u8bf4\u542c\u4e00\u76f4\u5728\u542c\u8bf4\u8fc7\u5b83\uff0c\u4f46\u662f\u597d\u50cf\u7528\u5904\u4e0d\u662f\u5f88\u5927\uff0c\u8bf4\u5b9e\u8bdd\u6211\u4e2a\u4eba\u6ca1\u7528\u8fc7\uff0c\u4f60\u770b\u4ed6\u7684star\u4e5f\u4e0d\u9ad8\uff0c\u5e94\u8be5\u662f\u63a8\u5e7f\u529b\u5ea6\u4e0d\u8db3\uff0c\u6216\u8005\u8bf4\u53ea\u662f\u4e00\u79cd\u7684\u5c31\u6ca1\u6709\u592a\u591a\u843d\u3002\u7136\u540e\u5f53\u6211\u4eec\u770b\u5b8c\u8fd9\u4e2a\u4e4b\u540e\u91cd\u70b9\u60f3\u8bf4\u7684\u662f\u4ec0\u4e48\uff1f\u5c31\u662f\u6211\u4eec\u7684\u6839\u636e\u963f\u91cc\u7684\u8fd9\u6837\u4e00\u5957\u3001\u5e73\u53f0\u4ee5\u53ca\u8fd9\u4e9b\u4e2d\u95f4\u4ef6\u6765\u7ec4\u5efa\u4e86\u6211\u4eec\u4e00\u6574\u5957\u5fae\u670d\u52a1\u8fd9\u79cd\u751f\u6001\u67b6\u6784\u56fe\uff0c\u7136\u540e\u6211\u4eec\u81ea\u5df1\u7684\u6211\u4eec\u7684\u9879\u76ee\uff0c\u6bd4\u5982\u8bf413606\u7a0d\u5fae\u8bfe\uff0c\u6211\u4eec\u8fd9\u4e2a\u7cfb\u7edf\u90fd\u5728\u6cbf\u7528\u8fd9\u6837\u7684\u8bbe\u8ba1\uff0c\u7136\u540e\u7701\u9886\u5bfc\u5728\u8fd9\u91cc\u9762\u662f\u8d77\u5230\u81f3\u5173\u91cd\u8981\u7684\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u7b80\u5355\u8bf4\u4e00\u4e0b\uff0c\u5728\u4f60\u7cfb\u7edf\u6ca1\u6709\u95ee\u9898\uff0c\u6ca1\u6709\u9047\u5230\u6311\u6218\u7684\u65f6\u5019\uff0c\u4ed6\u9ed8\u9ed8\u65e0\u95fb\uff0c\u4f46\u662f\u4e00\u65e6\u9047\u5230\u95ee\u9898\uff0c\u4ed6\u5c31\u50cf\u4e00\u4e2a\u52c7\u58eb\u4e00\u6837\u54d0\u5bf9\u5427\uff1f\u628a\u654c\u4eba\u8981\u653b\u8fdb\u5927\u95e8\u7684\u4ec0\u4e48\u628a\u90a3\u4e2a\u6865\u7ed9\u780d\u65ad\u5bf9\u5427\uff1f\u8ba9\u654c\u4eba\u6765\u4e0d\u4e86\u5f53\u7136\u4e5f\u51fa\u4e0d\u53bb\u5bf9\u4e0d\u5bf9\uff1f<\/p>\n\n\n\n<p>\u5f15\u5165 Sentinel\u5b9a\u4e49\u63a5\u53e3\u89c4\u5219\u5b9a\u4e49\u9700\u8981\u98ce\u63a7\u63a5\u53e3\u7684\u89c4\u5219\u3002<\/p>\n\n\n\n<p>1. \u5f15\u5165 Sentinel<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependency&gt;\n    &lt;groupId&gt;com.alibaba.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-alibaba-sentinel&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n\n&lt;dependency&gt;\n    &lt;groupId&gt;com.alibaba.csp&lt;\/groupId&gt;\n    &lt;artifactId&gt;sentinel-annotation-aspectj&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n\n\n\n<p id=\"FgrRr\">2. \u5b9a\u4e49\u63a5\u53e3\u89c4\u5219<\/p>\n\n\n\n<p id=\"u18219b93\">\u5b9a\u4e49\u9700\u8981\u98ce\u63a7\u63a5\u53e3\u7684\u89c4\u5219<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.project.config;\n\nimport com.alibaba.csp.sentinel.slots.block.RuleConstant;\nimport com.alibaba.csp.sentinel.slots.block.flow.FlowRule;\nimport com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;\nimport org.springframework.beans.factory.InitializingBean;\nimport org.springframework.stereotype.Component;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\/**\n * \u521d\u59cb\u5316\u9650\u6d41\u914d\u7f6e\n * \u516c\u4f17\u53f7\uff1a\u9a6c\u4e01\u73a9\u7f16\u7a0b\uff0c\u56de\u590d\uff1a\u52a0\u7fa4\uff0c\u6dfb\u52a0\u9a6c\u54e5\u5fae\u4fe1\uff08\u5907\u6ce8\uff1alink\uff09\u83b7\u53d6\u9879\u76ee\u8d44\u6599\n *\/\n@Component\npublic class SentinelRuleConfig implements InitializingBean {\n\n    @Override\n    public void afterPropertiesSet() throws Exception {\n        List&lt;FlowRule&gt; rules = new ArrayList&lt;&gt;();\n        FlowRule createOrderRule = new FlowRule();\n        createOrderRule.setResource(\"create_short-link\");\n        createOrderRule.setGrade(RuleConstant.FLOW_GRADE_QPS);\n        createOrderRule.setCount(1);\n        rules.add(createOrderRule);\n        FlowRuleManager.loadRules(rules);\n    }\n}<\/code><\/pre>\n\n\n\n<p>\u5982\u679c\u89e6\u53d1\u98ce\u63a7\uff0c\u8bbe\u7f6e\u964d\u7ea7\u7b56\u7565\u3002<\/p>\n\n\n\n<p>\u901a\u8fc7Spring Boot\u81ea\u52a8\u88c5\u914d\u673a\u5236\u52a0\u8f7dSentinel\u7ec4\u4ef6\uff1b\u5728Spring\u542f\u52a8\u5b8c\u6210\u540e\uff08<code>InitializingBean<\/code>\uff09\u52a0\u8f7d\u6d41\u63a7\u89c4\u5219\uff1a<\/p>\n\n\n\n<p><code>@SentinelResource<\/code>\u6807\u6ce8\u9700\u8981\u4fdd\u62a4\u7684\u8d44\u6e90\uff1b<code>value<\/code>\u5bf9\u5e94\u89c4\u5219\u5b9a\u4e49\u7684resource\u540d\u79f0\uff1b<code>blockHandler<\/code>\u6307\u5b9a\u964d\u7ea7\u65b9\u6cd5<\/p>\n\n\n\n<p>\u5f53QPS\u8d85\u8fc7\u8bbe\u5b9a\u503c\uff08\u59821\u6b21\/\u79d2\uff09Sentinel\u81ea\u52a8\u89e6\u53d1\u964d\u7ea7\uff0c\u8c03\u7528<code>CustomBlockHandler<\/code>\u65b9\u6cd5\uff1b\u8fd4\u56de\u53cb\u597d\u63d0\u793a\u800c\u975e\u76f4\u63a5\u62a5\u9519<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.project.handler;\n\nimport com.alibaba.csp.sentinel.slots.block.BlockException;\nimport com.nageoffer.shortlink.project.common.convention.result.Result;\nimport com.nageoffer.shortlink.project.dto.req.ShortLinkCreateReqDTO;\nimport com.nageoffer.shortlink.project.dto.resp.ShortLinkCreateRespDTO;\n\n\/**\n * \u81ea\u5b9a\u4e49\u6d41\u63a7\u7b56\u7565\n * \u516c\u4f17\u53f7\uff1a\u9a6c\u4e01\u73a9\u7f16\u7a0b\uff0c\u56de\u590d\uff1a\u52a0\u7fa4\uff0c\u6dfb\u52a0\u9a6c\u54e5\u5fae\u4fe1\uff08\u5907\u6ce8\uff1alink\uff09\u83b7\u53d6\u9879\u76ee\u8d44\u6599\n *\/\npublic class CustomBlockHandler {\n\n    public static Result&lt;ShortLinkCreateRespDTO&gt; createShortLinkBlockHandlerMethod(ShortLinkCreateReqDTO requestParam, BlockException exception) {\n        return new Result&lt;ShortLinkCreateRespDTO&gt;().setCode(\"B100000\").setMessage(\"\u5f53\u524d\u8bbf\u95ee\u7f51\u7ad9\u4eba\u6570\u8fc7\u591a\uff0c\u8bf7\u7a0d\u540e\u518d\u8bd5...\");\n    }\n}<\/code><\/pre>\n\n\n\n<p>&nbsp;\u5728\u4ee3\u7801\u4e2d\u5f15\u5165 Sentinel \u6ce8\u89e3\u63a7\u5236\u6d41\u63a7\u89c4\u5219\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * \u521b\u5efa\u77ed\u94fe\u63a5\n *\/\n@PostMapping(\"\/api\/short-link\/v1\/create\")\n@SentinelResource(\n        value = \"create_short-link\",\n        blockHandler = \"createShortLinkBlockHandlerMethod\",\n        blockHandlerClass = CustomBlockHandler.class\n)\npublic Result&lt;ShortLinkCreateRespDTO> createShortLink(@RequestBody ShortLinkCreateReqDTO requestParam) {\n    return Results.success(shortLinkService.createShortLink(requestParam));\n}<img loading=\"lazy\" decoding=\"async\" height=\"15\" width=\"15\" src=\"blob:https:\/\/eve2333.top\/88c77aee-9157-408c-9e0e-fa5117425c7c\"><\/code><\/pre>\n\n\n\n<p>\u63a5\u4e0b\u6765\u538b\u6d4b\uff0c\u7528jmx\u6587\u4ef6\u538b\u6d4b\uff0c\u7531\u4e8e\u6587\u4ef6\u592a\u957f\u4e86\uff085KB\uff0c\u5c31\u4e0d\u5199\u51fa\u6765\uff1b\u8bb0\u5f97\u5728HTTP\u8bf7\u6c42\u91cc\u9762\u628agid\u6362\u6389\uff1b<\/p>\n\n\n\n<p>\u00a0\"code\":\"B000001\",\"message\":\"\u7cfb\u7edf\u6267\u884c\u51fa\u9519\",\"data\":null,\"requestId\":null,\"success\":false<img loading=\"lazy\" decoding=\"async\" height=\"296\" width=\"1238\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/7a62f89854b040da923bded4b5e82809.png\" alt=\"\"><\/p>\n\n\n\n<p>&nbsp;\u4e5f\u6709\u90a3\u4e48\u4e24\u4e2a\u6210\u529f\u7684nurl.ink:8001\/ks1aD \uff1bnurl.ink:8001\/ElDFO\uff1b\u7136\u540e\u5c31\u7206\u4e86<\/p>\n\n\n\n<p>&nbsp;\u6211\u770b\u5230idea\u91cc\u9762\u662f100\u8bf7\u6c42\u4e00\u5171\u516d\u4e2a\u6210\u529f\u7684\uff0c\u524d\u4e94\u4e2a\u90fd\u662fnurl.ink:8001\/ks1aD\uff1b\u7b2c\u516d\u662fElDFO\uff0c\uff1b\u4e3a\u4ec0\u4e48\u5462\uff1f<\/p>\n\n\n\n<p id=\"Pop0i\">3. \u5fae\u670d\u52a1\u7248\u672c Sentinel \u5982\u4f55\u63a5\u5165\uff1f<\/p>\n\n\n\n<p id=\"uafea7dc9\">Sentinel \u63a7\u5236\u53f0\u8bf4\u660e\u3002<a href=\"https:\/\/sentinelguard.io\/zh-cn\/docs\/dashboard.html\" target=\"_blank\"  rel=\"nofollow\" >dashboard | Sentinel<\/a><\/p>\n\n\n\n<p id=\"u8eece9e7\">\u542f\u52a8 Sentinel \u63a7\u5236\u53f0\uff0c\u5220\u9664 Sentinel \u5b9a\u4e49\u7684\u76f8\u5173\u89c4\u5219\u4ee3\u7801\uff0c\u52a0\u5165\u4ee5\u4e0b\u914d\u7f6e\u5373\u53ef\u3002<\/p>\n\n\n\n<p id=\"u127b60a4\">\u5220\u9664\u7684\u89c4\u5219\u914d\u7f6e\uff0c\u5728 Sentinel \u4e2d\u8fdb\u884c\u914d\u7f6e\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spring:\n    sentinel:\n      transport:\n        dashboard: localhost:8686\n        port: 8719<\/code><\/pre>\n\n\n\n<p>4. \u538b\u6d4b\u811a\u672c&nbsp;<\/p>\n\n\n\n<p><strong>\u201cother\u201d \u4f5c\u4e3a\u515c\u5e95\u7684\u7528\u6237\u540d\u53bb\u8fdb\u884c\u8bbf\u95ee\u7edf\u8ba1\uff0c\u662f\u4e0d\u662f\u4f1a\u5bf9\u539f\u672c\u7528\u6237\u540d\u53eb\u201cother\u201d\u7684\u7528\u6237\u9020\u6210\u5f71\u54cd\u5462\uff1f\u8fd9\u4e2a\u662f\u6211\u4e34\u65f6\u8d77\u7684\uff0c\u6211\u4eec\u53ef\u4ee5\u5728\u7528\u6237\u540d\u521b\u5efa\u7684\u65f6\u5019\uff0c\u9ed8\u8ba4\u521d\u59cb\u5316\u4e00\u4e2a other \u7cfb\u7edf\u7528\u6237\uff0c\u6216\u8005\u5c31\u4e0d\u5141\u8bb8\u521b\u5efa other \u5c31\u597d<\/strong><\/p>\n\n\n\n<p><strong>\u6570\u636e\u5e93\u8bb0\u5f97 \u52a0\u4e8b\u52a1<\/strong><\/p>\n\n\n\n<p>&nbsp;\u770b\u5230\u8fc7\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u5c31\u662f\u5c06\u7528\u6237\u8bbf\u95ee\u6b21\u6570\u7528 redis int64\u7684\u6700\u5927\u503c\u51cf\u53bb\u7528\u6237\u53ef\u4ee5\u4f7f\u7528\u7684\u6b21\u6570\u3002\u63a5\u7740\u7528\u6237\u6bcf\u6b21\u8bbf\u95ee\u8fdb\u884c\u81ea\u589e\uff0c\u5f53\u8d85\u8fc7\u8bbf\u95ee\u6b21\u6570\uff0credis\u4e2d\u5b58\u50a8\u7684value\u4e5f\u4f1a\u53d1\u751f\u6570\u503c\u6ea2\u51fa\uff0c\u629b\u9519\u3002\u63a5\u7740\u6355\u83b7\u9519\u8bef\uff0c\u629b\u51fa\u201c\u8bbf\u95ee\u8fc7\u5feb\uff0c\u7cfb\u7edf\u7e41\u5fd9\u201d\u7684\u9519\u8bef\u5c31\u53ef\u4ee5\u4e86<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c12\u8282\uff1a\u6d88\u606f\u961f\u5217\u91cd\u6784\u77ed\u94fe\u63a5\u76d1\u63a7\u529f\u80fd<\/h2>\n\n\n\n<p><strong>\u6211\u4eec\u4e4b\u524d\u4f7f\u7528\u8bfb\u5199\u9501\uff0c\u662f\u4e3a\u4e86\u9632\u6b62\u5728\u6539\u53d8\u77ed\u94fe\u63a5\u5206\u7ec4\u7684\u65f6\u5019\u7528\u6237\u8bbf\u95ee\u77ed\u94fe\u63a5\u3002\u5982\u679c\u77ed\u94fe\u63a5\u6b63\u5728\u4fee\u6539\u5206\u7ec4\uff0c\u8fd9\u65f6\u6709\u7528\u6237\u6b63\u5728\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u7edf\u8ba1\u76d1\u63a7\u76f8\u5173\u7684\u5206\u7ec4\u8fd8\u662f\u4e4b\u524d\u7684\u6570\u636e\uff0c\u5c31\u6d89\u53ca\u5230\u65e0\u6cd5\u6b63\u786e\u7edf\u8ba1\u76d1\u63a7\u6570\u636e\u95ee\u9898\uff0c\u6bd4\u5982\u5728\u7edf\u8ba1\u76d1\u63a7\u4ee3\u7801\u6267\u884c\u4e4b\u524d\uff0c\u53e6\u4e00\u4e2a\u7528\u6237\u5df2\u7ecf\u4fee\u6539\u4e86gid\uff0c\u6b64\u65f6\u7edf\u8ba1\u6570\u636e\u5982\u679c\u62ff\u7740\u4e4b\u524d\u7684gid\u6765\u67e5\u8be2\u7684\u8bdd\uff0c\u5c31\u67e5\u4e0d\u5230\uff0c\u90a3\u5c31\u6ca1\u529e\u6cd5\u7edf\u8ba1\u6700\u65b0\u7684\u8bb0\u5f55\u4e86\u3002 \u6211\u4eec\u4e4b\u524d\u5f15\u5165\u5ef6\u8fdf\u961f\u5217\u7684\u539f\u56e0\u662f\u56e0\u4e3a\uff0c\u5982\u679c\u7528\u6237\u6b63\u5728\u4fee\u6539\u77ed\u94fe\u63a5\uff0c\u90a3\u5176\u4ed6\u7528\u6237\u6267\u884c\u8bbf\u95ee\u77ed\u94fe\u63a5restoreUrl\u7684\u65f6\u5019\u4f1a\u8c03\u7528shortLinkStats\u83b7\u53d6\u8bfb\u9501\uff0c\u5176\u4ed6\u7528\u6237\u4e0d\u80fd\u8bbf\u95ee\u80af\u5b9a\u662f\u4e0d\u5408\u7406\u7684\uff0c\u5982\u679c\u6211\u4eec\u5728shortLinkStats\u4e2d\u83b7\u53d6\u9501\u7684\u65f6\u5019\u662f\u6b7b\u7b49\u76f4\u5230\u83b7\u53d6\u8bfb\u9501\uff0c\u90a3\u5982\u679c\u5f88\u591a\u7684\u7528\u6237\u6765\u8bbf\u95ee\u5c31\u4f1a\u5f00\u542f\u5f88\u591a\u7684\u7ebf\u7a0b\uff0c\u5982\u679c\u8fd9\u4e9b\u7528\u6237\u90fd\u5728\u6b7b\u7b49\uff0c\u90a3\u4e48\u6211\u4eec\u7684\u5e94\u7528\u5c31\u65e0\u6cd5\u518d\u63a5\u6536\u65b0\u7684\u8bf7\u6c42\u3002\u90a3\u5982\u679c\u83b7\u53d6\u4e0d\u5230\u8bfb\u9501\u5c31\u8fd4\u56de\u5c31\u4e0d\u5904\u7406\u4e86\uff0c\u90a3\u5c31\u6ca1\u529e\u6cd5\u7edf\u8ba1\u4e86\uff0c\u6b64\u65f6\u5c31\u5f15\u5165\u5ef6\u8fdf\u961f\u5217\u3002 \u800c\u73b0\u5728\u4ee3\u7801\u6539\u9020\u4e4b\u540e\uff0c\u5f53\u7528\u6237\u8bbf\u95ee\u77ed\u94fe\u63a5\u7684\u8bdd\uff0c\u6267\u884c\u7684\u662f\u6539\u9020\u4e4b\u540e\u7684ShortLinkServiceImpl\u4e2d\u7684shortLinkStats\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u662f\u5f80RedisStream\u4e2d\u53d1\u9001\u6d88\u606f\u7684\u3002\u800c\u6b64\u65f6\u6d88\u8d39\u8005\u6d88\u8d39\u7684\u65f6\u5019\uff0c\u662f\u5148\u83b7\u53d6\u5230\u6d88\u606f\uff0c\u7136\u540e\u6267\u884cactualSaveShortLinkStats\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u8fd8\u662f\u5148\u83b7\u53d6\u8bfb\u5199\u9501\u3002\u5982\u679c\u6b64\u65f6\u6709\u7528\u6237\u6b63\u5728\u4fee\u6539\u77ed\u94fe\u63a5\uff0c\u90a3\u4e48\u6d88\u606f\u5c31\u4f1a\u88ab\u53d1\u9001\u5230\u5ef6\u8fdf\u961f\u5217\uff0c\u800c\u5ef6\u8fdf\u961f\u5217\u4e2d\u7684\u6d88\u606f\u4f1a\u901a\u8fc7\u6267\u884cShortLinkServiceImpl\u4e2d\u7684shortLinkStats\u65b9\u6cd5\u628a\u6d88\u606f\u53d1\u9001\u5230RedisStream\u4e2d\uff0c\u8fdb\u800c\u88ab\u5f02\u6b65\u4fee\u6539\u3002\u5982\u679c\u6b64\u65f6\u6ca1\u6709\u7528\u6237\u5728\u4fee\u6539\u77ed\u94fe\u63a5\uff0c\u90a3\u4e48\u8bbf\u95ee\u77ed\u94fe\u63a5\u90fd\u662f\u83b7\u53d6\u8bfb\u9501\uff0c\u4e5f\u5c31\u6ca1\u6709\u8bfb\u5199\u9501\u7ade\u4e89\uff0c\u56e0\u6b64\u6d88\u606f\u90fd\u4f1a\u88ab\u76f4\u63a5\u53d1\u9001\u5230RedisStream\u4e2d\uff0c\u8fdb\u800c\u88ab\u5f02\u6b65\u4fee\u6539\u3002\u56e0\u6b64\uff0c\u6700\u7ec8\u6d88\u606f\u90fd\u4f1a\u88ab\u6210\u529f\u6d88\u8d39\uff0c\u540e\u7eed\u518d\u6765\u5904\u7406\u5e42\u7b49\u6027\u95ee\u9898\u3002<\/strong>&nbsp;<\/p>\n\n\n\n<p>\u00a0\u6211\u4eec\u4e4b\u524d\u7684\u77ed\u94fe\u63a5\u76d1\u63a7\u90a3\u91cc\u662f\u76f4\u63a5\u901a\u8fc7\u8bbf\u95ee\u6570\u636e\u5e93\u7684\u5f62\u5f0f\uff0c\u5728\u4ed6\u5c31\u662f\u5728\u7528\u6237\u53bb\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u6211\u4eec\u5c06\u8fd9\u4e2a\u77ed\u94fe\u63a5\u7684\u76d1\u63a7\u4fe1\u606f\u5b58\u50a8sql\u91cc\u9762\uff1b\u6211\u4eec\u770b\u4e00\u4e0b\u8fd9\u4e2a\u6d41\u7a0b<br>\u00a0<img loading=\"lazy\" decoding=\"async\" height=\"199\" width=\"666\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/d2ee5f5462ee4ccb929d77d59632e1c4.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"u89b38266\">\u6d77\u91cf\u8bbf\u95ee\u77ed\u94fe\u63a5\uff0c\u76f4\u63a5\u8bbf\u95ee\u6570\u636e\u5e93\uff0c\u4f1a\u5bfc\u81f4\u6570\u636e\u5e93\u8d1f\u8f7d\u53d8\u9ad8\uff0c\u751a\u81f3\u6570\u636e\u5e93\u5b95\u673a\u3002\u4e3a\u6b64\uff0c\u9700\u8981\u5f15\u5165\u6d88\u606f\u961f\u5217\u524a\u5cf0\u3002<\/p>\n\n\n\n<p>\u6709\u4e00\u4e9b\u95ee\u9898\uff0c\u5b83\u6709\u4e00\u4e9b\u6bd4\u5982\u8bf4\u6211\u4eec\u5728\u77ed\u94fe\u63a5\u8bbf\u95ee\u8fc7\u7a0b\u5f53\u4e2d\uff0c\u7531\u4e8e\u7528\u6237\u7684\u8bf7\u6c42\u91cf\u8f83\u5927\uff0c\u7136\u540e\u5bfc\u81f4\u6d41\u91cf\u7684\u66b4\u589e\uff0c\u8fd9\u4e2a\u65f6\u5019\u77ed\u94fe\u63a5\u4e2d\u53f0\u8fd9\u8fb9\u8bbf\u95ee\uff0c\u77ed\u94fe\u63a5\u8bf7\u6c42\u7684\u8f6c\u8fd9\u79cd\u5927\u91cf\u7684\u8bbf\u95ee\u6d41\u91cf\u7684\u65f6\u5019\u5bf9\u5427\uff1fmysql\u53ef\u80fd\u4ed6\u65e0\u6cd5\u627f\u53d7\u8fd9\u79cd\u6d77\u91cf\u7684\u8c03\u7528\u91cf\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u5b83\u5c31\u4f1a\u5bfc\u81f4\u6700\u574f\u7684\u60c5\u51b5\u4f1a\u5bfc\u81f4mysql\u5d29\u6e83\u5bf9\u5427\uff1f\u6211\u4eec\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u8981\u5728mysql\u548c\u5e94\u7528\u4e2d\u95f4\u52a0\u4e00\u4e2a\u6d88\u606f\u961f\u5217\uff0c\u6d88\u606f\u961f\u5217\u6211\u76f8\u4fe1\u5927\u5bb6\u90fd\u5df2\u7ecf\u6bd4\u8f83\u719f\u6089\u4e86\uff0c\u5bf9\u5427\uff1f\u6bd4\u5982\u8bf4\u4e00\u4e9b\u5e38\u89c1\u7684\u573a\u666f\u5f02\u6b65\u5bf9\u5427\uff1f\u89e3\u8026\u4ee5\u53ca\u524a\u5cf0\u5bf9\u4e0d\u5bf9\uff1f\u57fa\u4e8e\u8fd9\u4e9b\u7684\u8bdd\uff0c\u6211\u4eec\u8fd9\u91cc\u5c31\u4e0d\u518d\u8fc7\u591a\u7684\u8d58\u8ff0\uff0c\u7136\u540e\u6211\u7ed9\u5927\u5bb6\u5982\u679c\u60f3\u4e86\u89e3\u6d88\u606f\u961f\u5217\uff0c\u4f7f\u7528\u6211\u4eec\u8fd9\u4e2a\u7f51\u7ad9\u91cc\u9762<\/p>\n\n\n\n<p id=\"u76d16f30\">\u6d88\u606f\u961f\u5217\u4f7f\u7528\u573a\u666f\uff1a<a href=\"https:\/\/nageoffer.com\/docs\/rocketmq\/\" target=\"_blank\"  rel=\"nofollow\" >\u4ece\u96f6\u5230\u4e00\u5b66\u4e60\u4e2d\u95f4\u4ef6\u4e4bRocketMQ | \u62ff\u4e2aoffer-\u5f00\u6e90&amp;\u9879\u76ee\u5b9e\u6218<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ydH1w\">1. \u4e3a\u4ec0\u4e48\u4f7f\u7528 Redis \u5145\u5f53\u6d88\u606f\u961f\u5217\uff1f<\/h3>\n\n\n\n<p id=\"u1f2784a5\">\u8f7b\u91cf\u7ea7<\/p>\n\n\n\n<p>\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u4e4b\u524d\u8981\u8ddf\u5927\u5bb6\u8bf4\u7684\u662f\u6211\u4eec\u77ed\u94fe\u63a5\u4e3b\u6253\u7684\u5c31\u662f\u8f7b\u91cf\u7ea7\u5bf9\u4e0d\u5bf9\uff1f\u6211\u4e0d\u5e0c\u671b\u5c31\u662f\u5728\u90e8\u7f72\u5927\u5bb6\u5728\u90e8\u7f72\u77ed\u4fe1\u7684\u8fc7\u7a0b\u5f53\u4e2d\u5bf9\u5427\uff1f\u7531\u4e8e\u8981\u90e8\u7f72rabbitmq\uff0crocketmq\u7b49\u4e00\u7cfb\u5217\u7684\u8fd9\u79cd\u5c31\u662f\u5360\u7528\u8d44\u6e90\u8f83\u5927\u7684\u7ec4\u4ef6\u7684\u65f6\u5019\u9020\u6210\u4e00\u4e9b\u90e8\u7f72\u95ee\u9898\uff0c\u672c\u7740\u80fd\u4e0d\u591a\u5f15\u7528\u7ec4\u4ef6\u5c31\u4e0d\u591a\u5f15\u7528\u7ec4\u4ef6\u7684\u539f\u5219\u6211\u4eec\u76f4\u63a5\u4f7f\u7528\u6765\u610f\u601d ready\u65af\uff0c\u5f53\u6d88\u606f\u961f\u5217\u5728\u7f51\u4e0a\u7684\u4e00\u4e9b\u516b\u80a1\u6587\u6bd4\u8f83\u591a\uff0c\u5bf9\u5427\uff1f\u76f8\u4fe1\u5927\u5bb6\u5728\u7f51\u4e0a\u6216\u591a\u6216\u5c11\u4e5f\u90fd\u80fd\u770b\u5230\u4e00\u4e9b\u6709\u4e09\u79cd\u65b9\u5f0f\u5728\u539f\u5730\u5c42\u9762\u5b9e\u73b0\u6d88\u606f\u961f\u5217<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"t4wAq\">2. Redis \u5b9e\u73b0\u6d88\u606f\u961f\u5217\u7684\u51e0\u79cd\u65b9\u5f0f\uff1f<\/h3>\n\n\n\n<p id=\"ua8e9a530\">List<\/p>\n\n\n\n<p id=\"u1822784d\">PubSub<\/p>\n\n\n\n<p id=\"ued276647\">Stream<\/p>\n\n\n\n<p id=\"uadfd5e72\">\u4f7f\u7528 Redis \u5145\u5f53\u6d88\u606f\u961f\u5217\u53c2\u8003\u6587\u7ae0\uff1a<a href=\"https:\/\/mp.weixin.qq.com\/s\/gCUT5TcCQRAxYkTJfTRjJw\" target=\"_blank\"  rel=\"nofollow\" >Redis\u6d88\u606f\u961f\u5217\u53d1\u5c55\u5386\u7a0b<\/a>&nbsp;<\/p>\n\n\n\n<p>\u60f3\u6709\u4e00\u4e2a\u6df1\u5165\u7684\u4e86\u89e3\uff0c\u8fd9\u91cc\u9762\u963f\u91cc\u5df4\u5df4\u8fd9\u8fb9\u5c31\u5199\u4e86\u7bc7\u6587\u7ae0\uff0c\u6211\u4e2a\u4eba\u89c9\u5f97\u5199\u7684\u8fd8\u86ee\u597d\u7684\uff0c\u5927\u5bb6\u53ef\u4ee5\u53bb\u770b\u4e00\u4e0b\u3002&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wGL4g\">3. \u4f7f\u7528 Redis \u6d88\u606f\u961f\u5217\u540e\u903b\u8f91<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"1000\" width=\"1758\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/82de0ea58e81843d87788ec4eb7f24d4.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"ubda58a54\">\u7136\u540e\u5728reids\u91cc\u9762\u6211\u4eec\u9996\u5148\u8981\u6267\u884c xadd\u7684\uff0c\u76f8\u5f53\u4e8e\u662f\u53bb\u521b\u5efa\u4e00\u4e2a\u5bf9\u5427\uff1f \u6211\u4eec\u7684\u53ef\u4ee5\u53eb\u4ec0\u4e48\u674e\u514b\u65af\u7279\uff0c\u7136\u540espring\u7136\u540e\u56e0\u4e3a\u5b83\u9ed8\u8ba4\u662f\u8981\u521b\u5efa\u4e00\u4e9bkey value \uff0c\u6240\u4ee5\u8bf4\u6210\u4e86\u4e00\u4e2anew key \u548cnew value\uff0c\u5e94\u8be5\u662f\u65e0\u610f\u4e49\u7684\uff0c\u7136\u540e\u8fd9\u4e2a\u623f\u5b50\u662f\u4e2a\u6d88\u606f\uff0c\u7136\u540e\u6211\u5c31\u6d88\u8d39\u8005\u7ec4\u3002 Ok\u73b0\u5728\u521b\u5efa\u5b8c\u4e86\u4e4b\u540e\uff0c\u6211\u4eec\u5f00\u59cb\u53bb\u4ee3\u7801\u91cc\u9762\u53bb\u521b\u5efa\u5bf9\u5e94\u7684\u4e00\u7cfb\u5217\u7684\u6d41\u7a0b<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sBJKQ\">\u521b\u5efa Redis Stream Key \u76f8\u5173\u914d\u7f6e<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"xyi2H\">1. \u521b\u5efa Stream Key<\/h3>\n\n\n\n<pre id=\"yuPow\" class=\"wp-block-code\"><code>XADD \"short_link:stats-stream\" * \"New key\" \"New value\"<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"hHWJ2\">2. \u521b\u5efa\u6d88\u8d39\u8005\u7ec4<\/h3>\n\n\n\n<pre id=\"uy4yY\" class=\"wp-block-code\"><code>xgroup create short_link:stats-stream short_link:stats-stream:only-group 0<\/code><\/pre>\n\n\n\n<p>\u9996\u5148\u6211\u4eec\u80af\u5b9a\u662f\u8981\u521b\u5efa\u51fa\u6765\u5bf9\u5e94\u7684redis stream\u8fd9\u4e48\u4e00\u4e2aconfig\u7c7b\uff0c\u7136\u540e\u8fd9\u91cc\u9762\u6709\u4e24\u4e2a\u914d\u7f6e\uff0c\u9996\u5148\u7b2c\u4e00\u4e2a\u5c31\u662fredis\u5f00\u59cb\u4e09\u4e2a\u6708\u76f8\u5f53\u4e8e\u610f\u601d\u8fde\u63a5\u5de5\u5382\uff0c\u7136\u540e\u76f4\u63a5\u70b9\u5c31\u884c\u4e86\uff0c\u7136\u540e\u8fd9\u4e2a\u7684\u8bdd\u662f\u6211\u4eec\u7684\u539f\u5219\uff0c\u6d88\u8d39\u8005\u9700\u8981\u53bb\u7ed1\u5b9a\uff0cok\u5148\u628a\u5b83\u5f15\u8fdb\u6765\uff0c\u7136\u540e\u6211\u4eec\u5728\u521a\u624d\u4e0d\u662f\u521b\u5efa\u4e86\u4e00\u4e2atopic\u4e86\uff0c\u5176\u5b9e\u5c31\u662f\u4f7f\u7528\u7684K\uff0c\u6211\u4eec\u53ef\u4ee5\u7406\u89e3\u5b83\u662f\u4e00\u4e2atopic\u7ed9\u5b83\u5f15\u8fdb\u6765\uff0c\u7136\u540e\u8fd8\u6709\u8fd9\u4e24\u4e2a\u5199\u5728\u54ea\u91cc\uff0c\u6211\u7ed9\u5927\u5bb6\u770b\u4e00\u4e0b\uff0c\u5728\u6211\u4eec\u7684application.yaml\u914d\u7f6e\u6587\u4ef6\u91cc\u9762\uff0c\u76f8\u5f53\u4e8e\u6211\u5728\u7c7b\u4f3c\u7684\u76ee\u5f55\u4e0b\u9762\u53c8\u52a0\u4e86\u4e00\u4e2achannel-topic\uff0c\u7136\u540e\u8fd9\u4e2a\u662f\u5b83\u7684topic\uff0c\u8fd9\u4e2a\u662f\u5b83\u7684\u4e00\u4e2agroup\uff0c\u73b0\u5728\u6211\u4eec\u5728\u8fd9\u91cc\u5199\u597d\u4e86\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">data:\n  redis:\n    host: 192.168.111.130\n    password: 123321\n    port: 6379\n    channel-topic:\n      short-link-stats: 'short_link:stats-stream'\n      short-link-stats-group: 'short_link:stats-stream:only-group'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.config;\n\nimport com.nageoffer.shortlink.project.mq.consumer.ShortLinkStatsSaveConsumer;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.redis.connection.RedisConnectionFactory;\nimport org.springframework.data.redis.connection.stream.Consumer;\nimport org.springframework.data.redis.connection.stream.MapRecord;\nimport org.springframework.data.redis.connection.stream.ReadOffset;\nimport org.springframework.data.redis.connection.stream.StreamOffset;\nimport org.springframework.data.redis.stream.StreamMessageListenerContainer;\n\nimport java.time.Duration;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\n\n\/**\n * Redis Stream \u6d88\u606f\u961f\u5217\u914d\u7f6e\n *\/\n@Configuration\n@RequiredArgsConstructor\npublic class RedisStreamConfiguration {\n\n    private final RedisConnectionFactory redisConnectionFactory;\n    private final ShortLinkStatsSaveConsumer shortLinkStatsSaveConsumer;\n\n    @Value(\"${spring.data.redis.channel-topic.short-link-stats}\")\n    private String topic;\n    @Value(\"${spring.data.redis.channel-topic.short-link-stats-group}\")\n    private String group;\n\n    @Bean\n    public ExecutorService asyncStreamConsumer() {\n        AtomicInteger index = new AtomicInteger();\n        int processors = Runtime.getRuntime().availableProcessors();\n        return new ThreadPoolExecutor(processors,\n                processors + processors &gt;&gt; 1,\n                60,\n                TimeUnit.SECONDS,\n                new LinkedBlockingQueue&lt;&gt;(),\n                runnable -&gt; {\n                    Thread thread = new Thread(runnable);\n                    thread.setName(\"stream_consumer_short-link_stats_\" + index.incrementAndGet());\n                    thread.setDaemon(true);\n                    return thread;\n                }\n        );\n    }\n\n    @Bean(initMethod = \"start\", destroyMethod = \"stop\")\n    public StreamMessageListenerContainer&lt;String, MapRecord&lt;String, String, String&gt;&gt; streamMessageListenerContainer(ExecutorService asyncStreamConsumer) {\n        StreamMessageListenerContainer.StreamMessageListenerContainerOptions&lt;String, MapRecord&lt;String, String, String&gt;&gt; options =\n                StreamMessageListenerContainer.StreamMessageListenerContainerOptions\n                        .builder()\n                        \/\/ \u4e00\u6b21\u6700\u591a\u83b7\u53d6\u591a\u5c11\u6761\u6d88\u606f\n                        .batchSize(10)\n                        \/\/ \u6267\u884c\u4ece Stream \u62c9\u53d6\u5230\u6d88\u606f\u7684\u4efb\u52a1\u6d41\u7a0b\n                        .executor(asyncStreamConsumer)\n                        \/\/ \u5982\u679c\u6ca1\u6709\u62c9\u53d6\u5230\u6d88\u606f\uff0c\u9700\u8981\u963b\u585e\u7684\u65f6\u95f4\u3002\u4e0d\u80fd\u5927\u4e8e ${spring.data.redis.timeout}\uff0c\u5426\u5219\u4f1a\u8d85\u65f6\n                        .pollTimeout(Duration.ofSeconds(3))\n                        .build();\n        StreamMessageListenerContainer&lt;String, MapRecord&lt;String, String, String&gt;&gt; streamMessageListenerContainer =\n                StreamMessageListenerContainer.create(redisConnectionFactory, options);\n        streamMessageListenerContainer.receiveAutoAck(Consumer.from(group, \"stats-consumer\"),\n                StreamOffset.create(topic, ReadOffset.lastConsumed()), shortLinkStatsSaveConsumer);\n        return streamMessageListenerContainer;\n    }\n}\n<\/pre>\n\n\n\n<p>\u7136\u540e\u8fd9\u8fb9\u521b\u5efa\u4e86\u7ebf\u7a0b\u6c60\uff0c\u8fd9\u4e2a\u7ebf\u7a0b\u6c60\u662f\u7528\u6765\u505a\u4ec0\u4e48\u7684\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u6d88\u606f\u7684\u6d88\u8d39\u8005\u4e5f\u662f\u901a\u8fc7\u4e00\u4e2a\u7ebf\u7a0b\u6c60\u53bb\u6267\u884c\u7684\uff0c\u5982\u679c\u8bf4\u4f60\u4e0d\u5728\u8fd9\u91cc\u6307\u5b9a\u5b83\u5c31\u4f1a\u7528\u9ed8\u8ba4\u7684\u4e0e\u5176\u9ed8\u8ba4\u7684\u5bf9\u5427\uff1f\u4e0d\u5982\u7531\u6211\u4eec\u81ea\u5df1\u6765\u7ba1\u63a7\u5bf9\u5427\uff1f\u51fa\u73b0\u95ee\u9898\u4ec0\u4e48\u7684\u8fd8\u597d\u5206\u6790\u4e00\u70b9\uff0c\u6211\u4eec\u8fd9\u91cc\u9762\u6b63\u5e38\u7684\u5c31\u662f\u8fd9\u4e2a\u662f\u6307\u7684\u662f\u83b7\u53d6\u5f53\u524d\u673a\u5668\u7684CPU\u548c\u6570\uff0c\u7136\u540e\u6700\u5927\u7ebf\u7a0b\u7684\u8bdd\u6211\u4eec\u7528\u4e86\u4e00\u4e2a\u4f4d\u79fb\u76f8\u5f53\u4e8e\u6bd4\u5982\u73b0\u5728\u662f\u5411\u53f3\u79fb\u4f4d\uff0c\u76f8\u5f53\u4e8e\u662f\u9664\u4ee52\u5bf9\u5427\uff1f \u7136\u540e\u6211\u4eec\u5047\u5982\u8bf4\u6211\u4eec\u662f\u4e00\u4e2a\u56db\u6838\u7684\u673a\u5668\uff0c\u76f8\u5f53\u4e8e4+2=6\u6700\u5927\u7ebf\u7a0b\u6570\uff0c\u7136\u540e\u4e0b\u9762\u53c2\u6570\u5c31\u4e0d\u4e00\u4e00\u89e3\u6790\u4e86\uff0c\u5c31\u662f:\u8f83\u5e38\u89c1\u3002<\/p>\n\n\n\n<p>\u7136\u540e\u8fd9\u8fb9\u662f\u4e00\u4e2a\u6bd4\u8f83\u91cd\u8981\u7684\u70b9\uff0c\u5b83\u7684\u76d1\u542c\u7684\u7ed1\u5b9a\u9996\u5148\u6211\u4eec\u521b\u5efa\u76d1\u542c\u7684\u65f6\u5019\u4e00\u5b9a\u8981\u5148\u7ed9\u4ed6\u6307\u5b9a\u4e00\u4e9b\u914d\u7f6e\uff0c\u9996\u9009\u7b2c\u4e00\u6211\u4eec\u4e00\u6b21\u6027\u91cc\u9762\u53bb\u83b7\u53d6\u6d88\u606f\u7684\u65f6\u5019\u8981\u4e00\u6b21\u62ff\u591a\u5c11\u6761\uff0c\u6211\u4eec\u8fd9\u91cc\u9762\u8bbe\u7684\u662f10\u5bf9\u5427\uff1f \u6279\u91cf1\u4e2a\u6d88\u606f\u5bf9\u5427\uff1f\u7136\u540e\u7b2c\u4e8c\u6211\u4eec\u8fd9\u91cc\u9762\u5c31\u662f\u6267\u884c\u8fd9\u4e2a\u6d88\u606f\u62c9\u5230\u6211\u4eec\u7684\u5185\u5b58\u4e4b\u540e\uff0c\u7531\u54ea\u4e2a\u6267\u884c\u8005\u53bb\u6267\u884c\u5982\u679c\u8bf4\uff0c\u6211\u4eec\u4e0d\u7ed1\u5b9a\u6211\u4eec\u7684\u5bf9\u5427\uff1f\u90a3\u4e48\u5b83\u5c31\u662f\u9ed8\u8ba4\u7684\uff0c\u4e3a\u6b64\u6211\u4eec\u80af\u5b9a\u662f\u672c\u7740\u7ed1\u5b9a\u7684\u539f\u5219\u5bf9\u5427\uff1f\u628a\u6240\u6709\u7684\u6d41\u7a0b\u63a7\u5236\u5728\u81ea\u5df1\u80fd\u591f\u628a\u63a7\u7684\u5730\u65b9\uff0c\u5bf9\u4e0d\u5bf9\uff1f \u7136\u540e\u7b2c\u4e09\u4e2a\u5c31\u662f\u5982\u679c\u8bf4\uff0c\u6211\u4eec\u4f7f\u7528\u91cc\u9762\u6ca1\u6709\u6d88\u606f\u4e86\uff0c\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u7684\u5ba2\u6237\u7aef\u4e0d\u80fd\u4e00\u76f4\u53bb\u627e\u4ed6\u53bb\u62ff\u53bb\u5bf9\u4e0d\u5bf9\uff1f\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u7ed9\u4ed6\u8ba9\u4ed6\u7c7b\u4f3csleep\u4e00\u6bb5\u65f6\u95f4\u3002\u662f\u4e0d\u80fd\u5927\u4e8e\u5b83\u4e0b\u9762\u5c31\u662fredis\u6709\u4e00\u4e2a\u5168\u5c40\u7684\u5f00\u653e\u7684\u65f6\u95f4\u7684\uff0c\u5426\u5219\u7684\u8bdd\u4f1a\u8d85\u65f6\u3002\u518d\u63a5\u4e0b\u6765\u7684\u8bdd\u5c31\u662f\u53bb\u7ed9\u5b83\u521b\u5efa\u5bf9\u5e94\u7684\u7ed1\u5b9a\u76d1\u542c\uff0c\u7136\u540e\u76f8\u5f53\u4e8e\u662f\u628a\u6211\u4eec\u7684\u901a\u8fc7\u8fde\u63a5\u5de5\u5382\u4ee5\u53ca\u6211\u4eec\u5bf9\u914d\u7f6e\u521b\u5efa\u51fa\u6765\uff0c\u7136\u540e\u901a\u8fc7\u914d\u7f6e\u53bb\u521b\u5efa\u5bf9\u5e94\u7684\u53bb\u7ed1\u5b9a\u5bf9\u5e94\u7684\u76d1\u542c\u5c31\u662f\u76d1\u542c\u8005\u3001\u4e5f\u662f\uff0c\u6211\u4eec\u6d88\u6d88\u8d39\u8005\uff0c\u4e5f\u5c31\u662f\u8fd9\u662f\u6211\u4eec\u81ea\u5df1\u5199\u7684\u8ba4\u53ef\u5bf9\u5427\uff1f \u5c31\u662f\u76d1\u63a7\u4fdd\u5b58\u5361\u6570\u7801\u6d88\u8d39\u8005\u3002Ok\u914d\u7f6e\u8fd9\u4e00\u5757\u7684\u8bdd\u5927\u6982\u5c31\u8fd9\u4e9b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>shortlinkIpml\u91cc\u9762\u8981\u4fee\u6539\u7684\u90a3\u4e2a\u7c7b\uff1a \n\n   @Override\n    public void shortLinkStats(String fullShortUrl, String gid, ShortLinkStatsRecordDTO statsRecord) {\n        Map&lt;String, String&gt; producerMap = new HashMap&lt;&gt;();\n        producerMap.put(\"fullShortUrl\", fullShortUrl);\n        producerMap.put(\"gid\", gid);\n        producerMap.put(\"statsRecord\", JSON.toJSONString(statsRecord));\n        shortLinkStatsSaveProducer.send(producerMap);\n    }<\/code><\/pre>\n\n\n\n<p>shortlinkimpl\u7684 \u73b0\u5728\u53d8\u6210\u76f8\u5f53\u4e8e\u5b83\u5c31\u662f\u628a\u4e4b\u524d\u7684\u90a3\u4e9b\u903b\u8f91\u5168\u90e8\u5c01\u88c5\u5230\u6211\u4eec\u7684\u54ea\u91cc\u53bb\u4e86\uff0c\u5c01\u88c5\u5230\u6211\u4eec\u7684\u6d88\u606f\u6d88\u8d39\u8005\u91cc\u9762\u53bb\u4e86\uff0c\u73b0\u5728\u53ea\u6709\u4e00\u4e2a\u53d1\u9001\u6d41\u7a0b\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.producer;\n\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Map;\n\n\/**\n * \u77ed\u94fe\u63a5\u76d1\u63a7\u72b6\u6001\u4fdd\u5b58\u6d88\u606f\u961f\u5217\u751f\u4ea7\u8005\n *\/\n@Component\n@RequiredArgsConstructor\npublic class ShortLinkStatsSaveProducer {\n\n    private final StringRedisTemplate stringRedisTemplate;\n\n    @Value(\"${spring.data.redis.channel-topic.short-link-stats}\")\n    private String topic;\n\n    \/**\n     * \u53d1\u9001\u5ef6\u8fdf\u6d88\u8d39\u77ed\u94fe\u63a5\u7edf\u8ba1\n     *\/\n    public void send(Map&lt;String, String&gt; producerMap) {\n        stringRedisTemplate.opsForStream().add(topic, producerMap);\n    }\n}<\/pre>\n\n\n\n<p>\u7136\u540e\u8fd9\u4e2a\u7c7b\u4e5f\u662f\u6211\u4eec\u65b0\u5efa\u7684\u53bb\u505a\u4e00\u4e2a\u65b0\u7684\u64cd\u4f5c\uff0c\u975e\u5e38\u7b80\u5355\uff0c\u6211\u4eec\u76f4\u63a5\u662fstream\uff0c\u7136\u540e\u6709\u4e00\u4e2aopsForStream\u76f4\u63a5add\u5c31\u53ef\u4ee5\u4e86\uff0c\u6211\u4eec\u5f80\u54ea\u4e2atopic\u91cc\u9762\u53bb\u53d1\uff0c\u7136\u540e\u7136\u540e\u6211\u4eec\u53d1\u4e86\u4e4b\u540e\u4ed6\u662f\u4e0d\u662f\u5c31\u5230\u54ea\u4e86\uff0c\u4ed6\u662f\u4e0d\u662f\u5c31\u5230\u6d88\u8d39\u8005\u80fd\u76d1\u542c\u5230\u7684\u5bf9\u4e0d\u5bf9\uff1fOk\u770b\u5230\u6ca1\u6709\uff1f\u628a\u8fd9\u5f88\u5927\u4e00\u5768\u7ed9\u4ed6\u5f15\u8fdb\u6765\u4e86\u3002\u7136\u540e\u6d88\u606f\u6d88\u8d39\u8005\u5927\u5bb6\u5982\u679c\u8bf4\u7528\u8fc7\uff0c\u4f60\u50cfrecketmq\u90a3\u79cd\u6bd4\u8f83\u719f\u6089\u7684\u8bdd\u5bf9\u5427\uff1f<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.consumer;\n\n\nimport cn.hutool.core.date.DateUtil;\nimport cn.hutool.core.date.Week;\nimport cn.hutool.core.util.StrUtil;\nimport cn.hutool.http.HttpUtil;\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONObject;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkAccessLogsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkAccessStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkBrowserStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkDeviceStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkLocaleStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkNetworkStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkOsStatsDO;\nimport com.nageoffer.shortlink.project.dao.entiry.LinkStatsTodayDO;\nimport com.nageoffer.shortlink.project.dao.entiry.ShortLinkGotoDO;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkAccessLogsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkAccessStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkBrowserStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkDeviceStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkLocaleStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkNetworkStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkOsStatsMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.LinkStatsTodayMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.ShortLinkGotoMapper;\nimport com.nageoffer.shortlink.project.dao.mapper.ShortLinkMapper;\nimport com.nageoffer.shortlink.project.dto.biz.ShortLinkStatsRecordDTO;\nimport com.nageoffer.shortlink.project.mq.producer.DelayShortLinkStatsProducer;\nimport lombok.RequiredArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\nimport org.redisson.api.RLock;\nimport org.redisson.api.RReadWriteLock;\nimport org.redisson.api.RedissonClient;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.data.redis.connection.stream.MapRecord;\nimport org.springframework.data.redis.connection.stream.RecordId;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.data.redis.stream.StreamListener;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.Optional;\n\nimport static com.nageoffer.shortlink.project.common.constant.RedisKeyConstant.LOCK_GID_UPDATE_KEY;\nimport static com.nageoffer.shortlink.project.common.constant.ShortLinkConstant.AMAP_REMOTE_URL;\n\n\/**\n * \u77ed\u94fe\u63a5\u76d1\u63a7\u72b6\u6001\u4fdd\u5b58\u6d88\u606f\u961f\u5217\u6d88\u8d39\u8005\n *\/\n@Slf4j\n@Component\n@RequiredArgsConstructor\npublic class ShortLinkStatsSaveConsumer implements StreamListener&lt;String, MapRecord&lt;String, String, String&gt;&gt; {\n\n    private final ShortLinkMapper shortLinkMapper;\n    private final ShortLinkGotoMapper shortLinkGotoMapper;\n    private final RedissonClient redissonClient;\n    private final LinkAccessStatsMapper linkAccessStatsMapper;\n    private final LinkLocaleStatsMapper linkLocaleStatsMapper;\n    private final LinkOsStatsMapper linkOsStatsMapper;\n    private final LinkBrowserStatsMapper linkBrowserStatsMapper;\n    private final LinkAccessLogsMapper linkAccessLogsMapper;\n    private final LinkDeviceStatsMapper linkDeviceStatsMapper;\n    private final LinkNetworkStatsMapper linkNetworkStatsMapper;\n    private final LinkStatsTodayMapper linkStatsTodayMapper;\n    private final DelayShortLinkStatsProducer delayShortLinkStatsProducer;\n    private final StringRedisTemplate stringRedisTemplate;\n\n    @Value(\"${short-link.stats.locale.amap-key}\")\n    private String statsLocaleAmapKey;\n\n    @Override\n    public void onMessage(MapRecord&lt;String, String, String&gt; message) {\n        String stream = message.getStream();\n        RecordId id = message.getId();\n        Map&lt;String, String&gt; producerMap = message.getValue();\n        String fullShortUrl = producerMap.get(\"fullShortUrl\");\n        if (StrUtil.isNotBlank(fullShortUrl)) {\n            String gid = producerMap.get(\"gid\");\n            ShortLinkStatsRecordDTO statsRecord = JSON.parseObject(producerMap.get(\"statsRecord\"), ShortLinkStatsRecordDTO.class);\n            actualSaveShortLinkStats(fullShortUrl, gid, statsRecord);\n        }\n        stringRedisTemplate.opsForStream().delete(Objects.requireNonNull(stream), id.getValue());\n    }\n\n    public void actualSaveShortLinkStats(String fullShortUrl, String gid, ShortLinkStatsRecordDTO statsRecord) {\n        fullShortUrl = Optional.ofNullable(fullShortUrl).orElse(statsRecord.getFullShortUrl());\n        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(String.format(LOCK_GID_UPDATE_KEY, fullShortUrl));\n        RLock rLock = readWriteLock.readLock();\n        if (!rLock.tryLock()) {\n            delayShortLinkStatsProducer.send(statsRecord);\n            return;\n        }\n        try {\n            if (StrUtil.isBlank(gid)) {\n                LambdaQueryWrapper&lt;ShortLinkGotoDO&gt; queryWrapper = Wrappers.lambdaQuery(ShortLinkGotoDO.class)\n                        .eq(ShortLinkGotoDO::getFullShortUrl, fullShortUrl);\n                ShortLinkGotoDO shortLinkGotoDO = shortLinkGotoMapper.selectOne(queryWrapper);\n                gid = shortLinkGotoDO.getGid();\n            }\n            int hour = DateUtil.hour(new Date(), true);\n            Week week = DateUtil.dayOfWeekEnum(new Date());\n            int weekValue = week.getIso8601Value();\n            LinkAccessStatsDO linkAccessStatsDO = LinkAccessStatsDO.builder()\n                    .pv(1)\n                    .uv(statsRecord.getUvFirstFlag() ? 1 : 0)\n                    .uip(statsRecord.getUipFirstFlag() ? 1 : 0)\n                    .hour(hour)\n                    .weekday(weekValue)\n                    .fullShortUrl(fullShortUrl)\n                    .gid(gid)\n                    .date(new Date())\n                    .build();\n            linkAccessStatsMapper.shortLinkStats(linkAccessStatsDO);\n            Map&lt;String, Object&gt; localeParamMap = new HashMap&lt;&gt;();\n            localeParamMap.put(\"key\", statsLocaleAmapKey);\n            localeParamMap.put(\"ip\", statsRecord.getRemoteAddr());\n            String localeResultStr = HttpUtil.get(AMAP_REMOTE_URL, localeParamMap);\n            JSONObject localeResultObj = JSON.parseObject(localeResultStr);\n            String infoCode = localeResultObj.getString(\"infocode\");\n            String actualProvince = \"\u672a\u77e5\";\n            String actualCity = \"\u672a\u77e5\";\n            if (StrUtil.isNotBlank(infoCode) &amp;&amp; StrUtil.equals(infoCode, \"10000\")) {\n                String province = localeResultObj.getString(\"province\");\n                boolean unknownFlag = StrUtil.equals(province, \"[]\");\n                LinkLocaleStatsDO linkLocaleStatsDO = LinkLocaleStatsDO.builder()\n                        .province(actualProvince = unknownFlag ? actualProvince : province)\n                        .city(actualCity = unknownFlag ? actualCity : localeResultObj.getString(\"city\"))\n                        .adcode(unknownFlag ? \"\u672a\u77e5\" : localeResultObj.getString(\"adcode\"))\n                        .cnt(1)\n                        .fullShortUrl(fullShortUrl)\n                        .country(\"\u4e2d\u56fd\")\n                        .gid(gid)\n                        .date(new Date())\n                        .build();\n                linkLocaleStatsMapper.shortLinkLocaleState(linkLocaleStatsDO);\n            }\n            LinkOsStatsDO linkOsStatsDO = LinkOsStatsDO.builder()\n                    .os(statsRecord.getOs())\n                    .cnt(1)\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .date(new Date())\n                    .build();\n            linkOsStatsMapper.shortLinkOsState(linkOsStatsDO);\n            LinkBrowserStatsDO linkBrowserStatsDO = LinkBrowserStatsDO.builder()\n                    .browser(statsRecord.getBrowser())\n                    .cnt(1)\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .date(new Date())\n                    .build();\n            linkBrowserStatsMapper.shortLinkBrowserState(linkBrowserStatsDO);\n            LinkDeviceStatsDO linkDeviceStatsDO = LinkDeviceStatsDO.builder()\n                    .device(statsRecord.getDevice())\n                    .cnt(1)\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .date(new Date())\n                    .build();\n            linkDeviceStatsMapper.shortLinkDeviceState(linkDeviceStatsDO);\n            LinkNetworkStatsDO linkNetworkStatsDO = LinkNetworkStatsDO.builder()\n                    .network(statsRecord.getNetwork())\n                    .cnt(1)\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .date(new Date())\n                    .build();\n            linkNetworkStatsMapper.shortLinkNetworkState(linkNetworkStatsDO);\n            LinkAccessLogsDO linkAccessLogsDO = LinkAccessLogsDO.builder()\n                    .user(statsRecord.getUv())\n                    .ip(statsRecord.getRemoteAddr())\n                    .browser(statsRecord.getBrowser())\n                    .os(statsRecord.getOs())\n                    .network(statsRecord.getNetwork())\n                    .device(statsRecord.getDevice())\n                    .locale(StrUtil.join(\"-\", \"\u4e2d\u56fd\", actualProvince, actualCity))\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .build();\n            linkAccessLogsMapper.insert(linkAccessLogsDO);\n            shortLinkMapper.incrementStats(gid, fullShortUrl, 1, statsRecord.getUvFirstFlag() ? 1 : 0, statsRecord.getUipFirstFlag() ? 1 : 0);\n            LinkStatsTodayDO linkStatsTodayDO = LinkStatsTodayDO.builder()\n                    .todayPv(1)\n                    .todayUv(statsRecord.getUvFirstFlag() ? 1 : 0)\n                    .todayUip(statsRecord.getUipFirstFlag() ? 1 : 0)\n                    .gid(gid)\n                    .fullShortUrl(fullShortUrl)\n                    .date(new Date())\n                    .build();\n            linkStatsTodayMapper.shortLinkTodayState(linkStatsTodayDO);\n        } catch (Throwable ex) {\n            log.error(\"\u77ed\u94fe\u63a5\u8bbf\u95ee\u91cf\u7edf\u8ba1\u5f02\u5e38\", ex);\n        } finally {\n            rLock.unlock();\n        }\n    }\n}<\/pre>\n\n\n\n<p>\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u77ed\u94fe\u63a5\u76d1\u63a7\u7edf\u8ba1\u7684\u5f02\u6b65\u5316\u91cd\u6784\u8fc7\u7a0b\u3002\u539f\u6765\u7684\u5b9e\u73b0\u662f\u540c\u6b65\u5199\u5165\u6570\u636e\u5e93\uff0c\u8fd9\u6837\u5728\u9ad8\u5e76\u53d1\u573a\u666f\u4e0b\u5bb9\u6613\u6210\u4e3a\u6027\u80fd\u74f6\u9888\u3002\u6211\u4eec\u901a\u8fc7\u5f15\u5165Redis Stream\u6d88\u606f\u961f\u5217\u5b9e\u73b0\u4e86\u5f02\u6b65\u5904\u7406\uff0c\u5177\u4f53\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p>\n\n\n\n<p>\u5728shortlinkImpl\u7c7b\u4e2d\uff0c\u539f\u672c\u7684shortLinkStats\u65b9\u6cd5\u4f1a\u76f4\u63a5\u6267\u884c\u6570\u636e\u5e93\u64cd\u4f5c\uff0c\u73b0\u5728\u6539\u4e3a\u8c03\u7528\u6d88\u606f\u961f\u5217\u751f\u4ea7\u8005\u53d1\u9001\u6d88\u606f\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Override\n\npublic void shortLinkStats(String fullShortUrl, String gid, ShortLinkStatsRecordDTO statsRecord) {\n\nMap&lt;String, String&gt; producerMap = new HashMap&lt;&gt;();\n\nproducerMap.put(\"fullShortUrl\", fullShortUrl);\n\nproducerMap.put(\"gid\", gid);\n\nproducerMap.put(\"statsRecord\", JSON.toJSONString(statsRecord));\n\nshortLinkStatsSaveProducer.send(producerMap);\n\n}<\/code><\/pre>\n\n\n\n<p>\u8fd9\u91cc\u521b\u5efa\u4e86\u4e00\u4e2aMap\u5bb9\u5668\u6765\u5c01\u88c5\u9700\u8981\u4f20\u9012\u7684\u4e09\u4e2a\u6838\u5fc3\u53c2\u6570\uff1a\u5b8c\u6574\u77ed\u94fe\u63a5\u5730\u5740\u3001\u5206\u7ec4ID\u548c\u7edf\u8ba1\u8bb0\u5f55\u5bf9\u8c61\u3002\u901a\u8fc7JSON\u5e8f\u5217\u5316\u5c06statsRecord\u8f6c\u6362\u4e3a\u5b57\u7b26\u4e32\u5b58\u50a8\uff0c\u786e\u4fdd\u53c2\u6570\u4f20\u8f93\u7684\u5b8c\u6574\u6027\u3002<\/p>\n\n\n\n<p>\u6d88\u606f\u961f\u5217\u751f\u4ea7\u8005ShortLinkStatsSaveProducer\u7684\u5b9e\u73b0\u975e\u5e38\u7b80\u5355\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class ShortLinkStatsSaveProducer {\n    private final StringRedisTemplate stringRedisTemplate;\n    @Value(\"${spring.data.redis.channel-topic.short-link-stats}\")\n    private String topic;\n    \n    public void send(Map&lt;String, String&gt; producerMap) {\n        stringRedisTemplate.opsForStream().add(topic, producerMap);\n    }\n}<\/code><\/pre>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"15\" src=\"blob:https:\/\/eve2333.top\/a0930c8c-cabc-4baa-bc58-e4218855e52e\" width=\"15\"><\/p>\n\n\n\n<p>\u8fd9\u91cc\u5229\u7528\u4e86Redis 5.0+\u7684Stream\u6570\u636e\u7ed3\u6784\u4f5c\u4e3a\u6d88\u606f\u961f\u5217\uff0c\u76f8\u6bd4List\u7ed3\u6784\u5177\u6709\u66f4\u597d\u7684\u6d88\u606f\u8ffd\u8e2a\u80fd\u529b\u3002\u901a\u8fc7\u914d\u7f6e\u4e2d\u5fc3\u6ce8\u5165\u7684topic\u540d\u79f0\uff0c\u5c06\u5c01\u88c5\u597d\u7684\u53c2\u6570\u4ee5\u6d41\u5f0f\u6570\u636e\u5f62\u5f0f\u53d1\u9001\u5230\u6307\u5b9a\u901a\u9053\u3002<\/p>\n\n\n\n<p>\u6d88\u606f\u6d88\u8d39\u8005ShortLinkStatsSaveConsumer\u7684\u6838\u5fc3\u903b\u8f91\u5728onMessage\u65b9\u6cd5\u4e2d\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Override\npublic void onMessage(MapRecord&lt;String, String, String&gt; message) {\n    String stream = message.getStream();\n    RecordId id = message.getId();\n    Map&lt;String, String&gt; producerMap = message.getValue();\n    String fullShortUrl = producerMap.get(\"fullShortUrl\");\n    if (StrUtil.isNotBlank(fullShortUrl)) {\n        String gid = producerMap.get(\"gid\");\n        ShortLinkStatsRecordDTO statsRecord = JSON.parseObject(producerMap.get(\"statsRecord\"), ShortLinkStatsRecordDTO.class);\n        actualSaveShortLinkStats(fullShortUrl, gid, statsRecord);\n    }\n    stringRedisTemplate.opsForStream().delete(Objects.requireNonNull(stream), id.getValue());\n}<\/code><\/pre>\n\n\n\n<p>\u5f53\u63a5\u6536\u5230\u6d88\u606f\u65f6\uff0c\u9996\u5148\u89e3\u6790\u51fa\u4e09\u4e2a\u6838\u5fc3\u53c2\u6570\uff0c\u9a8c\u8bc1\u5b8c\u6574\u6027\u540e\u8c03\u7528\u5b9e\u9645\u5904\u7406\u65b9\u6cd5\u3002\u5904\u7406\u5b8c\u6210\u540e\u7acb\u5373\u5220\u9664\u5df2\u6d88\u8d39\u7684\u6d88\u606f\uff0c\u9632\u6b62\u5185\u5b58\u5806\u79ef\u3002\u8fd9\u91cc\u6709\u4e2a\u5173\u952e\u8bbe\u8ba1\uff1a\u901a\u8fc7Stream\u7684del\u6307\u4ee4\u786e\u4fdd\u6d88\u606f\u53ea\u88ab\u5904\u7406\u4e00\u6b21\uff0c\u907f\u514d\u91cd\u590d\u6d88\u8d39\u95ee\u9898\u3002<\/p>\n\n\n\n<p>\u5b9e\u9645\u7684\u6570\u636e\u6301\u4e45\u5316\u903b\u8f91\u96c6\u4e2d\u5728actualSaveShortLinkStats\u65b9\u6cd5\u4e2d\u3002\u8fd9\u4e2a\u65b9\u6cd5\u9700\u8981\u5904\u7406\u591a\u4e2a\u7ef4\u5ea6\u7684\u7edf\u8ba1\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u57fa\u7840\u8bbf\u95ee\u7edf\u8ba1 <\/strong>\uff1aLinkAccessStatsDO\u8bb0\u5f55\u6bcf\u5c0f\u65f6\/\u6bcf\u5468\u7684PV\/UV\/UIP<\/li>\n\n\n\n<li><strong>\u5730\u7406\u4f4d\u7f6e\u7edf\u8ba1 <\/strong>\uff1a\u8c03\u7528AMap API\u89e3\u6790IP\u5f52\u5c5e\u5730<\/li>\n\n\n\n<li><strong>\u5ba2\u6237\u7aef\u73af\u5883\u7edf\u8ba1 <\/strong>\uff1a\u64cd\u4f5c\u7cfb\u7edf\u3001\u6d4f\u89c8\u5668\u3001\u8bbe\u5907\u3001\u7f51\u7edc\u7c7b\u578b<\/li>\n\n\n\n<li><strong>\u8bbf\u95ee\u65e5\u5fd7\u8bb0\u5f55 <\/strong>\uff1aLinkAccessLogsDO\u5b58\u50a8\u539f\u59cb\u8bbf\u95ee\u65e5\u5fd7<\/li>\n\n\n\n<li><strong>\u5b9e\u65f6\u6307\u6807\u66f4\u65b0 <\/strong>\uff1a\u901a\u8fc7shortLinkMapper.incrementStats\u66f4\u65b0\u5b9e\u65f6\u8ba1\u6570\u5668<\/li>\n\n\n\n<li><strong>\u5f53\u65e5\u7edf\u8ba1 <\/strong>\uff1aLinkStatsTodayDO\u8bb0\u5f55\u5f53\u5929\u7684\u7d2f\u8ba1\u6570\u636e<\/li>\n<\/ol>\n\n\n\n<p>\u8fd9\u91cc\u7528\u4e86Redisson\u7684\u8bfb\u5199\u9501\u6765\u4fdd\u8bc1\u540c\u4e2a\u77ed\u94fe\u63a5\u7684\u5e76\u53d1\u5b89\u5168\uff1a\u901a\u8fc7\u8bfb\u5199\u9501\u907f\u514d\u540c\u4e00\u77ed\u94fe\u63a5\u7684\u5e76\u53d1\u5904\u7406\u51b2\u7a81\u3002\u5982\u679c\u83b7\u53d6\u9501\u5931\u8d25\uff0c\u4f1a\u901a\u8fc7\u5ef6\u8fdf\u961f\u5217\u91cd\u65b0\u5165\u961f\u5904\u7406\u3002\u8fd9\u4e2a\u8bbe\u8ba1\u8003\u8651\u5230\u4e86\u5206\u5e03\u5f0f\u573a\u666f\u4e0b\u7684\u5e76\u53d1\u63a7\u5236\u9700\u6c42\u3002<\/p>\n\n\n\n<p>\u5730\u7406\u4f4d\u7f6e\u7edf\u8ba1\u90e8\u5206\u6709\u4e2a\u5de7\u5999\u7684\u5904\u7406\uff1a\u8fd9\u91cc\u901a\u8fc7\u9ad8\u5fb7\u5730\u56feAPI\u5c06IP\u8f6c\u6362\u4e3a\u5730\u7406\u4fe1\u606f\uff0c\u4f46\u505a\u4e86\u5bb9\u9519\u5904\u7406\uff1a\u5f53API\u8c03\u7528\u5931\u8d25\u6216\u8fd4\u56de\u65e0\u6548\u6570\u636e\u65f6\uff0c\u9ed8\u8ba4\u6807\u8bb0\u4e3a\"\u672a\u77e5\"\u5730\u533a\u3002\u8fd9\u79cd\u8bbe\u8ba1\u65e2\u4fdd\u8bc1\u4e86\u6838\u5fc3\u7edf\u8ba1\u7684\u53ef\u7528\u6027\uff0c\u53c8\u907f\u514d\u4e86\u7b2c\u4e09\u65b9\u670d\u52a1\u4e0d\u7a33\u5b9a\u5e26\u6765\u7684\u5f71\u54cd\u3002<\/p>\n\n\n\n<p>\u5728\u5904\u7406\u5ba2\u6237\u7aef\u73af\u5883\u7edf\u8ba1\u65f6\uff0c\u6bcf\u4e2a\u7ef4\u5ea6\u90fd\u6709\u72ec\u7acb\u7684DAO\u64cd\u4f5c\uff1a<\/p>\n\n\n\n<p>linkOsStatsMapper.shortLinkOsState(linkOsStatsDO); \/\/ \u64cd\u4f5c\u7cfb\u7edf<\/p>\n\n\n\n<p>linkBrowserStatsMapper.shortLinkBrowserState(linkBrowserStatsDO); \/\/ \u6d4f\u89c8\u5668<\/p>\n\n\n\n<p>linkDeviceStatsMapper.shortLinkDeviceState(linkDeviceStatsDO); \/\/ \u8bbe\u5907\u7c7b\u578b<\/p>\n\n\n\n<p>linkNetworkStatsMapper.shortLinkNetworkState(linkNetworkStatsDO); \/\/ \u7f51\u7edc\u7c7b\u578b<\/p>\n\n\n\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u4fdd\u6301\u4e86\u5404\u7ef4\u5ea6\u7edf\u8ba1\u7684\u6b63\u4ea4\u6027\uff0c\u4fbf\u4e8e\u540e\u7eed\u6269\u5c55\u548c\u7ef4\u62a4\u3002\u6bcf\u4e2a\u7edf\u8ba1\u7ef4\u5ea6\u90fd\u6709\u5bf9\u5e94\u7684\u8868\u7ed3\u6784\u652f\u6301\uff0c\u7b26\u5408\u5355\u4e00\u804c\u8d23\u539f\u5219\u3002<\/p>\n\n\n\n<p>\u65e5\u5fd7\u8bb0\u5f55\u548c\u5b9e\u65f6\u6307\u6807\u66f4\u65b0\u91c7\u7528\u4e86\u4e0d\u540c\u7684\u7b56\u7565\uff1a<\/p>\n\n\n\n<p>linkAccessLogsMapper.insert(linkAccessLogsDO); \/\/ \u539f\u59cb\u8bbf\u95ee\u65e5\u5fd7\u76f4\u63a5\u63d2\u5165<\/p>\n\n\n\n<p>shortLinkMapper.incrementStats(...); \/\/ \u4f7f\u7528MySQL\u7684\u539f\u5b50\u64cd\u4f5c\u66f4\u65b0\u5b9e\u65f6\u8ba1\u6570<\/p>\n\n\n\n<p>linkStatsTodayMapper.shortLinkTodayState(linkStatsTodayDO); \/\/ \u5f53\u65e5\u7edf\u8ba1\u901a\u8fc7upsert\u64cd\u4f5c<\/p>\n\n\n\n<p>\u539f\u59cb\u65e5\u5fd7\u4f7f\u7528\u7b80\u5355\u7684insert\u64cd\u4f5c\u4fdd\u8bc1\u6570\u636e\u5b8c\u6574\u6027\uff0c\u800c\u5b9e\u65f6\u6307\u6807\u91c7\u7528MySQL\u7684\u539f\u5b50\u66f4\u65b0\uff08\u5982UPDATE ... ON DUPLICATE KEY UPDATE\uff09\uff0c\u65e2\u4fdd\u8bc1\u6027\u80fd\u53c8\u907f\u514d\u9501\u7ade\u4e89\u3002<\/p>\n\n\n\n<p>\u5728\u5f02\u5e38\u5904\u7406\u65b9\u9762\uff0c\u6574\u4e2a\u65b9\u6cd5\u5305\u88f9\u5728try-catch\u4e2d\uff1a\u786e\u4fdd\u4efb\u4f55\u60c5\u51b5\u4e0b\u90fd\u4f1a\u91ca\u653e\u5206\u5e03\u5f0f\u9501\uff0c\u9632\u6b62\u6b7b\u9501\u3002\u540c\u65f6\u901a\u8fc7\u5ef6\u8fdf\u961f\u5217\u7684\u4e8c\u6b21\u6295\u9012\u673a\u5236\uff0c\u4fdd\u8bc1\u6570\u636e\u6700\u7ec8\u4e00\u81f4\u6027\u3002<\/p>\n\n\n\n<p>\u8fd9\u4e2a\u65b9\u6848\u6709\u4e09\u4e2a\u663e\u8457\u4f18\u52bf\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u89e3\u8026\u7edf\u8ba1\u4e0e\u4e1a\u52a1 <\/strong>\uff1a\u5c06\u8017\u65f6\u7684\u7edf\u8ba1\u64cd\u4f5c\u5f02\u6b65\u5316\uff0c\u63d0\u5347\u4e3b\u6d41\u7a0b\u54cd\u5e94\u901f\u5ea6<\/li>\n\n\n\n<li><strong>\u6279\u91cf\u5904\u7406\u80fd\u529b <\/strong>\uff1a\u901a\u8fc7\u6d88\u606f\u961f\u5217\u7f13\u51b2\uff0c\u53ef\u4ee5\u652f\u6301\u6279\u91cf\u5165\u5e93\u4f18\u5316<\/li>\n\n\n\n<li><strong>\u7cfb\u7edf\u7a33\u5b9a\u6027 <\/strong>\uff1a\u9694\u79bb\u7edf\u8ba1\u6a21\u5757\u5bf9\u6838\u5fc3\u94fe\u8def\u7684\u5f71\u54cd\uff0c\u589e\u5f3a\u7cfb\u7edf\u6574\u4f53\u53ef\u9760\u6027<\/li>\n<\/ol>\n\n\n\n<p>\u4f46\u8fd8\u5b58\u5728\u4e24\u4e2a\u5f85\u4f18\u5316\u70b9\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6570\u636e\u5ef6\u8fdf\u95ee\u9898 <\/strong>\uff1a\u7531\u4e8e\u5f02\u6b65\u5904\u7406\uff0c\u5b9e\u65f6\u6570\u636e\u53ef\u80fd\u5b58\u5728\u79d2\u7ea7\u5ef6\u8fdf<\/li>\n\n\n\n<li><strong>\u91cd\u590d\u6d88\u8d39\u98ce\u9669 <\/strong>\uff1a\u867d\u7136\u6d88\u606f\u5904\u7406\u662f\u5e42\u7b49\u7684\uff0c\u4f46\u9700\u8981\u66f4\u5b8c\u5584\u7684\u53bb\u91cd\u673a\u5236<\/li>\n<\/ol>\n\n\n\n<p>\u540e\u7eed\u8ba1\u5212\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5728consume\u9636\u6bb5\u589e\u52a0\u57fa\u4e8eRedis\u7684\u5e03\u9686\u8fc7\u6ee4\u5668\u505a\u53bb\u91cd<\/li>\n\n\n\n<li>\u4f7f\u7528\u5ef6\u8fdf\u961f\u5217\u505a\u8865\u507f\u673a\u5236\uff0c\u5e94\u5bf9\u6d88\u606f\u4e22\u5931\u573a\u666f<\/li>\n\n\n\n<li>\u589e\u52a0\u914d\u7f6e\u5f00\u5173\uff0c\u652f\u6301RocketMQ\/Kafka\u7b49\u4e13\u4e1a\u6d88\u606f\u4e2d\u95f4\u4ef6\u7684\u65e0\u7f1d\u5207\u6362<\/li>\n\n\n\n<li>\u6dfb\u52a0\u76d1\u63a7\u57cb\u70b9\uff0c\u5b9e\u65f6\u89c2\u6d4b\u6d88\u606f\u5806\u79ef\u60c5\u51b5<\/li>\n<\/ul>\n\n\n\n<p>\u8fd9\u79cd\u6539\u9020\u5c06\u539f\u672c\u9700\u8981100ms\u7684\u540c\u6b65\u64cd\u4f5c\u964d\u5230\u4e8610ms\u5185\u5b8c\u6210\uff0c\u867d\u7136\u589e\u52a0\u4e86\u7cfb\u7edf\u590d\u6742\u5ea6\uff0c\u4f46\u663e\u8457\u63d0\u5347\u4e86\u541e\u5410\u91cf\u3002\u901a\u8fc7Redis Stream\u7684\u81ea\u52a8ack\u673a\u5236\u548c\u6d88\u606f\u5220\u9664\u7b56\u7565\uff0c\u786e\u4fdd\u4e86\u6d88\u606f\u7684\u53ef\u9760\u6d88\u8d39\u3002\u8fd9\u79cd\u8bbe\u8ba1\u7279\u522b\u9002\u5408\u5199\u591a\u8bfb\u5c11\u7684\u7edf\u8ba1\u573a\u666f\uff0c\u540e\u7eed\u53ef\u4ee5\u6839\u636e\u5b9e\u9645\u538b\u6d4b\u6570\u636e\u8c03\u6574\u7ebf\u7a0b\u6c60\u53c2\u6570\uff0c\u8fdb\u4e00\u6b65\u4f18\u5316\u5904\u7406\u6027\u80fd\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"oM269\">\u4f7f\u7528\u6d88\u606f\u961f\u5217\u540e\u7684\u4e00\u4e9b\u95ee\u9898\uff1f<\/h2>\n\n\n\n<p id=\"u225b60ca\">\u6570\u636e\u5ef6\u8fdf<\/p>\n\n\n\n<p id=\"u24f0ff23\">\u5e42\u7b49<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Dc6hJ\">\u8bfe\u540e\u4f5c\u4e1a<\/h2>\n\n\n\n<p id=\"ufa1a4bfe\">\u4f7f\u7528 RabbitMQ\u3001RocketMQ \u6216 Kafka \u4efb\u610f\u4e00\u79cd MQ \u8fdb\u884c\u6539\u9020\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c13\u8282\uff1a\u6d88\u606f\u961f\u5217\u91cd\u590d\u6d88\u8d39\u95ee\u9898\u5982\u4f55\u89e3\u51b3\uff08\u4e0a\uff09<\/h2>\n\n\n\n<p>\u9700\u6c42\u80cc\u666f<\/p>\n\n\n\n<p>\u5f53\u6d88\u606f\u961f\u5217\u51fa\u73b0\u91cd\u590d\u6d88\u8d39\u95ee\u9898\u60c5\u51b5\u4e0b\uff0c\u5e94\u8be5\u5982\u4f55\u4fdd\u969c\u6570\u636e\u7684\u51c6\u786e\u6027\uff1f\u7f51\u7edc\u95ee\u9898\uff1b\u751f\u4ea7\u91cd\u8bd5<\/p>\n\n\n\n<p>\u5982\u4f55\u89e3\u51b3\uff1f\u5e42\u7b49\u3002\u5c31\u662f\u4f60\u4e00\u4e2a\u8bf7\u6c42\uff0c\u4e24\u6b21\u4e00\u6a21\u4e00\u6837\u7684\u8bf7\u6c42\u8fc7\u6765\uff0c\u6700\u7ec8\u6267\u884c\u7ed3\u679c\u548c\u6765\u4e00\u6b21\u7684\u662f\u4e00\u6837\u7684<img loading=\"lazy\" decoding=\"async\" height=\"742\" width=\"960\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c0b43c99996c44eeb6492560399dd28c.png\" alt=\"\"><br>\u00a0<\/p>\n\n\n\n<p>\u5728mq\u4e0b\u5c01\u88c5idempotent\u7684MessageQueueIdempotentHandler\u6587\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.idempotent;\n\n\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\n\n\/**\n * \u6d88\u606f\u961f\u5217\u5e42\u7b49\u5904\u7406\u5668\n *\/\n@Component\n@RequiredArgsConstructor\npublic class MessageQueueIdempotentHandler {\n\n    private final StringRedisTemplate stringRedisTemplate;\n\n    private static final String IDEMPOTENT_KEY_PREFIX = \"short-link:idempotent:\";\n\n    \/**\n     * \u5224\u65ad\u5f53\u524d\u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     * @return \u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n     *\/\n    public boolean isMessageProcessed(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, \"0\", 2, TimeUnit.MINUTES));\n    }\n\n    \/**\n     * \u5224\u65ad\u6d88\u606f\u6d88\u8d39\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     * @return \u6d88\u606f\u662f\u5426\u6267\u884c\u5b8c\u6210\n     *\/\n    public boolean isAccomplish(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        return Objects.equals(stringRedisTemplate.opsForValue().get(key), \"1\");\n    }\n\n    \/**\n     * \u8bbe\u7f6e\u6d88\u606f\u6d41\u7a0b\u6267\u884c\u5b8c\u6210\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     *\/\n    public void setAccomplish(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        stringRedisTemplate.opsForValue().set(key, \"1\", 2, TimeUnit.MINUTES);\n    }\n\n    \/**\n     * \u5982\u679c\u6d88\u606f\u5904\u7406\u9047\u5230\u5f02\u5e38\u60c5\u51b5\uff0c\u5220\u9664\u5e42\u7b49\u6807\u8bc6\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     *\/\n    public void delMessageProcessed(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        stringRedisTemplate.delete(key);\n    }\n}<\/pre>\n\n\n\n<p>\u5bf9\u5e94\u662f&nbsp;ShortLinkStatsSaveConsumer<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    @Override\n    public void onMessage(MapRecord&lt;String, String, String&gt; message) {\n        String stream = message.getStream();\n        RecordId id = message.getId();\n        if (!messageQueueIdempotentHandler.isMessageProcessed(id.toString())) {\n            \/\/ \u5224\u65ad\u5f53\u524d\u7684\u8fd9\u4e2a\u6d88\u606f\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\n            if (messageQueueIdempotentHandler.isAccomplish(id.toString())) {\n                return;\n            }\n            throw new ServiceException(\"\u6d88\u606f\u672a\u5b8c\u6210\u6d41\u7a0b\uff0c\u9700\u8981\u6d88\u606f\u961f\u5217\u91cd\u8bd5\");\n        }\n        try {\n            Map&lt;String, String&gt; producerMap = message.getValue();\n            String fullShortUrl = producerMap.get(\"fullShortUrl\");\n            if (StrUtil.isNotBlank(fullShortUrl)) {\n                String gid = producerMap.get(\"gid\");\n                ShortLinkStatsRecordDTO statsRecord = JSON.parseObject(producerMap.get(\"statsRecord\"), ShortLinkStatsRecordDTO.class);\n                actualSaveShortLinkStats(fullShortUrl, gid, statsRecord);\n            }\n            stringRedisTemplate.opsForStream().delete(Objects.requireNonNull(stream), id.getValue());\n        } catch (Throwable ex) {\n            \/\/ \u67d0\u67d0\u67d0\u60c5\u51b5\u5b95\u673a\u4e86\n            messageQueueIdempotentHandler.delMessageProcessed(id.toString());\n            log.error(\"\u8bb0\u5f55\u77ed\u94fe\u63a5\u76d1\u63a7\u6d88\u8d39\u5f02\u5e38\", ex);\n        }\n        messageQueueIdempotentHandler.setAccomplish(id.toString());\n    }<\/code><\/pre>\n\n\n\n<p>\u6211\u4eec\u8fd9\u8fb9\u5df2\u7ecf\u6709\u4e00\u4e2aKey\uff0c\u5b83\u7684\u8fc7\u671f\u65f6\u95f4\u662f600\u79d2\uff0810\u5206\u949f\uff09\uff0c\u5bf9\u5427\uff1f\u8fd9\u91cc\u5df2\u7ecfok\u4e86\u3002\u90a3\u5982\u679c\u8bf4\u518d\u6709\u4e00\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u6d88\u606f\uff0cID\u518d\u51fa\u73b0\u7684\u8bdd\uff0c\u8fd9\u91cc\u76f4\u63a5\u662f\u4e0d\u662f\u56e0\u4e3a\u5b83\u5df2\u7ecf\u6709\u4e86\u63d2\u4e0d\u8fdb\u53bb\uff1f\u5c31\u4f1a\u8fd4\u56defalse\u3002\u8fd9\u4e2a\u65f6\u5019\u4e00\u65e6Q\u7684\u8bdd\u5b83\u5c31\u7b49\u4e8efalse\uff0cboss\u8fd9\u8fb9\u5c31\u5217\u5165\u4e86\uff0c\u662f\u4e0d\u662f\u5c31\u76f4\u63a5\u4fdd\u8bc1\u4e86\u6211\u4eec\u7684\u5e42\u7b49\u6027\uff1f\u5bf9\u5427\uff1f\u5982\u679c\u5927\u5bb6\u770b\u5230\u8fd9\u91cc\u89c9\u5f97\u6ca1\u6709\u95ee\u9898\u7684\uff0c\u6211\u4eec\u518d\u5f80\u4e0b\u770b\u3002<\/p>\n\n\n\n<p>\u7ee7\u7eed\u770b\u5e38\u89c1\u95ee\u9898\uff1a<strong>\u6d88\u606f\u6d88\u8d39\u5931\u8d25\u600e\u4e48\u529e <\/strong>\uff1f<\/p>\n\n\n\n<p>\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u5047\u8bbe\u6d88\u606f\u7b2c\u4e00\u6b21\u6d88\u8d39\u65f6\u63d2\u5165\u4e86\u5e42\u7b49\u6807\u8bc6\uff08Redis key\uff09\uff0c\u4f46\u5728\u540e\u7eed\u5904\u7406\u4e2d\u53d1\u751f\u4e86\u5f02\u5e38\u3002\u8fd9\u65f6\u5019MQ\u4e00\u822c\u4f1a\u89e6\u53d1\u91cd\u8bd5\u673a\u5236\u3002\u7531\u4e8eRedis\u4e2d\u8fd8\u5b58\u5728\u8fd9\u4e2a\u6807\u8bc6\uff0c\u7b2c\u4e8c\u6b21\u6d88\u8d39\u65f6\u4f1a\u88ab\u8ba4\u4e3a\u5df2\u7ecf\u5904\u7406\u8fc7\uff0c\u76f4\u63a5\u8fd4\u56de\u6210\u529f\uff0c\u4f46\u5b9e\u9645\u4e0a\u4e1a\u52a1\u903b\u8f91\u5e76\u6ca1\u6709\u6b63\u786e\u6267\u884c\u3002\u5f53\u5904\u7406\u5931\u8d25\u65f6\uff0c\u4e3b\u52a8\u5220\u9664Redis\u4e2d\u7684\u6807\u8bc6\uff0c\u8ba9MQ\u53ef\u4ee5\u91cd\u65b0\u6295\u9012\u8fd9\u6761\u6d88\u606f\u3002\u8fd9\u6837\u5373\u4f7f\u7b2c\u4e00\u6b21\u5904\u7406\u5931\u8d25\uff0c\u4e5f\u80fd\u4fdd\u8bc1\u540e\u7eed\u80fd\u6210\u529f\u5904\u7406\u3002\u8bbe\u7f6e\u4e24\u4e2a\u72b6\u6001\uff1a<code>\"0\"<\/code> \u8868\u793a\u5df2\u63d2\u5165\u4f46\u672a\u5b8c\u6210\uff1b<code>\"1\"<\/code> \u8868\u793a\u5df2\u5b8c\u5168\u5904\u7406\u6210\u529f<\/p>\n\n\n\n<p>\u5173\u952e\u6539\u8fdb\u70b9\uff1a\u5728catch\u4e2d\u5220\u9664\u6807\u8bc6\uff0c\u786e\u4fddMQ\u53ef\u4ee5\u91cd\u65b0\u6295\u9012\uff1b\u65e0\u8bba\u6210\u529f\u4e0e\u5426\u90fd\u5728finally\u4e2d\u5220\u9664\u6d88\u606f\uff0c\u907f\u514d\u6d88\u606f\u5806\u79ef<\/p>\n\n\n\n<p>\u6d4b\u8bd5\u9a8c\u8bc1\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u6b63\u5e38\u573a\u666f <\/strong>\uff1a\u7b2c\u4e00\u6b21\u5904\u7406\u6210\u529f \u2192 Redis\u503c\u53d8\u4e3a\"1\" \u2192 \u91cd\u590d\u6d88\u606f\u76f4\u63a5\u8df3\u8fc7<\/li>\n\n\n\n<li><strong>\u5931\u8d25\u91cd\u8bd5 <\/strong>\uff1a\u7b2c\u4e00\u6b21\u5904\u7406\u5931\u8d25 \u2192 \u5220\u9664\u6807\u8bc6 \u2192 MQ\u91cd\u8bd5 \u2192 \u6210\u529f\u5904\u7406 \u2192 \u6807\u8bb0\u4e3a\"1\"<\/li>\n\n\n\n<li><strong>MQ\u81ea\u52a8\u91cd\u8bd5 <\/strong>\uff1a\u6d88\u606f\u672a\u786e\u8ba4 \u2192 MQ\u81ea\u52a8\u91cd\u6295 \u2192 \u53d1\u73b0\u72b6\u6001\u662f\"0\" \u2192 \u629b\u5f02\u5e38\u89e6\u53d1\u91cd\u8bd5<\/li>\n<\/ol>\n\n\n\n<p>\u901a\u8fc7Redis+\u72b6\u6001\u673a\u5b9e\u73b0\u4e86\u53ef\u9760\u7684\u5e42\u7b49\u6027\u4fdd\u969c\uff0c\u89e3\u51b3\u4e86\u4ee5\u4e0b\u95ee\u9898\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6d88\u606f\u91cd\u590d <\/strong>\uff1a\u901a\u8fc7\u552f\u4e00ID\u548cRedis\u9501\u4fdd\u8bc1<\/li>\n\n\n\n<li><strong>\u6d88\u606f\u4e22\u5931 <\/strong>\uff1aMQ\u81ea\u52a8ack\u673a\u5236\u4fdd\u969c<\/li>\n\n\n\n<li><strong>\u72b6\u6001\u6df7\u4e71 <\/strong>\uff1a\u72b6\u6001\u673a\u8bbe\u8ba1\u9632\u6b62\u4e2d\u95f4\u72b6\u6001\u5bfc\u81f4\u7684\u8bef\u5224<\/li>\n\n\n\n<li><strong>\u5185\u5b58\u6cc4\u6f0f <\/strong>\uff1a\u8bbe\u7f6eTTL\u81ea\u52a8\u6e05\u7406<\/li>\n<\/ul>\n\n\n\n<p>\u5e38\u89c1\u95ee\u9898\u5982\u679c\u6d88\u8d39\u8005\u6d88\u8d39\u5931\u8d25\u4e86\u4f46\u6ca1\u6709\u6267\u884c\u5230\u5220\u9664\u6807\u8bc6\uff0c\u8be5\u600e\u4e48\u529e\uff1f\u4e3a\u4ec0\u4e48\u4ec5\u8bbe\u7f6e 10 \u5206\u949f\u7684\u8fc7\u671f\u65f6\u95f4\uff1f\u5982\u4f55\u5e94\u5bf9\u6d77\u91cf\u5e42\u7b49 Key \u6240\u6d88\u8017\u7684\u5185\u5b58\uff1fMySQL \u6216\u5176\u5b83\u5927\u6570\u636e\u91cf\u5b58\u50a8\u3002\u60f3\u529e\u6cd5\u6539\u9020\u6570\u636e\u3002<\/p>\n\n\n\n<p id=\"u163af72a\"><strong>\u6b63\u5e38\u60c5\u51b5\uff1a\u83b7\u53d6\u6d88\u606f -&gt; \u8bbe\u7f6e\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09 -&gt; \u6d88\u8d39 -&gt; \u6807\u8bc6\u8bbe\u7f6e\uff08\u5df2\u5b8c\u6210\uff09<\/strong><\/p>\n\n\n\n<p id=\"udb7901b2\"><strong>\u5f02\u5e38\u60c5\u51b5\uff1a<\/strong><\/p>\n\n\n\n<p id=\"u685ec468\"><strong>1.\u91cd\u590d\u6d88\u606f\uff1a\u91cd\u590d\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u6b63\u5728\u6d88\u8d39\u4e2d\uff09 -&gt; \u5224\u65ad\u662f\u5426\u6d88\u8d39\u5b8c\u6210\uff08\u5df2\u5b8c\u6210\uff09-&gt; \u8fd4\u56de<\/strong><\/p>\n\n\n\n<p id=\"u6da499db\"><strong>2.\u91cd\u8bd5\u6d88\u606f\uff08\u6b63\u5e38\u6d41\u7a0b\uff09\uff1a\u91cd\u8bd5\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt;\u6d88\u8d39 -&gt;\u6807\u8bc6\u8bbe\u7f6e\uff08\u5df2\u5b8c\u6210\uff09<\/strong><\/p>\n\n\n\n<p id=\"u1331f0b7\"><strong>3.\u91cd\u8bd5\u6d88\u606f\uff08\u4e4b\u524d\u8bbe\u7f6e\u5df2\u5b8c\u6210\u6807\u8bc6\u5931\u8d25\uff09\uff1a\u91cd\u8bd5\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt; \u5224\u65ad\u662f\u5426\u6d88\u8d39\u5b8c\u6210\uff08\u672a\u5b8c\u6210\uff09-&gt; \u629b\u51fa\u5f02\u5e38 \u6d88\u606f\u6d88\u8d39\u4e2d \u4f46\u662f\u672a\u5b8c\u6210 -&gt; \u91cd\u8bd5 -&gt;redis\u8fc7\u671f -&gt; \u8fdb\u5165\u6b63\u5e38\u6d41\u7a0b<\/strong><\/p>\n\n\n\n<p id=\"u2c95994a\"><strong>4.\u6b63\u5e38\u6d88\u606f\uff08\u6d88\u8d39\u5f02\u5e38\uff09\uff1a\u83b7\u53d6\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt; \u6d88\u8d39\u5f02\u5e38 -&gt;\u5220\u9664\u9884\u5360\u6807\u8bc6 -&gt; \u629b\u51fa\u5f02\u5e38 \u6d88\u606f\u6d88\u8d39\u5931\u8d25 -&gt;\u91cd\u8bd5<\/strong><\/p>\n\n\n\n<p id=\"u90afd5d7\"><strong>5.\u91cd\u8bd5\u6d88\u606f\uff08\u4e4b\u524d\u6d88\u8d39\u5f02\u5e38\uff0c\u5e76\u4e14\u5220\u9664\u9884\u5360\u6807\u8bc6\u5931\u8d25\u201c\u5b95\u673a\u201d\uff09\uff1a\u53c2\u8003\u7b2c3\u6761<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u4e50\u5fe7\u5fd8\u5fe7\uff1a\u60f3\u95ee\u4e00\u4e0bredis\u7684Stream\u6709ack\u673a\u5236\u6765\u4fdd\u8bc1\u6d88\u606f\u88ab\u6d88\u8d39\u8005\u83b7\u53d6\u5230\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u91cc\u8fd8\u9700\u8981\u5355\u72ec\u91cd\u5199\u5224\u65ad<\/p>\n\n\n\n<p>Edgar&nbsp;\u56de\u590d&nbsp;\u4e50\u5fe7\u5fd8\u5fe7\uff1aACK\u53ea\u662f\u4fdd\u8bc1\u201dAT LEAST ONCE\u201c\uff0c\u4e0d\u662f\u201dExactly Once\u201c\u3002ACK\u673a\u5236\u53ef\u80fd\u51fa\u73b0\u95ee\u9898\uff0c\u5f53\u751f\u4ea7\u8005\u6ca1\u6709\u6536\u5230ACK\u65f6\uff0c\u53ef\u80fd\u7ee7\u7eed\u5411\u961f\u5217\u4e2d\u91cd\u590d\u53d1\u9001\u6d88\u606f\uff0c\u6b64\u65f6\u5c31\u9700\u8981\u989d\u5916\u5728\u4ee3\u7801\u5c42\u9762\u5e72\u9884\uff08\u4e2a\u4eba\u7406\u89e3\uff09<\/p>\n\n\n\n<p>cmqqq&nbsp;\u56de\u590d&nbsp;Edgar\uff1aACK\u673a\u5236\u53ea\u662f\u8bf4\u53bb\u4fdd\u8bc1\u6d88\u606f\u81f3\u5c11\u88ab\u6d88\u8d39\u4e00\u6b21\uff0c\u5e76\u6ca1\u6709\u4fdd\u8bc1\u91cd\u590d\u6d88\u8d39\u7684\u5e42\u7b49\u6027\u95ee\u9898\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u5728\u4e1a\u52a1\u91cc\u5224\u65ad\u662f\u5426\u88ab\u6d88\u8d39\u8fc7\u4e86\u3002<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;\u4e50\u5fe7\u5fd8\u5fe7\uff1a\u5927\u4f6c\u8bf4\u7684\u662fxack\u547d\u4ee4\u5417\uff1f\u6211\u67e5\u4e86\u4e0b\u8fd9\u4e2a\u547d\u4ee4\u662f\u5c06\u6d88\u606f\u6807\u8bb0\u4e3a\u3010\u5df2\u5904\u7406\u3011\uff0c\u4e0d\u662f\u7528\u6765\u4fdd\u8bc1\u6d88\u606f\u88ab\u6d88\u8d39\u8005\u3010\u5df2\u83b7\u53d6\u3011\u3002<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;Edgar\uff1a\u4f60\u8bf4\u7684\u610f\u601d\u6211\u61c2\uff0c\u4f46\u662f\u5728 redis stream \u4e2d\u7684\u751f\u4ea7\u8005\u6ca1\u6709\u91cd\u53d1\u673a\u5236\u3002&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ACK\u673a\u5236\u7684\u5c40\u9650\u6027 <\/strong>\uff1a<br>Redis Stream \u7684 <code>XACK<\/code> \u4ec5\u4fdd\u8bc1\u6d88\u8d39\u8005\u786e\u8ba4\u6d88\u606f\u540e\uff0cMQ \u624d\u5220\u9664\u6d88\u606f\uff08AT LEAST ONCE\uff09\uff0c\u4f46\u65e0\u6cd5\u907f\u514d\u4ee5\u4e0b\u573a\u666f\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u751f\u4ea7\u8005\u91cd\u590d\u53d1\u9001 <\/strong>\uff1a\u751f\u4ea7\u8005\u672a\u6536\u5230 ACK\uff0c\u89e6\u53d1\u91cd\u8bd5\uff0c\u5bfc\u81f4 MQ \u4e2d\u5b58\u5728\u91cd\u590d\u6d88\u606f\u3002<\/li>\n\n\n\n<li><strong>\u6d88\u8d39\u8005\u91cd\u590d\u5904\u7406 <\/strong>\uff1a\u6d88\u8d39\u8005\u4e1a\u52a1\u903b\u8f91\u6267\u884c\u5931\u8d25\uff08\u5982\u7f51\u7edc\u5f02\u5e38\uff09\uff0cMQ \u91cd\u8bd5\u65f6\u91cd\u590d\u6d88\u8d39\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5e42\u7b49\u6027\u7684\u5fc5\u8981\u6027 <\/strong>\uff1a<br>\u5373\u4f7f MQ \u4fdd\u8bc1\u6d88\u606f\u4e0d\u4e22\u5931\uff0c\u4e1a\u52a1\u5c42\u4ecd\u9700\u901a\u8fc7\u552f\u4e00 ID\uff08\u5982 <code>messageId<\/code>\uff09\u548c Redis \u6807\u8bc6\u786e\u4fdd\u91cd\u590d\u6d88\u606f\u7684\u5904\u7406\u7ed3\u679c\u4e00\u81f4\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u6728\u5c0f\u91cc\uff1a\u5728\u89c6\u9891\u6700\u540e\u9a6c\u54e5\u6f14\u793a\u7684\u90a3\u4e2a\u5f02\u5e38\u662f\u4e0d\u662f\u4f1a\u6709\u8fd9\u6837\u7684\u4e00\u4e2a\u95ee\u9898\uff1a\u7531\u4e8e\u5f02\u5e38\u662f\u5728\u6d88\u606f\u88ab\u6d88\u8d39\u4e4b\u540e\u629b\u51fa\u7684\uff0c\u53d1\u751f\u5728 <code>stringRedisTemplate.opsForStream().delete(...)<\/code> \u4e4b\u524d\uff1b\u4e5f\u5c31\u662f\u6d88\u606f\u88ab\u6210\u529f\u6d88\u8d39\u4e86\uff0c\u4f46\u662f\u8fd9\u65f6\u8fd9\u6761\u6d88\u606f\u7684 key \u4f1a\u4ece Redis \u4e2d\u5220\u6389\uff0c\u90a3\u4e0b\u4e00\u6b21\u53e6\u4e00\u4e2a\u6d88\u8d39\u8005\u62ff\u5230\u540c\u6837\u7684\u6d88\u606f\u4e4b\u540e\uff0c\u7531\u4e8e Redis \u6ca1\u6709\u8be5\u6761\u6d88\u606f\u7684 key\uff0c\u90a3\u5c82\u4e0d\u662f\u8bf4\u660e\u8be5\u6761\u6d88\u606f\u6ca1\u6709\u88ab\u6d88\u8d39\u8fc7\uff0c\u53c8\u8981\u88ab\u6d88\u8d39\u4e00\u6b21\uff0c\u8fd9\u4e0d\u8fd8\u662f\u6ca1\u89e3\u51b3\u5e42\u7b49\u6027\u95ee\u9898\u5417\uff1f<\/p>\n\n\n\n<p>\u674e\u6e29\u5019&nbsp;\u56de\u590d&nbsp;\u6728\u5c0f\u91cc\uff1a\u6211\u770b\u4e86\u4e00\u4e0btry\u91cc\u9762\u7684\u4ee3\u7801\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u5f02\u5e38\u7684\u5e94\u8be5\u5c31\u53ea\u6709actualSaveShortLinkStats\uff08\uff09 \u548c stringRedisTemplate.opsForStream().delete\uff08\uff09\uff0c\u524d\u8005\u662f\u548c\u6d88\u8d39\u6709\u5173\u7684\uff08\u6240\u4ee5\u5b83\u653e\u5728try\u91cc\u9762\u6ca1\u6bdb\u75c5\uff09\uff0c\u540e\u8005\u53ea\u662f\u91ca\u653e\u5185\u5b58\uff0c\u8981\u662f\u540e\u8005\u8fd9\u91cc\u4e00\u5b9a\u4e0d\u4f1a\u62a5\u9519\uff0c\u90a3\u6211\u4eec\u5c31\u53ef\u4ee5\u4e0d\u7528\u52a8\uff0c\u8981\u662f\u53ef\u80fd\u62a5\u9519\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b83\u79fb\u5230try\u5916\u9762\uff08\u4e2a\u4eba\u770b\u6cd5\uff09<\/p>\n\n\n\n<p>\u5730\u4fe1\u54e5&nbsp;\u56de\u590d&nbsp;\u6728\u5c0f\u91cc\uff1a\u6d88\u606f\u88ab\u6210\u529f\u6d88\u8d39\u4e4b\u540e\uff0c\u6700\u540e\u90a3\u4e2a\u6d88\u606f\u4e0d\u662f\u88ab\u79fb\u9664\u4e86\uff1f\u5c31\u4e0d\u5b58\u5728\u4e0b\u4e00\u6b21\u53e6\u4e00\u4e2a\u6d88\u8d39\u8005\u62ff\u5230\u540c\u6837\u7684\u6d88\u606f\u7684\u8fd9\u79cd\u60c5\u51b5\u4e86<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6b63\u5e38\u6d41\u7a0b <\/strong>\uff1a\u6d88\u606f\u5904\u7406\u6210\u529f \u2192 <code>setAccomplish<\/code> \u5c06 Redis \u503c\u8bbe\u4e3a <code>\"1\"<\/code> \u2192 \u5220\u9664 Stream \u6d88\u606f\u3002<\/li>\n\n\n\n<li><strong>\u5f02\u5e38\u6d41\u7a0b <\/strong>\uff1a\u82e5 <code>actualSaveShortLinkStats(...)<\/code> \u629b\u51fa\u5f02\u5e38 \u2192 \u8fdb\u5165 <code>catch<\/code> \u5757 \u2192 \u5220\u9664 Redis \u6807\u8bc6\uff08\u5141\u8bb8\u91cd\u8bd5\uff09\u3002<\/li>\n\n\n\n<li><strong>\u6f5c\u5728\u98ce\u9669 <\/strong>\uff1a<ul><li>\u82e5\u5f02\u5e38\u53d1\u751f\u5728 <code>actualSaveShortLinkStats(...)<\/code> \u6210\u529f\u540e\uff0c\u4f46 <code>delete(...)<\/code> \u5931\u8d25\u524d\uff0c\u6b64\u65f6 <code>setAccomplish(...)<\/code> \u672a\u6267\u884c\uff0cRedis \u6807\u8bc6\u4ecd\u4e3a <code>\"0\"<\/code>\uff0cMQ \u91cd\u8bd5\u65f6\u4f1a\u91cd\u65b0\u6d88\u8d39\uff0c\u4f46\u4e1a\u52a1\u903b\u8f91\u53ef\u80fd\u5df2\u90e8\u5206\u6267\u884c\uff08\u5982\u6570\u636e\u5e93\u5199\u5165\uff09\uff0c\u5bfc\u81f4\u6570\u636e\u4e0d\u4e00\u81f4<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li><strong>\u6b63\u5e38\u6d41\u7a0b <\/strong>\uff1a\u6d88\u606f\u5904\u7406\u6210\u529f \u2192 <code>setAccomplish<\/code> \u5c06 Redis \u503c\u8bbe\u4e3a <code>\"1\"<\/code> \u2192 \u5220\u9664 Stream \u6d88\u606f\u3002<\/li>\n\n\n\n<li><strong>\u5f02\u5e38\u6d41\u7a0b <\/strong>\uff1a\u82e5 <code>actualSaveShortLinkStats(...)<\/code> \u629b\u51fa\u5f02\u5e38 \u2192 \u8fdb\u5165 <code>catch<\/code> \u5757 \u2192 \u5220\u9664 Redis \u6807\u8bc6\uff08\u5141\u8bb8\u91cd\u8bd5\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6f5c\u5728\u98ce\u9669 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u82e5\u5f02\u5e38\u53d1\u751f\u5728 <code>actualSaveShortLinkStats(...)<\/code> \u6210\u529f\u540e\uff0c\u4f46 <code>delete(...)<\/code> \u5931\u8d25\u524d\uff0c\u6b64\u65f6 <code>setAccomplish(...)<\/code> \u672a\u6267\u884c\uff0cRedis \u6807\u8bc6\u4ecd\u4e3a <code>\"0\"<\/code>\uff0cMQ \u91cd\u8bd5\u65f6\u4f1a\u91cd\u65b0\u6d88\u8d39\uff0c\u4f46\u4e1a\u52a1\u903b\u8f91\u53ef\u80fd\u5df2\u90e8\u5206\u6267\u884c\uff08\u5982\u6570\u636e\u5e93\u5199\u5165\uff09\uff0c\u5bfc\u81f4\u6570\u636e\u4e0d\u4e00\u81f4\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u9a6c\u4e01\u54e5\uff0c\u6211\u89c9\u5f97\u629b\u5f02\u5e38\u7684\u8bed\u53e5\u5e94\u8be5\u5199\u5728stringRedisTemplate.opsForStream().delete(Objects.requireNonNull(stream), id.getValue()); \u8fd9\u6761\u8bed\u53e5\u4e4b\u524d\u66f4\u52a0\u5408\u7406\uff0c\u56e0\u4e3a\u6211\u89c9\u5f97\u6d88\u606f\u5220\u9664\u5c31\u5df2\u7ecf\u4ee3\u8868\u6d88\u8d39\u6210\u529f\uff0c\u4e4b\u540e\u6d88\u8d39\u8005\u4e5f\u4e0d\u4f1a\u518d\u83b7\u53d6\u5230\u6d88\u606f\u961f\u5217\u91cc\u7684\u90a3\u6761\u6d88\u606f\u4e86\uff08\u56e0\u4e3a\u5df2\u7ecf\u88ab\u5220\u9664\u4e86\uff09\uff0c\u4e4b\u540e\u518d\u629b\u5f02\u5e38\u7136\u540e\u5220\u9664\u5e42\u7b49\u6807\u8bc6\u611f\u89c9\u6ca1\u6709\u591a\u5927\u610f\u4e49<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;\u5730\u4fe1\u54e5\uff1a\u8fd9\u4e2a\u540e\u9762\u6709\u91cd\u6784\u7684\uff0c\u53ef\u4ee5\u5148\u5f80\u540e\u770b\uff0c\u5982\u679c\u6709\u95ee\u9898\u53ef\u4ee5\u5728\u91cd\u6784\u7ae0\u8282\u53cd\u9988\u3002 \u89c6\u9891\u4fee\u590d\u7ae0\u8282 9-04\uff1a\u4fee\u590d\u5e42\u7b49&amp;Redis-Stream\u6d88\u606f\u961f\u5217\u7ebf\u4e0a\u6d88\u8d39\u505c\u6b62\u95ee\u9898<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5f53\u524d\u4ee3\u7801\u903b\u8f91 <\/strong>\uff1a<code>setAccomplish(...)<\/code> \u5728 <code>try<\/code> \u5757\u672b\u5c3e\u8c03\u7528\uff0c\u786e\u4fdd\u4ec5\u5f53\u4e1a\u52a1\u903b\u8f91\u548c\u6d88\u606f\u5220\u9664\u5747\u6210\u529f\u65f6\uff0c\u624d\u6807\u8bb0\u4e3a\u5b8c\u6210\u3002<strong>\u6f5c\u5728\u7f3a\u9677 <\/strong>\uff1a\u82e5 <code>delete(...)<\/code> \u629b\u51fa\u5f02\u5e38\uff08\u5982 Redis \u8fde\u63a5\u5931\u8d25\uff09\uff0c\u4f1a\u8fdb\u5165 <code>catch<\/code> \u5757\u5220\u9664\u6807\u8bc6\uff0c\u5bfc\u81f4 MQ \u91cd\u8bd5\uff0c\u4f46\u5b9e\u9645\u6d88\u606f\u672a\u5220\u9664\uff0c\u53ef\u80fd\u91cd\u590d\u6d88\u8d39\u3002<\/li>\n\n\n\n<li><strong>\u6539\u8fdb\u65b9\u6848 <\/strong>\uff1a<strong>\u5e42\u7b49\u6807\u8bc6\u751f\u547d\u5468\u671f <\/strong>\uff1a\u8bbe\u7f6e Redis Key \u7684 TTL\uff08\u5982 2 \u5206\u949f\uff09\uff0c\u907f\u514d\u957f\u671f\u5360\u7528\u5185\u5b58\u3002<strong>\u5206\u79bb\u72b6\u6001\u66f4\u65b0\u4e0e\u6d88\u606f\u5220\u9664 <\/strong>\uff1a\u5148\u66f4\u65b0\u72b6\u6001\uff0c\u518d\u5220\u9664\u6d88\u606f\uff08\u53c2\u8003\u4e0a\u4e00\u70b9\uff09\u3002<\/li>\n\n\n\n<li><strong>\u7ed3\u8bba <\/strong>\uff1a\u9a6c\u4e01\u54e5\u7684\u5efa\u8bae\u90e8\u5206\u6b63\u786e\uff0c\u9700\u91cd\u6784\u4ee3\u7801\u786e\u4fdd\u72b6\u6001\u66f4\u65b0\u4e0e\u6d88\u606f\u5220\u9664\u7684\u539f\u5b50\u6027\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u76d1\u63a7\u7edf\u8ba1\u4e0d\u662f\u6709\u597d\u591a\u5f20\u8868\u5417,\u8bf7\u95ee,\u5982\u679c\u76d1\u63a7\u6570\u636e\u63d2\u5165\u4e86\u51e0\u5f20\u8868,\u629b\u5f02\u5e38\u4e86\u6216\u8005\u7a0b\u5e8f\u5b95\u673a\u4e86(\u5b95\u673a\u52a0\u4e8b\u52a1\u7ba1\u7528\u5417?),\u5269\u4e0b\u51e0\u5f20\u6ca1\u67e5\u76d1\u63a7\u6570\u636e,\u90a3\u4e0d\u662f\u4e0d\u6ee1\u8db3\u539f\u5b50\u6027\u5417,\u5982\u679c\u6d88\u606f\u961f\u5217\u91cd\u8bd5\u8ba9\u6d88\u8d39\u8005\u6d88\u8d39\u8fd9\u4e2a\u6d88\u606f,\u524d\u51e0\u5f20\u8868\u4e0d\u662f\u53c8\u6d88\u8d39\u4e86\u4e00\u6b21,\u6240\u4ee5\u6574\u4e2a\u63d2\u5165\u8868\u7684\u903b\u8f91(actualSaveShortLinkStats\u65b9\u6cd5)\u8981\u4e0d\u8981\u52a0\u4e8b\u52a1&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u65e0\u4e8b\u52a1\u65f6\uff0c\u90e8\u5206\u6570\u636e\u5199\u5165\u6210\u529f \u2192 MQ \u91cd\u8bd5 \u2192 \u518d\u6b21\u5199\u5165\uff0c\u5bfc\u81f4\u6570\u636e\u91cd\u590d\u6216\u4e0d\u4e00\u81f4\u3002\n<ul class=\"wp-block-list\">\n<li><strong>\u89e3\u51b3\u65b9\u6848 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u6dfb\u52a0\u4e8b\u52a1 <\/strong>\uff1a\u5728 <code>actualSaveShortLinkStats(...)<\/code> \u65b9\u6cd5\u4e0a\u6dfb\u52a0 <code>@Transactional<\/code>\uff0c\u786e\u4fdd\u539f\u5b50\u6027\u3002<\/li>\n\n\n\n<li><strong>\u8865\u507f\u673a\u5236 <\/strong>\uff1a\u82e5\u4e8b\u52a1\u4e0d\u53ef\u884c\uff0c\u9700\u8bb0\u5f55\u4e2d\u95f4\u72b6\u6001\u5e76\u5f02\u6b65\u8865\u507f\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u7ed3\u8bba <\/strong>\uff1a\u8ba8\u8bba\u8005\u6b63\u786e\u6307\u51fa\u4e8b\u52a1\u7f3a\u5931\u7684\u98ce\u9669\uff0c\u9700\u5728\u4e1a\u52a1\u903b\u8f91\u4e2d\u8865\u5145\u4e8b\u52a1\u7ba1\u7406\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c14\u8282\uff1a\u6d88\u606f\u961f\u5217\u91cd\u590d\u6d88\u8d39\u95ee\u9898\u5982\u4f55\u89e3\u51b3\uff08\u4e0b\uff09<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"YfUJe\">1. \u5982\u679c\u6d88\u8d39\u8005\u6d88\u8d39\u5931\u8d25\u4e86\u4f46\u6ca1\u6709\u6267\u884c\u5230\u5220\u9664\u6807\u8bc6\uff0c\u8be5\u600e\u4e48\u529e\uff1f<\/h3>\n\n\n\n<p>\u6bd4\u5982\u751f\u4ea7\u73af\u5883\u4e2d -9 \u76f4\u63a5\u6740\u6389redis\uff0c\u673a\u5668\u65ad\u7535\u4ec0\u4e48\u7684\uff0c\u8fd9\u65f6\u5019\u5c31\u63d0\u5230\u4e3a\u4ec0\u4e4810min\u8fc7\u671f\u4e86\uff0c<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ZDiua\">2. \u4e3a\u4ec0\u4e48\u4ec5\u8bbe\u7f6e 10 \u5206\u949f\u7684\u8fc7\u671f\u65f6\u95f4\uff1f<\/h3>\n\n\n\n<p>\u5e42\u6807\u8bc6\u6240\u5360redis\u5b58\u50a8\u7684\u95ee\u9898\uff0c\u4f60\u4e00\u65e6\u6240\u8bbe\u7f6e\u7684\u65f6\u95f4\u8fc7\u9ad8\uff0c\u4f60\u6240\u8981\u5b58\u50a8\u7684key\u7684\u6570\u91cf\u8d8a\u591a\uff0c\u56e0\u6b64\u5f02\u5e38\u91cd\u8981<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"gUFkR\">3. \u5982\u4f55\u5e94\u5bf9\u6d77\u91cf\u5e42\u7b49 Key \u6240\u6d88\u8017\u7684\u5185\u5b58\uff1f<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MySQL \u6216\u5176\u5b83\u5927\u6570\u636e\u91cf\u5b58\u50a8\u3002<\/li>\n\n\n\n<li>\u60f3\u529e\u6cd5\u6539\u9020\u6570\u636e\u3002<\/li>\n<\/ul>\n\n\n\n<p>DelayShortLinkStatsConsumer\u6dfb\u52a0\u5224\u65ad\u5f53\u524d\u7684\u8fd9\u4e2a\u6d88\u606f\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\uff0c\u5b8c\u6210\u4e86true\u5c31\u6267\u884c\uff0c\u6ca1\u6709\u5b8c\u6210\u5c31throw new ServiceException(\"\u6d88\u606f\u672a\u5b8c\u6210\u6d41\u7a0b\uff0c\u9700\u8981\u6d88\u606f\u961f\u5217\u91cd\u8bd5\");\u610f\u5473\u7740\u5982\u679c\u8bf4\u6ca1\u5b8c\u6210\uff0c\u90a3\u9700\u8981\u90a3\u4e2a\u6d88\u606f\u961f\u5217\u91cd\u590d\u7ed9\u8fd9\u4e2a\u6d88\u8d39\u8005\u8fdb\u884c\u4e0b\u653e\uff0c\u91cc\u9762\u6267\u884c\u5f02\u5e38\u4e86\uff0c\u5c31\u628a\u4e1c\u897f\u7ed9\u5220\u9664\u6389\uff0c\u6ca1\u6709\u6267\u884c\u5f02\u5e38\uff0c\u5c31\u6267\u884c\u4e3atrue\uff1b<\/p>\n\n\n\n<p>\u5982\u679c\u8bf4\u8fd9\u4e2a\u6d88\u606f\u6d88\u8d39\u5931\u8d25\u4e86\uff0crocketmq\u5728\u6d88\u8d39\u8005\u6d88\u8d39\u5931\u8d25\u7684\u60c5\u51b5\u4e0b\uff0cblock\u662f\u91cd\u590d\u4f1a\u8ba9\u6d88\u8d39\u8005\u62c9\u5230\u67d0\u4e2a\u6d88\u606f\uff0c\u6709\u4e00\u4e2a\u9636\u68af\uff0c\u51481min\uff0c2min\uff0c\u534a\u5c0f\u65f6\u4ec0\u4e48\u7684\uff0c\u4e00\u70b9\u4e00\u70b9\u7684\u3002\u90a3\u5982\u679c\u8bf4\u662f\u56e0\u4e3a\u6211\u4eec\u6ca1\u6709\u6d88\u8d39\u5b8c\uff0c\u8fd9\u91cc\u8fd9\u4e2a\u65f6\u5019\uff0c<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public void onMessage() {\n    Executors.newSingleThreadExecutor(\n                    runnable -&gt; {\n                        Thread thread = new Thread(runnable);\n                        thread.setName(\"delay_short-link_stats_consumer\");\n                        thread.setDaemon(Boolean.TRUE);\n                        return thread;\n                    })\n            .execute(() -&gt; {\n                RBlockingDeque&lt;ShortLinkStatsRecordDTO&gt; blockingDeque = redissonClient.getBlockingDeque(DELAY_QUEUE_STATS_KEY);\n                RDelayedQueue&lt;ShortLinkStatsRecordDTO&gt; delayedQueue = redissonClient.getDelayedQueue(blockingDeque);\n                for (; ; ) {\n                    try {\n                        ShortLinkStatsRecordDTO statsRecord = delayedQueue.poll();\n                        if (statsRecord != null) {\n                            if (!messageQueueIdempotentHandler.isMessageProcessed(statsRecord.getKeys())) {\n                                \/\/ \u5224\u65ad\u5f53\u524d\u7684\u8fd9\u4e2a\u6d88\u606f\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\n                                if (messageQueueIdempotentHandler.isAccomplish(statsRecord.getKeys())) {\n                                    return;\n                                }\n                                throw new ServiceException(\"\u6d88\u606f\u672a\u5b8c\u6210\u6d41\u7a0b\uff0c\u9700\u8981\u6d88\u606f\u961f\u5217\u91cd\u8bd5\");\n                            }\n                            try {\n                                shortLinkService.shortLinkStats(null, null, statsRecord);\n                            } catch (Throwable ex) {\n                                messageQueueIdempotentHandler.delMessageProcessed(statsRecord.getKeys());\n                                log.error(\"\u5ef6\u8fdf\u8bb0\u5f55\u77ed\u94fe\u63a5\u76d1\u63a7\u6d88\u8d39\u5f02\u5e38\", ex);\n                            }\n                            messageQueueIdempotentHandler.setAccomplish(statsRecord.getKeys());\n                            continue;\n                        }\n                        LockSupport.parkUntil(500);\n                    } catch (Throwable ignored) {\n                    }\n                }\n            });\n}<\/pre>\n\n\n\n<p>&nbsp;\u90a3\u4e48MessageQueueIdempotentHandler\u91cc\u9762\u7684\u6dfb\u52a0\u5982\u4e0b\u51fd\u6570\uff1b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">private static final String IDEMPOTENT_KEY_PREFIX = \"short-link:idempotent:\";\n\n\/**\n * \u5224\u65ad\u5f53\u524d\u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n *\n * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n * @return \u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n *\/\npublic boolean isMessageProcessed(String messageId) {\n    String key = IDEMPOTENT_KEY_PREFIX + messageId;\n    return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, \"0\", 2, TimeUnit.MINUTES));\n}\n\n\/**\n * \u5224\u65ad\u6d88\u606f\u6d88\u8d39\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\n *\n * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n * @return \u6d88\u606f\u662f\u5426\u6267\u884c\u5b8c\u6210\n *\/\npublic boolean isAccomplish(String messageId) {\n    String key = IDEMPOTENT_KEY_PREFIX + messageId;\n    return Objects.equals(stringRedisTemplate.opsForValue().get(key), \"1\");\n}\n\n\/**\n * \u8bbe\u7f6e\u6d88\u606f\u6d41\u7a0b\u6267\u884c\u5b8c\u6210\n *\n * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n *\/\npublic void setAccomplish(String messageId) {\n    String key = IDEMPOTENT_KEY_PREFIX + messageId;\n    stringRedisTemplate.opsForValue().set(key, \"1\", 2, TimeUnit.MINUTES);\n}\n\n\/**\n * \u5982\u679c\u6d88\u606f\u5904\u7406\u9047\u5230\u5f02\u5e38\u60c5\u51b5\uff0c\u5220\u9664\u5e42\u7b49\u6807\u8bc6\n *\n * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n *\/\npublic void delMessageProcessed(String messageId) {\n    String key = IDEMPOTENT_KEY_PREFIX + messageId;\n    stringRedisTemplate.delete(key);\n}<\/pre>\n\n\n\n<p>return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, \"0\", 2, TimeUnit.MINUTES));\u91cc\u97620\u4ee3\u8868\u6267\u884c\u4e2d\uff0c1\u4ee3\u8868\u5df2\u5b8c\u6210\uff0c\u8fdb\u4e00\u6b65\u8865\u5145\u6b64\u6587\u4ef6;<\/p>\n\n\n\n<p>\u662f0\u7684\u8bdd\u5c31\u4f1a\u4e0d\u65ad\u7684\u629b\u5f02\u5e38\uff1b10\u5206\u949f\u5b9e\u8df5\u6211\u4eec\u8fd9\u91cc\u4ed6\u5728\u62c9\u6765\u6d88\u606f\u7684\u65f6\u5019\uff0cRedis\u91cc\u9762\u5c31\u6ca1\u6709\u8fd9\u4e2a\u6807\u8bc6\u4e86\uff0c\u6ca1\u6709\u6807\u8bc6\u540e\u5c31\u80fd\u591f\u6b63\u5e38\u6d88\u8d39<\/p>\n\n\n\n<p>\u9664\u4e86\u6211\u4eec\u7528Redis\u53bb\u5b9e\u73b0mysql\u4e5f\u80fd\u5b9e\u73b0\uff0c<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.mq.idempotent;\n\n\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Objects;\nimport java.util.concurrent.TimeUnit;\n\n\/**\n * \u6d88\u606f\u961f\u5217\u5e42\u7b49\u5904\u7406\u5668\n *\/\n@Component\n@RequiredArgsConstructor\npublic class MessageQueueIdempotentHandler {\n\n    private final StringRedisTemplate stringRedisTemplate;\n\n    private static final String IDEMPOTENT_KEY_PREFIX = \"short-link:idempotent:\";\n\n    \/**\n     * \u5224\u65ad\u5f53\u524d\u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     * @return \u6d88\u606f\u662f\u5426\u6d88\u8d39\u8fc7\n     *\/\n    public boolean isMessageProcessed(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        return Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(key, \"0\", 2, TimeUnit.MINUTES));\n    }\n\n    \/**\n     * \u5224\u65ad\u6d88\u606f\u6d88\u8d39\u6d41\u7a0b\u662f\u5426\u6267\u884c\u5b8c\u6210\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     * @return \u6d88\u606f\u662f\u5426\u6267\u884c\u5b8c\u6210\n     *\/\n    public boolean isAccomplish(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        return Objects.equals(stringRedisTemplate.opsForValue().get(key), \"1\");\n    }\n\n    \/**\n     * \u8bbe\u7f6e\u6d88\u606f\u6d41\u7a0b\u6267\u884c\u5b8c\u6210\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     *\/\n    public void setAccomplish(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        stringRedisTemplate.opsForValue().set(key, \"1\", 2, TimeUnit.MINUTES);\n    }\n\n    \/**\n     * \u5982\u679c\u6d88\u606f\u5904\u7406\u9047\u5230\u5f02\u5e38\u60c5\u51b5\uff0c\u5220\u9664\u5e42\u7b49\u6807\u8bc6\n     *\n     * @param messageId \u6d88\u606f\u552f\u4e00\u6807\u8bc6\n     *\/\n    public void delMessageProcessed(String messageId) {\n        String key = IDEMPOTENT_KEY_PREFIX + messageId;\n        stringRedisTemplate.delete(key);\n    }\n}\n<\/pre>\n\n\n\n<p>&nbsp;delreq\u6ca1\u6709\u6d88\u606fid\u554a\uff0c\u56e0\u6b64\u5728shortLinkStatsRecordDTO\u91cc\u9762\u6dfb\u52a0\u4e00\u4e2a\u6d88\u606f\u961f\u5217keys<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>&nbsp;\u9cb8\uff1a\u8fd9\u91cc\u77ed\u8fde\u63a5\u7edf\u8ba1\u65f6\u51fa\u73b0\u5f02\u5e38catch\u540e\uff0c\u53ea\u6253\u5370\u9519\u8bef\u65e5\u5fd7\u597d\u50cf\u5e76\u4e0d\u4f1a\u91cd\u65b0\u53bb\u6d88\u8d39\uff0c\u6211\u5c1d\u8bd5\u7684\u629b\u51fa\u5f02\u5e38\u624d\u4f1a\u8fdb\u884c\u91cd\u8bd5<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4ee3\u7801\u903b\u8f91 <\/strong>\uff1a\u5f53\u524d <code>catch<\/code> \u5757\u4e2d\u4ec5\u5220\u9664 Redis \u6807\u8bc6\uff0c\u672a\u629b\u51fa\u5f02\u5e38\uff0c\u5bfc\u81f4 MQ \u8ba4\u4e3a\u6d88\u8d39\u6210\u529f\uff08\u81ea\u52a8 ACK\uff09\uff0c\u6d88\u606f\u4e0d\u4f1a\u91cd\u8bd5\u3002\u9700\u5728 <code>catch<\/code> \u4e2d\u629b\u51fa\u5f02\u5e38\uff08\u5982 <code>ServiceException<\/code>\uff09\uff0c\u89e6\u53d1 MQ \u91cd\u8bd5\u673a\u5236\u3002<\/li>\n<\/ul>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;\u9cb8\uff1a\u8fd9\u91cc\u4f7f\u7528 redis stream \u662f\u6536\u5230\u5373\u711a\u7684\u54c7\uff1fuu \u600e\u4e48\u6d4b\u51fa\u91cd\u8bd5\u7684\uff1f<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u81ea\u52a8 ACK \u7684\u98ce\u9669 <\/strong>\uff1a\u6d88\u606f\u62c9\u53d6\u540e\u7acb\u5373\u88ab\u786e\u8ba4\uff0c\u82e5\u6d88\u8d39\u5931\u8d25\uff0cMQ \u4e0d\u4f1a\u91cd\u8bd5\uff08\u6d88\u606f\u5df2\u5220\u9664\uff09\u3002\u4f7f\u7528\u624b\u52a8 ACK\uff0c\u5728\u6d88\u8d39\u5b8c\u6210\u540e\u663e\u5f0f\u786e\u8ba4\uff0c\u907f\u514d\u6d88\u606f\u4e22\u5931\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u738b\u5c0f\u660e\uff1a\u6211\u600e\u4e48\u89c9\u5f97\uff0c\u5728\u6d88\u8d39\u6210\u529f\u540e\uff0c\u76f4\u63a5\u8bbe\u7f6e\u4e00\u4e2a\u6210\u679c\u6807\u8bc6\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u9700\u8981\u5904\u7406\u7684\u8fd9\u4e48\u590d\u6742\u3002\u5148\u5224\u65ad\u6210\u529f\u6807\u8bc6\u662f\u5426\u5b58\u5728 \u5373hasKey\uff0c\u4e0d\u5b58\u5728\u5219\u8fdb\u884c\u6d88\u8d39\uff0c\u6d88\u8d39\u5b8csetAccomplish<\/p>\n\n\n\n<p>Apricity\ud83c\udf24&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u6211\u4e5f\u8fd9\u4e48\u89c9\u5f97\uff0c\u5e94\u8be5\u5728\u6d88\u8d39\u6210\u529f\u540e\u8bbe\u7f6e\u6807\u8bc6\uff0c\u800c\u4e0d\u662f\u6d88\u8d39\u5f00\u59cb\u7684\u65f6\u5019\u8bbe\u7f6e\u6807\u8bc6<\/p>\n\n\n\n<p>\u5c11\u00b7\u7fbd&nbsp;\u56de\u590d&nbsp;Apricity\ud83c\udf24\uff1a\u4f46\u662f\u5c31\u4f1a\u51fa\u73b0\u91cd\u590d\u6d88\u8d39\u554a\uff0c\u4f60\u662f\u6d88\u8d39\u6210\u529f\u4e86\u624d\u8bbe\u7f6e\uff0c\u90a3\u4e48\u5c31\u4f1a\u6709\u597d\u591a\u4e2a\u540c\u65f6\u8fdb\u5165\u4e86\u6d88\u8d39\u7a0b\u5e8f\uff0c\u90a3\u4e48\u5c31\u76f8\u5f53\u4e8e\u5c06\u5224\u65ad\u538b\u529b\u7ed9\u5230\u4e86\u6570\u636e\u5e93\u8fd9\u8fb9\u4e86<\/p>\n\n\n\n<p>\u81ea\u7531\u5982\u98ce&nbsp;\u56de\u590d&nbsp;\u5c11\u00b7\u7fbd\uff1a\u91cd\u590d\u6d88\u8d39?\u5e94\u8be5\u4e0d\u4f1a\uff0c\u56e0\u4e3a\u62c9\u53d6\u6d88\u606f\u7684\u65f6\u5019\u90fd\u662f\u5355\u7ebf\u7a0b\uff0c\u4e24\u4e2a\u8fde\u63a5\u62ff\u5230\u7684\u662f\u4e0d\u540c\u5f97\u6d88\u606f<\/p>\n\n\n\n<p>ymf&nbsp;\u56de\u590d&nbsp;\u738b\u5c0f\u660e\uff1a\u4e2a\u4eba\u7406\u89e3\u77db\u76fe\u70b9\u4e3b\u8981\u5728\u4e8e\u5982\u4f55\u662f\u5426catch\u6d88\u8d39\u5f02\u5e38\uff0c\u5982\u679c\u6ca1\u6709catch\u5f02\u5e38\uff0c\u90a3\u4e48\u8fd9\u4e2a\u5f02\u5e38\u4f1a\u4e0d\u65ad\u88ab\u629b\u51fa\uff0c\u59a8\u788d\u6267\u884c\uff1b\u4f46\u5b9e\u9645\u4e0a\u8fd9\u4e2a\u6d88\u8d39\u5f02\u5e38\u53ef\u4ee5\u5728\u8be5\u65b9\u6cd5\u5185\u90e8catch\u5230\u6765\u8fdb\u884c\u89e3\u51b3\uff0c\u5982\u6709\u4e0d\u5bf9\u8bf7\u6307\u6b63\u3002<\/p>\n\n\n\n<p>INSIST&nbsp;\u56de\u590d&nbsp;ymf\uff1a\u6709\u6ca1\u6709\u8fd9\u4e2a\u53ef\u80fd\uff0c\u521a\u597d\u6d88\u8d39\u5b8c\u6210\uff0c\u8fd8\u6ca1\u6765\u5f97\u53ca\u8bbe\u7f6e\u6d88\u8d39\u6210\u529f\u6807\u8bc6\uff0c\u6b64\u65f6\u5b95\u673a\uff0c\u90a3\u4e48\u518d\u6b21\u6295\u653e\u6d88\u606f\u65f6\u5c31\u7b49\u4e8e\u6d88\u8d39\u4e86\u4e24\u6b21\uff0c\u8fd9\u8be5\u548b\u529e\u3002<\/p>\n\n\n\n<p>rebcaaaaaa*&nbsp;\u56de\u590d&nbsp;INSIST\uff1a\u9a6c\u54e5\u7684\u4ee3\u7801\u4e5f\u4e0d\u80fd\u5904\u7406\u8fd9\u79cd\u60c5\u51b5\u5427\uff0c\u603b\u7684\u6765\u8bf4\u6211\u611f\u89c9\u8fd9\u79cd\u601d\u8def\u7b80\u5316\u4e86\u5f88\u591a\uff0c\u6548\u679c\u4e5f\u5dee\u4e0d\u591a\u3002\u6211\u89c9\u5f97\u9a6c\u54e5\u7684\u4ee3\u7801\u53ef\u4ee5\u628a\u672a\u5b8c\u6210\u76f4\u63a5\u629b\u5f02\u5e38\u91cd\u8bd5\u90a3\u6bb5\u5220\u4e86\uff0c\u672a\u5b8c\u6210\u5c31\u7ee7\u7eed\u5f80\u4e0b\u8fdb\u884c\u6d88\u8d39\uff0c\u76f4\u63a5\u5b8c\u6210\u4e3a\u6b62\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u4e00\u76f4\u91cd\u8bd5\u4e86\uff0c\u53cd\u6b63\u6700\u7ec8\u90fd\u8fd8\u662f\u8981\u6d88\u8d39\u5b8c\u6210\u7684\u3002\u8fd9\u6837\u6574\u4f53\u4e0a\u5c31\u8ddf\u697c\u4e3b\u7684\u601d\u8def\u5dee\u4e0d\u591a\u4e86<\/p>\n\n\n\n<p>\u767d\u65e5\u68a6\u60f3\u5bb6&nbsp;\u56de\u590d&nbsp;rebcaaaaaa*\uff1a\u8d5e\u540c\u3002\u770b\u4e86\u4e00\u4e0b\u8fd9\u5c42\u4e0b\u9762\u7684\u56de\u7b54\uff0c\u611f\u89c9\u8bbe\u7f6e\u9884\u5360\u6807\u8bc6\u786e\u5b9e\u6709\u70b9\u591a\u6b64\u4e00\u4e3e\u3002\u76f4\u63a5\u6d88\u8d39\u5b8c\u6210\u4e4b\u540e\u8bbe\u7f6e\u4e00\u4e2a\u5b8c\u6210\u6807\u8bc6\u5c31\u884c<\/p>\n\n\n\n<p>Best HL&nbsp;\u56de\u590d&nbsp;\u767d\u65e5\u68a6\u60f3\u5bb6\uff1a\u5982\u679c\u4e00\u4e2a\u6d88\u606f\u6b63\u5728\u6d88\u8d39\uff0c\u5df2\u7ecf\u628a\u8bfb\u5199\u9501\u91ca\u653e\u4f46\u8fd8\u6ca1\u6709\u8bbe\u7f6e\u5b8c\u6210\u6807\u8bc6\u7684\u65f6\u5019\uff0c\u7136\u540e\u6b64\u6d88\u606f\u53c8\u91cd\u65b0\u6295\u9012\uff0c\u5982\u679c\u6ca1\u6709\u9884\u5360\u6807\u8bc6\uff0c\u8fd9\u4e2a\u6d88\u606f\u5224\u65ad\u6ca1\u6709\u5b8c\u6210\u6807\u8bc6\u5c31\u4f1a\u518d\u6b21\u88ab\u6d88\u8d39\uff0c\u5f15\u8d77\u5e42\u7b49\u95ee\u9898\u3002\u4f46\u662f\u91cd\u590d\u7684\u6d88\u606f\u4ec0\u4e48\u65f6\u5019\u4f1a\u6295\u9012\uff0c\u6d88\u8d39\u65f6\u95f4\u8fc7\u957f\u4f1a\u4e0d\u4f1a\u81ea\u52a8\u518d\u6b21\u6295\u9012\u4e00\u6b21\uff0c\u5982\u679c\u4f1a\u7684\u8bdd\u611f\u89c9\u662f\u9700\u8981\u8bbe\u7f6e\u4e00\u4e2a\u9884\u5360\u6807\u8bc6\u7684\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u65b9\u6848 <\/strong>\uff1a<code>setAccomplish<\/code> \u65b9\u6cd5\u4e2d\u68c0\u67e5 Redis \u503c\u662f\u5426\u4e3a \"0\"\uff0c\u518d\u8bbe\u7f6e\u4e3a \"1\"\uff0c\u907f\u514d\u8986\u76d6\u5f02\u5e38\u72b6\u6001\u3002<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u2705 <strong>\u90e8\u5206\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u4f18\u52bf <\/strong>\uff1a\u9632\u6b62\u5728\u5f02\u5e38\u5904\u7406\u4e2d\u9519\u8bef\u6807\u8bb0\u4e3a\u5b8c\u6210\uff08\u5982\u6807\u8bc6\u5df2\u88ab\u5220\u9664\uff09\u3002<\/li>\n\n\n\n<li><strong>\u7f3a\u9677 <\/strong>\uff1a\u672a\u89e3\u51b3\u5b95\u673a\u53d1\u751f\u5728 <code>setAccomplish<\/code> \u4e4b\u524d\u7684\u573a\u666f\uff08\u5982\u6807\u8bc6\u5df2\u5199\u5165\u6570\u636e\u5e93\u4f46\u672a\u66f4\u65b0 Redis\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Drano \ud83c\udf1d \u7684\u5efa\u8bae <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u65b9\u6848 <\/strong>\uff1a\u5c06 <code>setAccomplish<\/code> \u79fb\u51fa <code>finally<\/code>\uff0c\u5728 <code>catch<\/code> \u4e2d\u629b\u51fa\u5f02\u5e38\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>&nbsp;\u4e00\u5f00\u59cbredis\u4e2d\u521b\u5efakey\uff0c \u503c\u4e3a0\uff0c\u7136\u540e\u629b\u51fa\u5f02\u5e38\u8fd9\u91cccatch\u4e4b\u540e\uff0c\u4f1a\u5c06\u5f53\u524dkey\u5220\u9664\uff0c\u6700\u540e\u8fd8\u662f\u4f1a\u6267\u884c\u4e00\u4e2asetAccomplish\uff0c\u4e5f\u5c31\u662f\u5c06key\u8bbe\u7f6e\u62101\uff0c\u56e0\u4e3a\u6211\u4eec\u5df2\u7ecf\u5220\u9664\u4e86\uff0c\u6240\u4ee5\u5c31\u7b97key\u4e0d\u5b58\u5728\u4e5f\u4f1a\u5c06key\u8bbe\u7f6e\u62101\uff0c\u6240\u4ee5\u4e0b\u6b21\u91cd\u8bd5\u7684\u65f6\u5019\uff0c\u5c31\u4f1a\u5224\u65ad\u5230\u503c\u4e3a1\uff0c\u6240\u4ee5\u5c31\u4e0d\u4f1a\u91cd\u8bd5\u4e86 \u8fd9\u662f\u6211\u6539\u8fdb\u4e4b\u540e\u7684\u4ee3\u7801\uff0c\u5728\u8bbe\u7f6e\u5b8c\u6210\u4e4b\u524d\u5224\u65ad\u503c\u662f\u4e0d\u662f\u4e3a0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void setAccomplish(String id) {\n    String key = IDEMPOTENT_REDIS_KEY + id;\n    if (Objects.equals(stringRedisTemplate.opsForValue().get(key), \"0\")){ \n        stringRedisTemplate.opsForValue() .set(key, \"1\", 2, TimeUnit.MINUTES);\n    }\n}<\/code><\/pre>\n\n\n\n<p>champagnep*&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u4e3a\u5565\u8fd8\u4f1a\u6267\u884c\u4e00\u4e2asetAccomplish<\/p>\n\n\n\n<p>\u4e00\u53ea\u9c7c&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u6817\u5b50\u54e5\uff0c\u4f60\u6709\u81ea\u5df1\u8bb0\u77ed\u94fe\u63a5\u7684\u7b14\u8bb0\u561b\uff1f<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u6b63\u5e38\u6765\u8bf4\u5e94\u8be5\u5728 catch \u4e2d\u5c06\u5f02\u5e38 throw \u51fa\u53bb<\/p>\n\n\n\n<p>Drano \ud83c\udf1d&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u628asetAccomplish\u65b9\u6cd5\u79fb\u51fafinally\uff0c\u7136\u540e\u5728catch\u91cc\u629b\u51fa\u5f02\u5e38\u4e5f\u53ef\u4ee5\u5427<\/p>\n\n\n\n<p>\u6817\u5b50ing&nbsp;\u56de\u590d&nbsp;Drano \ud83c\udf1d\uff1a\u76f4\u63a5\u629b\u5f02\u5e38\u5c31\u53ef\u4ee5\uff0c\u4e0d\u9700\u8981\u79fb\u5230finally\u91cc<\/p>\n\n\n\n<p>Everglow&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u5df2\u7ecf\u629b\u51fa\u5f02\u5e38\u4e86\u80af\u5b9a\u4e0d\u4f1a\u5f80\u4e0b\u9762\u6267\u884c\u4e86\u5427<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;champagnep*\uff1acatch \u6355\u83b7\u5f02\u5e38\u540e\uff0c\u7a0b\u5e8f\u4f1a\u7ee7\u7eed\u5f80\u4e0b\u6267\u884c<\/p>\n\n\n\n<p>\u809a\u5706\u5706&nbsp;\u56de\u590d&nbsp;\u6817\u5b50ing\uff1a\u90a3\u80fd\u4e0d\u80fd\u76f4\u63a5\u5728try\u91cc\u9762\u6267\u884csetAccomplish\u5c31\u597d<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u65b9\u6848 <\/strong>\uff1a<code>setAccomplish<\/code> \u65b9\u6cd5\u4e2d\u68c0\u67e5 Redis \u503c\u662f\u5426\u4e3a \"0\"\uff0c\u518d\u8bbe\u7f6e\u4e3a \"1\"\uff0c\u907f\u514d\u8986\u76d6\u5f02\u5e38\u72b6\u6001\u3002<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u2705 <strong>\u90e8\u5206\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u4f18\u52bf <\/strong>\uff1a\u9632\u6b62\u5728\u5f02\u5e38\u5904\u7406\u4e2d\u9519\u8bef\u6807\u8bb0\u4e3a\u5b8c\u6210\uff08\u5982\u6807\u8bc6\u5df2\u88ab\u5220\u9664\uff09\u3002<\/li>\n\n\n\n<li><strong>\u7f3a\u9677 <\/strong>\uff1a\u672a\u89e3\u51b3\u5b95\u673a\u53d1\u751f\u5728 <code>setAccomplish<\/code> \u4e4b\u524d\u7684\u573a\u666f\uff08\u5982\u6807\u8bc6\u5df2\u5199\u5165\u6570\u636e\u5e93\u4f46\u672a\u66f4\u65b0 Redis\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Drano \ud83c\udf1d \u7684\u5efa\u8bae <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u65b9\u6848 <\/strong>\uff1a\u5c06 <code>setAccomplish<\/code> \u79fb\u51fa <code>finally<\/code>\uff0c\u5728 <code>catch<\/code> \u4e2d\u629b\u51fa\u5f02\u5e38\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>&nbsp;\u5982\u679c\u6d88\u8d39\u6210\u529fsetAccomplish\u540e\uff0c\u7b49\u5230\u8fc7\u671f\u65f6\u95f4\u8fc7\u4e86\uff0c\u53c8\u8fdb\u6765\u4e00\u4e2a\u4e4b\u524d\u6d88\u8d39\u8fc7\u7684\u6570\u636e\u600e\u4e48\u529e\uff1f\u6709\u8fd9\u79cd\u53ef\u80fd\u4e48\uff1f\u6d88\u606f\u961f\u5217\u4e2d\uff0c\u5982\u679c\u4e00\u4e2a\u6d88\u606f\u5df2\u7ecf\u88ab\u6d88\u8d39\u6210\u529f\u4e86\uff0c\u7406\u8bba\u4e0a\u4e0d\u4f1a\u91cd\u65b0\u53d1\u9001\u8fd9\u6761\u6d88\u606f\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u8ba8\u8bba\u7126\u70b9 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u6d88\u606f\u5df2\u6807\u8bb0\u4e3a\u5b8c\u6210\uff08\"1\"\uff09\u4e14 Redis Key \u8fc7\u671f\u540e\uff0c\u76f8\u540c\u6d88\u606f\u662f\u5426\u4f1a\u88ab\u91cd\u65b0\u6d88\u8d39\uff1f<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u2705 <strong>\u5b8c\u5168\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u903b\u8f91\u5206\u6790 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u8fc7\u671f\u540e Redis Key \u4e0d\u5b58\u5728\uff0c\u6d88\u606f ID \u53ef\u518d\u6b21\u901a\u8fc7 <code>isMessageProcessed<\/code> \u9884\u5360\u6807\u8bc6\uff08\"0\"\uff09\u8fdb\u5165\u6d88\u8d39\u6d41\u7a0b\u3002<\/li>\n\n\n\n<li><strong>\u98ce\u9669 <\/strong>\uff1a\u82e5\u6d88\u606f ID \u5168\u5c40\u552f\u4e00\u4e14\u4ec5\u5355\u6b21\u6709\u6548\uff0c\u6b64\u8bbe\u8ba1\u4f1a\u5bfc\u81f4\u91cd\u590d\u6d88\u8d39\uff1b\u82e5\u6d88\u606f ID \u53ef\u91cd\u590d\uff08\u5982\u4e1a\u52a1\u903b\u8f91\u5173\u8054\u552f\u4e00\u952e\uff09\uff0c\u9700\u989d\u5916\u6821\u9a8c\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6539\u8fdb\u5efa\u8bae <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u6d88\u606f ID \u8bbe\u8ba1 <\/strong>\uff1a\u786e\u4fdd\u5168\u5c40\u552f\u4e00\u6027\uff0c\u6216\u5173\u8054\u4e1a\u52a1\u552f\u4e00\u952e\uff08\u5982\u8ba2\u5355\u53f7\uff09\u3002<\/li>\n\n\n\n<li><strong>\u72b6\u6001\u6301\u4e45\u5316 <\/strong>\uff1a\u5c06\u5e42\u7b49\u6807\u8bc6\u843d\u5e93\uff0c\u907f\u514d Redis \u8fc7\u671f\u540e\u4e22\u5931\u72b6\u6001\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>RQTN\uff1a\u8fd9\u4e00\u8282\u7ed9\u6211\u770b\u61f5\u903c\u4e86\uff0c\u6211\u611f\u89c9\u771f\u8981\u8bb2\u6d88\u606f\u961f\u5217\u6d88\u8d39\u5e42\u7b49\u7684\u8bdd\uff0c\u5e94\u8be5\u8981\u7ed3\u5408 ack \u6765\u8bb2\u5427\u3002 \u50cf\u8fd9\u4e00\u8282\u672b\u5c3e\u7684\u5ef6\u65f6\u961f\u5217\uff0c\u5176\u5b9e\u5b8c\u5168\u6ca1\u5fc5\u8981\u52a0\u5e42\u7b49\uff0c\u56e0\u4e3a\u5ef6\u65f6\u961f\u5217 poll \u51fa\u6765\uff0c\u6d88\u606f\u5728redis\u4e2d\u5176\u5b9e\u5c31\u6ca1\u6709\u4e86\uff0c\u9605\u540e\u5373\u711a\uff0c\u4e0d\u5b58\u5728\u91cd\u590d\u6295\u9012\u7684\u53ef\u80fd\u6027\uff0c\u4e0d\u5fc5\u518d\u52a0\u5e42\u7b49\u4e86\u3002 \u518d\u6bd4\u5982\u8fd9\u4e00\u8282\u63d0\u5230\u7684 Redis Stream\uff0c\u5176\u5b9e Redis Stream \u662f\u6709 ack \u673a\u5236\u7684\uff0c\u4f46\u662f\u9a6c\u54e5\u7528\u7684\u662f auto ack\uff0c\u76f8\u5f53\u4e8e\u6d88\u606f\u4e5f\u662f\u9605\u540e\u5373\u711a\u4e86\uff0c\u4e5f\u4e0d\u5b58\u5728\u91cd\u590d\u6295\u9012\u7684\u53ef\u80fd\u6027\u4e86\uff0c\u81ea\u7136\u4e5f\u4e0d\u5fc5\u518d\u52a0\u5e42\u7b49\u4e86\u3002 \u6700\u540e\u8fd9\u91cc\u8bb2\u5e42\u7b49\uff0c\u56e0\u4e3a\u6ca1\u6709 ack \u8bb2\u5f97\u4e5f\u6bd4\u8f83\u5947\u602a\uff0c\u6bd4\u5982\u4e3a\u4ec0\u4e48\u5e42\u7b49\u6807\u8bc6\u5b58\u5728\u4ee5\u540e\uff0c\u8fd8\u9700\u8981\u989d\u5916\u5224\u65ad\u4e00\u4e0b\u662f\u5426\u6d88\u8d39\u6210\u529f\uff0c\u4e00\u4e2a\u76f4\u63a5return\uff0c\u4e00\u4e2a\u629b\u5f02\u5e38\uff0c\u4e0d\u90fd\u662f\u63d0\u524d\u8fd4\u56de\u5417\uff1f\u770b\u8d77\u6765\u989d\u5916\u5224\u65ad\u662f\u5426\u6d88\u8d39\u6210\u529f\u662f\u591a\u4f59\u7684\uff0c\u4f46\u8fd9\u4e2a\u95ee\u9898\u6211\u662f\u770b\u4e86 12306 \u5e42\u7b49\u90a3\u5757\u624d\u5927\u81f4\u660e\u767d\uff0c\u76f8\u5f53\u4e8e\u662f\u6574\u4e2a onMessage \u65b9\u6cd5\u5916\u9762\u8fd8\u5305\u4e86\u4e00\u5c42\uff0cMQ\u629b\u5f02\u5e38\u5c31\u4e0d\u4f1a\u8fd4\u56de ack \u4ece\u800c\u4f1a\u8ba9 MQ \u91cd\u65b0\u53bb\u6295\u9012\u6d88\u606f\uff0c\u6b63\u5e38return\u4f1a\u8fd4\u56de ack\uff0cMQ \u5c31\u4e0d\u4f1a\u91cd\u65b0\u6295\u9012\u4e86\u3002<\/p>\n\n\n\n<p>\u5403\u4e2a\u6708\u997c&nbsp;\u56de\u590d&nbsp;RQTN\uff1a\u8fd9\u4e2aauto ack\u662f\u4e0d\u662f\u62ff\u5230\u6d88\u606f\u5c31\u53d1\u9001\u4e86ACK\u554a\uff0c\u6ca1\u6709\u7b49\u5230onMessage\u6267\u884c\u5b8c\uff0c\u90a3\u611f\u89c9\u6f0f\u6d1e\u8fd8\u633a\u591a\u7684\uff0c\u5982\u679c\u6d88\u8d39\u8fc7\u7a0b\u4e2d\u51fa\u4e86\u95ee\u9898\uff0c\u90a3\u8fd9\u4e2a\u6d88\u606f\u4e0d\u5c31\u4e0d\u4f1a\u52a0\u5165\u5230Pending\u5217\u8868\u4e2d\u4e86<\/p>\n\n\n\n<p>RQTN&nbsp;\u56de\u590d&nbsp;\u5403\u4e2a\u6708\u997c\uff1a\u662f\u7684\uff0c\u76f8\u5f53\u4e8e\u6d88\u606f\u9605\u540e\u5373\u711a\uff0c\u4ee5 auto ack \u65b9\u5f0f\u53bb\u8bfb\u53d6\u6d88\u606f\u7684\u8bdd\uff0c\u6d88\u606f\u4e0d\u4f1a\u989d\u5916\u5728 PEL \u4e2d\u989d\u5916\u5b58\u4e00\u4efd\u3002<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;\u5403\u4e2a\u6708\u997c\uff1a\u5bf9 \u5c31\u662f\u9605\u540e\u5373\u711a \u5982\u679c\u7528\u7684\u65f6\u5019\u51fa\u95ee\u9898\u4e86 \u90a3\u5c31\u76f4\u63a5\u4e22\u6570\u636e\u4e86<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;RQTN\uff1a\u6700\u597d\u4e0d\u8981 auto ack \u5427\uff01\u9605\u540e\u5373\u711a\u7684\u8bdd\u5982\u679c\u51fa\u5f02\u5e38\u6d88\u606f\u76f4\u63a5\u5c31\u4e22\u5931\u4e86\uff0c\u8fd8\u662f\u5f97\u5b8c\u6210\u6d88\u8d39\u540e\u624b\u52a8 acknowledge\u3002\u611f\u89c9\u4f7f\u7528 redis stream \u9632\u91cd\u590d\u6d88\u8d39\uff0c\u4e3b\u8981\u9700\u8981\u8003\u8651 redis \u5b95\u673a\u3001\u4e91\u670d\u52a1\u5668\u5b95\u673a\u5c31\u591f\u4e86\uff0credis stream \u673a\u5236\u4e0b\u4e0d\u9700\u8981\u8fc7\u591a\u62c5\u5fc3\u3010\u91cd\u590d\u6d88\u8d39\u3011\u95ee\u9898\uff0c\u53cd\u800c\u9700\u8981\u5173\u6ce8\u3010\u6d88\u606f\u4e22\u5931\u3011\u95ee\u9898\u3002<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;RQTN\uff1aredis stream \u6d88\u8d39\u8005\u5728 onMessage \u4e2d\u629b\u51fa\u5f02\u5e38\u4f1a\u5bfc\u81f4\u91cd\u65b0\u6295\u9012\u6d88\u606f\u5417\uff1f\u4e3a\u4ec0\u4e48\u6211\u8fd9\u91cc\u6a21\u62df\u4e0d\u51fa\u6765\uff0c\u4e00\u65e6\u629b\u51fa\u5f02\u5e38\u5c31\u50cf\u6302\u4e86\u4e00\u6837\u3002<\/p>\n\n\n\n<p>kidult&nbsp;\u56de\u590d&nbsp;TheTurtle\uff1a\u9a6c\u54e5\u8fd9\u91cc\u5bf9redis \u505a\u6d88\u606f\u961f\u5217\u7684\u539f\u7406\u7684\u7406\u89e3\u6211\u4e2a\u4eba\u611f\u89c9\u662f\u6709\u95ee\u9898\u7684\uff0c\u8fd9\u91cc\u9a6c\u54e5\u7528\u7684\u662fauto ack\u4e00\u65e6\u6536\u5230\u4e86\u6d88\u606f\u4f1a\u81ea\u52a8\u786e\u8ba4\u6d88\u606f\uff0c\u7136\u540e\u8fd9\u4e2a\u6d88\u606f\u5c31\u518d\u4e5f\u6536\u4e0d\u5230\u4e86 \u5982\u679c\u662f\u624b\u52a8ack\u7684\u8bdd\uff0c\u672aack\u7684\u6d88\u606f\u662f\u4f1a\u653e\u5230\u4e00\u4e2apending_list\u91cc\uff0c\u9664\u975e\u6307\u5b9a\u4ece\u8fd9\u4e2a\u961f\u5217\u91cc\u53d6\uff0credis\u662f\u4e0d\u4f1a\u4e3b\u52a8\u5bf9\u8fd9\u4e2a\u961f\u5217\u91cc\u7684\u6d88\u606f\u8fdb\u884c\u6295\u9012\u7684\u3002 \u9664\u5f00\u7f51\u7edc\u6296\u52a8\u51fa\u73b0\u628a\u4e00\u4e2a\u6d88\u606f\u51e0\u4e4e\u540c\u65f6\u6295\u9001\u4e24\u904d\u8fd9\u79cd\u60c5\u51b5\uff0credis\u662f\u4e0d\u4f1a\u628a\u4e00\u4e2a\u672aack\u7684\u6d88\u606f\u8fdb\u884c\u4e8c\u6b21\u6295\u9012<\/p>\n\n\n\n<p>\u665f&nbsp;\u56de\u590d&nbsp;RQTN\uff1a\u81ea\u52a8ack\u4e5f\u662f\u9700\u8981\u52a0\u5e42\u7b49\u7684\u554a\uff0c\u867d\u7136\u9605\u540e\u5373\u711a\uff0c\u4f46\u662f\u4f60\u80fd\u4fdd\u8bc1\u6d88\u8d39\u8005\u7ec4\u91cc\u9762\u591a\u4e2a\u5b9e\u4f8b\u4e0d\u4f1a\u62c9\u53d6\u5230\u540c\u4e00\u6761\u6d88\u606f\u5417\uff1f\u4f46\u662f\u597d\u50cf\u8fd9\u91cc\u6ca1\u6709\u89e3\u51b3\u751f\u4ea7\u8005\u91cd\u8bd5\u673a\u5236\uff1aredis stream\u4e2d\u53ef\u80fd\u6709\u4e24\u6761\u76f8\u540c\u7684\u6d88\u606f\uff08\u5185\u5bb9\u76f8\u540c\u4f46id\u4e0d\u540c\uff09<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>RQTN \u7684\u8d28\u7591 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u89c2\u70b9 <\/strong>\uff1aRedis Stream \u81ea\u52a8 ACK\uff08\u9605\u540e\u5373\u711a\uff09\u4e0b\u65e0\u9700\u5e42\u7b49\uff0c\u6d88\u606f\u4e0d\u4f1a\u91cd\u590d\u6295\u9012\u3002<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u274c <strong>\u9519\u8bef<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u95ee\u9898\u5206\u6790 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u751f\u4ea7\u8005\u91cd\u8bd5 <\/strong>\uff1a\u82e5\u751f\u4ea7\u8005\u672a\u6536\u5230 ACK\uff0c\u53ef\u80fd\u91cd\u590d\u53d1\u9001\u76f8\u540c\u6d88\u606f\uff08\u4e0d\u540c ID\uff09\uff0c\u5bfc\u81f4 MQ \u4e2d\u5b58\u5728\u91cd\u590d\u6d88\u606f\u3002<\/li>\n\n\n\n<li><strong>\u7f51\u7edc\u6296\u52a8 <\/strong>\uff1a\u6d88\u606f\u53ef\u80fd\u88ab\u591a\u6b21\u6295\u9012\uff08\u5373\u4f7f ID \u4e0d\u540c\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u7ed3\u8bba <\/strong>\uff1a\u5e42\u7b49\u5904\u7406\u4ecd\u5fc5\u8981\uff0c\u9700\u7ed3\u5408\u6d88\u606f ID \u548c\u4e1a\u52a1\u903b\u8f91\u4fdd\u969c\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>kidult \u7684\u8865\u5145 <\/strong>\uff1a\u2705 <strong>\u5b8c\u5168\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u81ea\u52a8 ACK \u7684\u5c40\u9650\u6027 <\/strong>\uff1a\u6d88\u606f\u4e00\u65e6\u62c9\u53d6\u5373\u786e\u8ba4\uff0c\u5f02\u5e38\u65e0\u6cd5\u89e6\u53d1\u91cd\u8bd5\uff0c\u9700\u4f9d\u8d56\u624b\u52a8 ACK\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Best HL \u7684\u5efa\u8bae <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u95ee\u9898 <\/strong>\uff1a\u82e5\u6d88\u8d39\u4e2d\u5b95\u673a\uff08\u5df2\u5199\u5165\u6570\u636e\u5e93\u4f46\u672a\u6807\u8bb0\u5b8c\u6210\uff09\uff0c\u91cd\u590d\u6d88\u606f\u4f1a\u56e0\u65e0\u9884\u5360\u6807\u8bc6\u800c\u518d\u6b21\u6d88\u8d39\u3002<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u2705 <strong>\u5b8c\u5168\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u89e3\u51b3\u65b9\u6848 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u5206\u79bb\u72b6\u6001\u66f4\u65b0\u4e0e\u4e1a\u52a1\u903b\u8f91 <\/strong>\uff1a\u5148\u66f4\u65b0 Redis \u4e3a \"1\"\uff0c\u518d\u63d0\u4ea4\u6570\u636e\u5e93\u4e8b\u52a1\uff08\u9700\u4e24\u9636\u6bb5\u63d0\u4ea4\uff09\u3002<\/li>\n\n\n\n<li><strong>\u8865\u507f\u673a\u5236 <\/strong>\uff1a\u5b9a\u65f6\u4efb\u52a1\u626b\u63cf\u672a\u5b8c\u6210\u6807\u8bc6\uff0c\u89e6\u53d1\u91cd\u8bd5\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Everglow \u7684\u8d28\u7591 <\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u95ee\u9898 <\/strong>\uff1a<code>setAccomplish<\/code> \u5728 <code>finally<\/code> \u4e2d\u6267\u884c\u662f\u5426\u5408\u7406\uff1f<\/li>\n\n\n\n<li><strong>\u6b63\u786e\u6027 <\/strong>\uff1a\u2705 <strong>\u90e8\u5206\u6b63\u786e<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>\u98ce\u9669 <\/strong>\uff1a\u82e5\u6d88\u8d39\u5931\u8d25\uff08\u5982\u6570\u636e\u5e93\u5f02\u5e38\uff09\uff0c\u6807\u8bb0\u4e3a\u5b8c\u6210\uff08\"1\"\uff09\u4f1a\u5bfc\u81f4\u6d88\u606f\u88ab\u8bef\u5224\u4e3a\u6210\u529f\u3002<\/li>\n\n\n\n<li><strong>\u5efa\u8bae <\/strong>\uff1a\u4ec5\u5728\u4e1a\u52a1\u903b\u8f91\u6210\u529f\u540e\u8c03\u7528 <code>setAccomplish<\/code>\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>&nbsp;\u6b63\u5e38\u60c5\u51b5\uff1a\u83b7\u53d6\u6d88\u606f -&gt; \u8bbe\u7f6e\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09 -&gt; \u6d88\u8d39 -&gt; \u6807\u8bc6\u8bbe\u7f6e\uff08\u5df2\u5b8c\u6210\uff09 \u5f02\u5e38\u60c5\u51b5\uff1a 1.\u91cd\u590d\u6d88\u606f\uff1a\u91cd\u590d\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u6b63\u5728\u6d88\u8d39\u4e2d\uff09 -&gt; \u5224\u65ad\u662f\u5426\u6d88\u8d39\u5b8c\u6210\uff08\u5df2\u5b8c\u6210\uff09-&gt; \u8fd4\u56de 2.\u91cd\u8bd5\u6d88\u606f\uff08\u6b63\u5e38\u6d41\u7a0b\uff09\uff1a\u91cd\u8bd5\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt;\u6d88\u8d39 -&gt;\u6807\u8bc6\u8bbe\u7f6e\uff08\u5df2\u5b8c\u6210\uff09 3.\u91cd\u8bd5\u6d88\u606f\uff08\u4e4b\u524d\u8bbe\u7f6e\u5df2\u5b8c\u6210\u6807\u8bc6\u5931\u8d25\uff09\uff1a\u91cd\u8bd5\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt; \u5224\u65ad\u662f\u5426\u6d88\u8d39\u5b8c\u6210\uff08\u672a\u5b8c\u6210\uff09-&gt; \u629b\u51fa\u5f02\u5e38 \u6d88\u606f\u6d88\u8d39\u4e2d \u4f46\u662f\u672a\u5b8c\u6210 -&gt; \u91cd\u8bd5 -&gt;redis\u8fc7\u671f -&gt; \u8fdb\u5165\u6b63\u5e38\u6d41\u7a0b 4.\u6b63\u5e38\u6d88\u606f\uff08\u6d88\u8d39\u5f02\u5e38\uff09\uff1a\u83b7\u53d6\u6d88\u606f -&gt; \u5224\u65ad\u9884\u5360\u6807\u8bc6\uff08\u65e0\uff0c\u8bbe\u7f6e\u6b63\u5728\u6d88\u8d39\u4e2d\uff09-&gt; \u6d88\u8d39\u5f02\u5e38 -&gt;\u5220\u9664\u9884\u5360\u6807\u8bc6 -&gt; \u629b\u51fa\u5f02\u5e38 \u6d88\u606f\u6d88\u8d39\u5931\u8d25 -&gt;\u91cd\u8bd5 5.\u91cd\u8bd5\u6d88\u606f\uff08\u4e4b\u524d\u6d88\u8d39\u5f02\u5e38\uff0c\u5e76\u4e14\u5220\u9664\u9884\u5360\u6807\u8bc6\u5931\u8d25\u201c\u5b95\u673a\u201d\uff09\uff1a\u53c2\u8003\u7b2c3\u6761<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c15\u8282\uff1a\u77ed\u94fe\u63a5Redis\u7f13\u5b58\u547d\u540d\u91cd\u6784<\/h2>\n\n\n\n<p>&nbsp;\u5728userserviceimpl\u4e2d\uff0c\u6211\u4eec\u53d1\u73b0 \u8fd9\u4e48\u4e00\u53e5\u8bdd&nbsp; &nbsp; &nbsp; &nbsp;Map&lt;Object ,Object&gt; hasLoginMap = stringRedisTemplate.opsForHash().entries(\"login_\" + requestParam.getUsername());\u4fee\u6539\u4e3a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Map&lt;Object, Object&gt; hasLoginMap = stringRedisTemplate.opsForHash().entries(USER_LOGIN_KEY + requestParam.getUsername());\n<\/pre>\n\n\n\n<p>&nbsp;\u540c\u6837\u7684\u4e0b\u9762\u7684 \u6240\u6709\u201clogin_\u201d\u7edf\u7edf\u4fee\u6539\u4e3aUSER_LOGIN_KEY\uff0c\u4e00\u51715\u4e2a\uff1b<\/p>\n\n\n\n<p>\u76f8\u5e94\u7684\uff0cRedisCacheConstant\u91cc\u9762\u5f04\u4e00\u4e2aUSER_LOGIN_KEY\uff0c\u8fd8\u6709UserTransmitFilter\u91cc\u9762\u4e5f\u6709\u4e00\u4e2a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.common.constant;\n\n\/**\n * redisson \u7684\u5e38\u91cf\u547d\u540d\n *\/\npublic class RedisCacheConstant {\n    \/**\n     * \u7528\u6237\u6ce8\u518c\u5206\u5e03\u5f0f\u9501\n     *\/\n    public static final String LOCK_USER_REGISTER_KEY = \"short-link:lock-user-register:\";\n\n    \/**\n     * \u5206\u7ec4\u521b\u5efa\u5206\u5e03\u5f0f\u9501\n     *\/\n    public static final String LOCK_GROUP_CREATE_KEY = \"short-link:lock_group-create:%s\";\n    \/**\n     * \u7528\u6237\u767b\u5f55\u7f13\u5b58\u6807\u8bc6\n     *\/\n    public static final String USER_LOGIN_KEY = \"short-link:login:\";\n}\n<\/pre>\n\n\n\n<p>\u8fd8\u6709\u5c31\u662fRedisKeyConstant.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.project.common.constant;\n\n\/**\n * Redis Key \u5e38\u91cf\u7c7b\n *\/\npublic class RedisKeyConstant {\n\n    \/**\n     * \u77ed\u94fe\u63a5\u8df3\u8f6c\u524d\u7f00 Key\n     *\/\n    public static final String GOTO_SHORT_LINK_KEY = \"short-link:goto:%s\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u7a7a\u503c\u8df3\u8f6c\u524d\u7f00 Key\n     *\/\n    public static final String GOTO_IS_NULL_SHORT_LINK_KEY = \"short-link:is-null:goto_%s\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u8df3\u8f6c\u9501\u524d\u7f00 Key\n     *\/\n    public static final String LOCK_GOTO_SHORT_LINK_KEY = \"short-link:lock:goto:%s\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u4fee\u6539\u5206\u7ec4 ID \u9501\u524d\u7f00 Key\n     *\/\n    public static final String LOCK_GID_UPDATE_KEY = \"short-link:lock:update-gid:%s\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u5ef6\u8fdf\u961f\u5217\u6d88\u8d39\u7edf\u8ba1 Key\n     *\/\n    public static final String DELAY_QUEUE_STATS_KEY = \"short-link:delay-queue:stats\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u7edf\u8ba1\u5224\u65ad\u662f\u5426\u65b0\u7528\u6237\u7f13\u5b58\u6807\u8bc6\n     *\/\n    public static final String SHORT_LINK_STATS_UV_KEY = \"short-link:stats:uv:\";\n\n    \/**\n     * \u77ed\u94fe\u63a5\u7edf\u8ba1\u5224\u65ad\u662f\u5426\u65b0 IP \u7f13\u5b58\u6807\u8bc6\n     *\/\n    public static final String SHORT_LINK_STATS_UIP_KEY = \"short-link:stats:uip:\";\n}\n<\/pre>\n\n\n\n<p>&nbsp;project \u7684shortLinkServiceimpl\u662f\u8fd9\u6837\u7684\uff1a\u6240\u6709\u7684 \"short-link:stats:uv:\"&nbsp; \u7edf\u7edf\u66ff\u6362\u6210<br>SHORT_LINK_STATS_UV_KEY<\/p>\n\n\n\n<p>\u4ed6\u8fd9\u8fb9\u52a0\u8fdb\u53bb\u4e4b\u540e\u518d\u5904\u7406\uff0c\u53ef\u80fd\u6ca1\u5730\u65b9\u7528\u4e86\u3002\u6211\u60f3\u60f3\u4ed6\u5728\u91cc\u9762\u63d0\u5230\u4e86\u54ea\u91cc\uff1f\u4ed6\u5728\u54ea\u4e2a\u73af\u8282\u5361\u4f4f\u4e86\uff1f\u6211\u4eec\u628a\u4e1a\u52a1\u5173\u8054\u5173\u7cfb\u4e0d\u80fd\u8fd9\u6837\u5904\u7406\uff0c\u8fd9\u91cc\u53ea\u662f\u65b0\u589e\u4e86\u4f46\u6ca1\u7528\u5230\u662f\u4e0d\u53ef\u80fd\u7684\u3002\u6211\u95ee\u4e00\u4e0b\u8fd9\u4e2a\u903b\u8f91\u662f\u4ec0\u4e48\uff1f\u7b2c\u4e8ca\u7684remote\uff0c\u6ca1\u7528\u5230\u5417\uff1f\u4ed6\u5230\u5e95\u5728\u505a\u4ec0\u4e48\uff1f\u7528\u7684\u662f\u8fd9\u4e2a\u4e1c\u897f\u3002VIP\u3002VIP\u3002You are talking\u3002\u7136\u540e\u518d\u52a0\u4e00\u4e2a127.0.0.1\uff0c\u8fd9\u4e2a\u4e0d\u53ef\u80fd\u7528\u4e0d\u5230\u3002\u6211\u4eec\u6267\u884c\u7684\u65f6\u5019\u5c31\u5f00\u59cb\u53d1\u9001\u8bf7\u6c42\u4e86\uff0c\u6211\u4eec\u53bb\u91cc\u9762\u770b\u4e00\u4e0b\uff0c\u6709\u70b9\u79bb\u8c31\u3002\u6211\u60f3\u60f3\u5f53\u65f6\u6211\u62ff\u5b83\u7528\u6765\u505a\u4ec0\u4e48\uff0c\u628a\u5f53\u524d\u7684uip address\u4e0d\u7b49\u4e8e...\u6211\u60f3\u8d77\u6765\u786e\u5b9e\u6ca1\u7528\u5230\uff0c\u6216\u8005\u8bf4\u4e0d\u80fd\u8bf4\u5b8c\u5168\u6ca1\u7528\u5230\uff0c\u662f\u56e0\u4e3a\u672c\u8eab\u628a\u5b83\u52a0\u8fdb\u53bb\uff0c\u6211\u4eec\u7528\u4e86Excel\u7684\u7ed3\u679c\uff0c\u5982\u679c\u80fd\u52a0\u8fdb\u53bb\u5c31\u8bc1\u660e\u662f\u9996\u6b21\u8bbf\u95ee\uff0c\u52a0\u4e0d\u8fdb\u53bb\u5176\u5b9e\u5c31\u4e0d\u662f\u5bf9\u5427\uff1f\u80fd\u5927\u6982\u8bb2\u6e05\u695a\u8fd9\u4e2a\u4e34\u65f6\u903b\u8f91\uff0cok\u73b0\u5728\u6211\u4eec\u7684rise\u5e94\u8be5\u5c31\u6ca1\u95ee\u9898\u4e86\u3002\u54b1\u4eec\u8fd9\u8fb9\u6211\u770b\u4e00\u4e0b\u3002Ok\u6709\u6ca1\u6709\u95ee\u9898\uff0c\u6211\u4eec\u542f\u52a8\u524d\u7aef\u8bd5\u4e00\u4e0b\u3002\u6211\u53d6\u6d88\u3002\u7528\u6237\u540d\u6211\u8fd8\u771f\u6709\u70b9\u5fd8\u4e86\uff0c\u627e\u4e00\u4e2a\u7528\u6237\u597d\u50cf\u662f\u6211\u65b0\u52a0\u7684\u3002\u8fd8\u771f\u662f\u3002\u6211\u4e4b\u524d\u6ca1\u521b\u5efa\u8fc7\u5417\uff1f\u540e\u6765\u600e\u4e48\u4e86\uff1f\u96be\u9053\u662f\u7528\u6237\u8fd9\u8fb9\u6539\u9519\u4e86\uff1f\u529f\u80fd\u8fd9\u5757\u4fee\u6539\u8981\u6bd4\u8f83\u8c28\u614e\uff0c\u4e00\u62db\u9519\u5c31\u4f1a\u6b65\u6b65\u9519\uff0c\u4e00\u5f00\u59cb\u767b\u5f55\u62a5\u9519\u5c31\u77e5\u9053\u662f\u8fc7\u6ee4\u5668\u7684\u95ee\u9898\u3002Ok\u600e\u4e48\u4e86\uff1f\u6765\u91cd\u542f\u4e00\u4e0b\u670d\u52a1\uff0c\u8fd9\u5c31\u5bf9\u4e86\u3002\u6211\u8bb0\u5f97\u5f53\u65f6\u6211\u5f04\u4e86\u4e00\u4e2a\u94fe\u63a5\u7684ok\uff0c\u9a8c\u8bc1\u6210\u529f\u3002\u8fd9\u5bb6\u56e0\u4e3a\u4e4b\u524d\u6709\u8fc7\u7c7b\u4f3c\u95ee\u9898\uff0c\u8fd9\u8fb9\u662f1999\u600e\u4e48\u6ca1\u6709\uff1f\u8fd9\u4e2a\u903b\u8f91\u662f\u6ca1\u95ee\u9898\u7684\uff0c\u76f8\u5f53\u4e8e\u8fd9\u6b21\u65e7\u6539\u662f\u6b63\u786e\u7684\uff0c\u6211\u4eec\u52a0\u4e00\u4e2a\u4f18\u5316\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u8bb2\u4f18\u5316\u77ed\u94fe\u63a5\u76f8\u5173\u7f13\u5b58key\u628a\u4ee3\u7801\u63d0\u4ea4\u4e00\u4e0b\u5c31\u53ef\u4ee5\u4e86\uff0c\u7136\u540e\u4ee5\u8fd9\u4e2a\u89c6\u9891\u4e5f\u7ed9\u5927\u5bb6\u4e00\u4e9b\u5efa\u8bae\uff0c\u6bcf\u6b21\u5728\u5199\u5b8c\u4ee3\u7801\u4e4b\u540e\uff0c\u5c3d\u91cf\u9694\u4e00\u6bb5\u65f6\u95f4\u5728\u4e0d\u5f71\u54cd\u7ebf\u4e0a\u4e1a\u52a1\u8fd0\u884c\u7684\u60c5\u51b5\u4e0b\u5c31\u53bb\u7559\u5fc3\u4e00\u4e0b\u4ee3\u7801\uff0c\u76f8\u4fe1\u6211\u80af\u5b9a\u4f1a\u6709\u4e00\u4e9b\u5e2e\u52a9\u7684\u3002<\/p>\n\n\n\n<p>&nbsp;\u300a\u91cd\u6784\u65e2\u6709\u4ee3\u7801\u8bbe\u8ba1\u300b\uff0c\u300a\u4ee3\u7801\u6574\u6d01\u4e4b\u9053\u300b<\/p>\n\n\n\n<p>optimize:\u4f18\u5316\u77ed\u94fe\u63a5\u540e\u7ba1\u7528\u6237\u8fd4<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public UserLoginRespDTO login(UserLoginReqDTO requestParam) {\n    LambdaQueryWrapper&lt;UserDO&gt; queryWrapper = Wrappers.lambdaQuery(UserDO.class)\n            .eq(UserDO::getUsername, requestParam.getUsername())\n            .eq(UserDO::getPassword, requestParam.getPassword())\n            .eq(UserDO::getDelFlag, 0);\n    UserDO userDO = baseMapper.selectOne(queryWrapper);\n    if (userDO == null) {\n        throw new ServiceException(\"\u7528\u6237\u4e0d\u5b58\u5728\");\n    }<\/pre>\n\n\n\n<p>optimize:\u4f18\u5316\u7528\u6237\u4e0d\u5b58\u5728\u5f02\u5e38<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">private void returnJson(HttpServletResponse response, String json) throws Exception {\n   \/*\n    PrintWriter writer = null;\n    response.setCharacterEncoding(\"UTF-8\");\n    response.setContentType(\"text\/html; charset=utf-8\");\n    try {\n        writer = response.getWriter();\n        writer.print(json);\n    } catch (IOException e) {\n    } finally {\n        if (writer != null)\n            writer.close();\n    }\n    *\/\n    response.setCharacterEncoding(\"UTF-8\");\n    response.setContentType(\"text\/html; charset=utf-8\");\n    try (PrintWriter writer = response.getWriter()) {\n        writer.print(json);\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c16\u8282\uff1a\u77ed\u94fe\u63a5\u751f\u6210\u91cd\u590d\u4e3a\u4ec0\u4e48\u8981\u518d\u67e5\u8be2\u6570\u636e\u5e93\uff1f<\/h2>\n\n\n\n<p>\u8fd9\u4e2a\u6765\u8ddf\u5927\u5bb6\u804a\u4e00\u4e2a\u56f0\u6270\u5927\u5bb6\u5df2\u4e45\u7684\u4e00\u4e2a\u95ee\u9898\u3002\u4e3a\u4ec0\u4e48\u56f0\u6270\u5df2\u4e45\uff1f\u56e0\u4e3a\u4e4b\u524d\u4e00\u76f4\u542c\u5927\u5bb6\u8ddf\u6211\u63d0\u8d77\uff0c\u4f46\u662f\u5f53\u65f6\u56e0\u4e3a\u89c6\u9891\u5728\u5f55\u5236\u8fdb\u5ea6\u8fc7\u7a0b\u5f53\u4e2d\u4e0d\u592a\u53ef\u80fd\u56de\u5230\u524d\u9762\uff0c\u6240\u4ee5\u8bf4\u5f53\u5927\u90e8\u5206\u5185\u5bb9\u5f55\u5b8c\u4e4b\u540e\uff0c\u6211\u4eec\u7ec8\u4e8e\u53ef\u4ee5\u5728\u4e00\u8d77\u804a\u804a\u8fd9\u4e2a\u95ee\u9898\u3002\u90a3\u77ed\u94fe\u63a5catch\u91cc\u9762\u7684 if\u5224\u65ad\u6709\u6ca1\u6709\u5fc5\u8981\uff0c\u5bf9\u5427\uff1f\u5728\u804a\u8fd9\u4e2a\u95ee\u9898\u4e4b\u524d\uff0c\u6211\u4eec\u5148\u628a\u4e0a\u8282\u8bfe\u7684\u5c0f\u5c3e\u5df4\u7ed9\u6536\u4e00\u4e0b\u3002\u6211\u5728review\u4ee3\u7801\u7684\u8fc7\u7a0b\u5f53\u4e2d\u53d1\u73b0\u4e86\u6211\u4eec\u7684\u4f60\u53ef\u4ee5\u4f18\u5316\u4e00\u4e0b\uff0c\u6211\u4eec\u7edf\u4e00\u7684\u628a\u8fd9\u91cc\u9762\u62bd\u8c61\u5230\u957f\u6c5f\u91cc\u9762\u53bb\uff0c\u5728\u4ed6\u4eec\u7136\u540e\u662f\u8fd9\u79cd\u8fd9\u4e2a\u53eb10\u4e2a\u8ba4\u53ef\u3002\u662f\u8ddd\u79bb\u4e2d\u5fc3\u3002\u5b9e\u9645\u6211\u4eec\u8fd9\u8fb9\u7ed9\u4ed6\u6539\u4e2a\u7279\u522b\u4e86\uff0c\u533a\u522b\u6211\u4eec\u4e0b\u9762\u7684\u533a\u522b\u6211\u4eec\u4e0b\u9762\u7684\u5565\uff1f\u533a\u522b\u6211\u4eec\u4e0b\u9762\u8fd9\u4e2a\u6b4c\u8c31\uff0c\u77ed\u94fe\u63a5\u76d1\u63a7\u3002\u6d88\u606f\u4fdd\u5b58\uff0c\u7136\u540e\u6211\u4eec\u5c31\u53ef\u4ee5\u770b\u4e00\u4e0b\u8fd9\u91cc\u9762\u5b83\u5728\u54ea\u91cc\u53ef\u4ee5\u7528\u5230\u4e86\u4e24\u4e2a\u5730\u65b9\u5e94\u8be5\u9996\u5148\u8fd9\u91cc\u6211\u4eec\u76f4\u63a5\u628a\u5b83\u6539\u6210\u7136\u540e\u7136\u540e\u683c\u9c81\u666e\u5220\u6389\u3002Ok\uff0c\u6ca1\u6709\u4e86\u3002\u786e\u4fdd\u4e07\u4e00\u6211\u4eec\u628a\u8fd9\u4e24\u4e2a\u770b\u5230\u6ca1\u6709\uff0c\u5305\u62ec\u6ce2\u6d6a\u7ebf\u4e86\uff0c\u8fd9\u8fb9\u786e\u5b9e\u6ca1\u6709\u4e86\u3002\u7136\u540e\u628a\u8fd9\u4e2a\u5220\u6389\u4e4b\u540e\uff0c\u4f60\u5148\u63d0\u4ea4\u4ee3\u7801\u3002\u5c06\u7f13\u5b58T\u4e00\u81f4\u8003\u8651\u4e00\u8d77\u63d0\u3002\u7136\u540e\u628a\u8fd9\u4e2a\u641e\u5b9a\u4e4b\u540e\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5c31\u662f\u6211\u4eec\u5728\u4e0a\u4e00\u8282\u8bfe\u91cc\u9762\u8bf4\u4e86\uff0c\u9700\u8981\u7ed9\u4ed6\u505a\u4e00\u4e2a\u5c31\u662f\u624b\u52a8\u7684\u53bb\u6dfb\u52a0group\u7684\u4e00\u4e2a\u903b\u8f91\uff0c\u8fd9\u662f\u5728\u6211\u7684\u5370\u8c61\u5f53\u4e2d\u80af\u5b9a\u5fcd\u4e0d\u4e86\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u5e72\u4ec0\u4e48\u6dfb\u52a0\u4e00\u4e2a\u521d\u59cb\u5316\u7684\u4efb\u52a1\uff0c\u6253\u9519\u4e86\u3002<\/p>\n\n\n\n<p>\u7136\u540e\u52a0\u4e00\u4e2a\u4ec0\u4e48\uff1f\u52a0\u4e00\u4e2a\u5bf9\u3002\u4f7f\u52b2\uff0c\u6ca1\u4ec0\u4e48\u95ee\u9898\u3002\u521d\u59cb\u5316\u3002\u521d\u59cb\u5316\u4ec0\u4e48\u521d\u59cb\u5316\uff0c\u77ed\u94fe\u63a5\u76d1\u63a7\u6d88\u606f\u961f\u5217\uff0c\u4ec0\u4e48\uff1f\u6d88\u8d39\u8005\uff0c\u7136\u540e\u6211\u4eec\u8981\u5728\u8fd9\u91cc\u9762\u628a\u90a3\u4e2a\u662f\u4e0d\u9002\u5e94\u539f\u7406\uff0c\u4ed6\u6ca1\u6709\u7591\u96be\u3002\u7b2c\u4e8c\u5b9e\u8bad\uff0c\u7b2c\u4e8ca\u7684\u4e0d\u5bf9group\u3002\u89c9\u5f97\u4e0d\u662f\u7136\u540e\u628a topic\u5f15\u8fdb\u6765\uff0c\u7b54\u4e0d\u51fa\u6765\u3002\u7b54\u4e0d\u51fa\u6765\u90a3\u5c31\u590d\u5236\u3002\u7136\u540e\u8fd8\u6709\u4e00\u70b9\u5c31\u662f\u5982\u679c\u8bf4\u8fd9\u4e2a\u77ed\u4fe1\uff0c\u5982\u679c\u8bf4 stream\u8fd9\u4e2a\u5df2\u7ecf\u5b58\u5728\u5b83\u4f1a\u62a5\u9519\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u8fd9\u91cc\u9762\u8981\u5148\u52a0\u4e00\u4e2a\u5224\u65ad\u3002\u7b2c\u4e8c\u8fd8\u662f\u53ef\u4ee5\u3002\u7b2c\u56db\u8bfe\u7684\u8bdd\u6211\u4eec\u8fdb\u5165\u8131\u8d2b\u8bfe\u9898\u3002\u7b2c\u56db\u9898\uff0c\u9886\u5bfc\uff0c\u6216\u8005\u6b63\u597d\u5c31\u4e07\u65e0\u4e00\u5931\u4e86\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u4ec0\u4e48\u6211\u4eec\u53ef\u4ee5\u628a\u8fd9\u73a9\u610f\u7ed9\u5220\u4e86\u3002\u8bf4\u4e0d\u5b9a\u4e0b\u9762\u5c31\u8fd9\u4e24\u4e2a\uff0c\u7136\u540e\u6211\u4eec\u628a\u8fd9\u4e2a\u9879\u76ee\u542f\u52a8\u4e00\u4e0b\uff0c\u53ea\u8981\u6211\u4eec\u542f\u52a8\u4e24\u6b21\u4ee5\u4e0a\u6ca1\u6709\u95ee\u9898\uff0c\u4ed6\u8fd9\u4e2a\u5c31\u7b97\u662fok\u7684\u3002\u7136\u540e\u8fd9\u6837\u7684\u8bdd\u5927\u5bb6\u542f\u52a8\u7684\u65f6\u5019\u5c31\u5c11\u4e86\u4e00\u4e2a\u6b65\u9aa4\uff0c\u5bf9\u4e0d\u5bf9\u770b\u5230\u6ca1\u6709\u6211\u4eec<\/p>\n\n\n\n<p>&nbsp;Ok\u662f\u6ca1\u62a5\u9519\u7684\u3002\u7136\u540e\u6211\u4eec\u8bbf\u95ee\u4e00\u4e0b\u6211\u4eec\u7684\u524d\u7aef\u9879\u76ee\uff0c\u53c8\u6709\u70b9\u5fd8\u4e86\u7528\u6237\u540d\u53eb\u4ec0\u4e48\u4e86\u3002\u641c\u4e00\u4e0b\u3002\u60f3\u8d77\u67658889 3 45678. \u597d\u7684\u903b\u8f91\u662f\u6ca1\u5565\u95ee\u9898\u3002\u770b\u770b\u6709\u6ca1\u6709\u62a5\u9519\u3002\u6ca1\u62a5\u9519\uff0c\u7136\u540e\u6570\u636e\u4e5f\u6b63\u5e38\u90fd\u8fdb\u6765\u4e86\uff0c\u5c31\u8bc1\u660e\u6211\u4eec\u6539\u7684\u6ca1\u95ee\u9898\u3002\u628a\u8fd9\u4e2a\u6539\u4e00\u4e0b\uff0c\u8fd9\u6837\u7684\u8bdd\u5927\u5bb6\u5bf9\u5427\u5c31\u5c11\u4e86\u4e2a\u903b\u8f91\uff0c\u5c11\u4e86\u4e00\u4e2a\u6b65\u9aa4\u5bf9\u4e0d\u5bf9\uff1f\u5c31\u4e0d\u9700\u8981\u4f60\u624b\u52a8\u7684\u53bb\u505a\u4e86\uff0c\u56e0\u4e3a\u624b\u52a8\u505a\u7684\u8bdd\uff0c\u8bf4\u5b9e\u8bdd\u8fd9\u91cc\u6211\u662f\u6bd4\u8f83\u53cd\u611f\u8fd9\u79cd\u884c\u4e3a\u7684\uff0c\u8bf4\u5b9e\u8bdd\u3002Raise stream. \u9ad8\u54c1\u683c\u548c\u6d88\u8d39\u8005\u51fa\u6765\u3002\u7136\u540e\u628a\u8fd9\u4e2a\u95ee\u9898\u89e3\u51b3\u4e86\u4e4b\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u771f\u6b63\u7684\u53bb\u770b\u4e00\u4e0b\u6211\u4eec\u4eca\u5929\u8981\u8bb2\u7684\u4e3b\u9898\u4e86\uff0c\u90a3\u5c31\u662f\u6211\u4eec\u7684\u5f02\u5e38\u5230\u5e95\u6709\u6ca1\u6709\u5fc5\u8981\u5728\u6211\u4eecservice\u91cc\u9762\uff0c\u8fd9\u4e2a\u903b\u8f91\u6bd4\u8f83\u7b80\u5355\uff0c\u5c31\u662f\u5982\u679c\u8bf4\u65b0\u589e\u51fa\u73b0\u4e86 K\u91cd\u590d\u4ee5\u4e0a\uff0c\u56e0\u4e3a\u6211\u4eec\u5df2\u7ecf\u628a\u77ed\u94fe\u63a5\u8868\u91cc\u9762\u7684\u5b8c\u6574\u77ed\u94fe\u63a5\u5f53\u505a\u4e00\u4e2a\u552f\u4e00\u7d22\u5f15\u4e86\uff0c\u5982\u679c\u8bf4\u629b\u51fa\u5f02\u5e38\u7684\u8bdd\uff0c\u5b83\u5e94\u8be5\u4f1a\u5728\u8fd9\u91cc\u8fb9\u62e6\u622a\u51fa\u6765\uff0c\u7136\u540e\u6211\u4eec\u4e4b\u524d\u8fd9\u91cc\u67e5\u8be2\u4e86\u4e00\u6b65\u5bf9\u5427\uff1f\u7136\u540e\u67e5\u8be2\u771f\u6b63\u4e0d\u7b49\u4e8e\u7a7a\u7684\u8bdd\u518d\u8dd1\u4e00\u573a\u3002\u8fd9\u4e2a\u903b\u8f91\u5c31\u662f\u4e3a\u4ec0\u4e48\uff1f\u7136\u540e\u6211\u4eec\u5148\u5206\u6790\u4e00\u4e0b\u6d41\u7a0b\uff0c\u6211\u4eec\u662f\u9760\u4ec0\u4e48\u6765\u5224\u65ad\u8fd9\u4e2a\u6570\u636e\u77ed\u94fe\u63a5\u662f\u5426\u5b58\u5728\u7684\uff1f\u4e0d\u80fd\u8fc7\u6ee4\u5668\u5bf9\u4e0d\u5bf9\uff1f\u90a3\u4e0d\u80fd\u8fc7\u6ee4\u5668\u6709\u4ec0\u4e48\u7279\u70b9\uff1f\u67e5\u8be2\u662f\u5426\u5b58\u5728\u3002\u5982\u679c\u8fd4\u56de\u5b58\u5728\uff0c\u53ef\u80fd\u6570\u636e\u5b58\u53ef\u80fd\u6570\u636e\u662f\u4e0d\u5b58\u5728\u7684\uff0c\u5982\u679c\u8fd4\u56de\u4e0d\u5b58\u5728\uff0c\u6570\u636e\u4e00\u5b9a\u4e0d\u5b58\u5728\u3002\u5927\u5bb6\u53bb\u719f\u6089\u4e00\u4e0b\u6211\u4eec\u4e0d\u540c\u8fc7\u6ee4\u5668\u7684\u4e00\u4e9b\u539f\u7406\uff0c\u5927\u5bb6\u5e94\u8be5\u90fd\u77e5\u9053\uff0c\u4e4b\u524d\u5e94\u8be5\u662f\u7ed9\u5927\u5bb6\u8bb2\u8fc7\u7684\u3002\u57fa\u4e8e\u8fd9\u79cd\u7684\u8bdd\uff0c\u9996\u5148\u8fd9\u91cc\u9762\u6211\u662f\u6309\u7167\u4e0a\u9762\u8fd9\u4e2a\u903b\u8f91\u53bb\u5224\u65ad\u7684\uff0c\u4ed6\u53ef\u80fd\u5bf9\u5427\uff1f\u6211\u53ef\u80fd\u9884\u60f3\u5230\u4f1a\u6709\u8fd9\u79cd\u60c5\u51b5\uff0c\u4f46\u662f\u6211\u540e\u9762\u7684\u4ee3\u7801\u5176\u5b9e\u91cd\u6784\u4e86\uff0c\u6211\u628a\u8fd9\u91cc\u5fd8\u6539\u4e86\uff0c\u5c31\u662f\u8fd9\u4e2a\u6837\u5b50\u3002\u7136\u540e\u6211\u4eec\u53ef\u4ee5\u770b\u4e00\u4e0b\u5224\u65ad\u5b83\u751f\u6210\u94fe\u63a5\u7684\u65f6\u5019\uff0c\u90a3\u5c31\u662f\u5728\u8fd9\u91cc\u6211\u4eec\u7528\u7684\u4ec0\u4e48\uff1f\u4e0d\u662f\u8fd9\u91cc\u3002\u5728\u8fd9\u91cc\u6211\u4eec\u7528\u7684\u662f\u4e0d\u5b58\u5728\u5982\u679c\u8bf4\u4e0d\u5b58\u5728\uff0c\u751f\u6210\u77ed\u4fe1\u9875\u4e4b\u540e\u5224\u65ad\u4e0d\u80fd\u8fc7\u6ee4\u5668\u91cc\u9762\u4e0d\u5b58\u5728\uff0c\u90a3\u4e48\u5b83\u4e00\u5b9a\u662f\u5bf9\u5427\uff1f\u4e0d\u5b58\u5728\u7684\uff0c\u8fd9\u6837\u7684\u8bdd\u5c31\u8fd4\u56de\u535a\u535a\u53ef\u4e0d\u8ba4\u53ef\u5bf9\u5427\uff1f\u7136\u540e\u5c31\u544a\u8bc9\u6211\u4eec\u8bf4\u8fd9\u4e2a\u5f53\u7136\u4e5f\u53ef\u4ee5\u7528\uff0c\u8fd9\u79cd\u60c5\u51b5\u4e0b\u4ed6\u6709\u4ec0\u4e48\u95ee\u9898\u5417\uff1f\u5927\u5bb6\u60f3\u60f3\u6709\u6ca1\u6709\u4ec0\u4e48\u95ee\u9898\uff0c\u7ed9\u5927\u5bb6\u534a\u5206\u949f\u7684\u65f6\u95f4\u601d\u8003\u3002\u4ed6\u7684\u95ee\u9898\u5c31\u5728\u4e8e\u4ed6\u7684\u4e00\u4e9b\u5047\u5982\u8bf4\u6211\u4eec\u751f\u6210\u4e86123456\uff0c\u5047\u5982\u751f\u6210\u4e86\u8fd9\u4e2a\u7531\u4e8e\u8f6c\u94fe\u63a5\u7684\u8bef\u5224\uff0c\u4ed6\u53ef\u80fd\u6ca1\u529e\u6cd5\u4f7f\u7528\uff0c\u4f46\u662f\u8fd9\u4e2a\u5c31\u50cf\u6211\u4eec\u572812366\u91cc\u9762\u7684\u7528\u6237\u540d\u4e00\u6837\uff0c\u8fd9\u79cd\u6709\u5f71\u54cd\u5417\uff1f<\/p>\n\n\n\n<p>\u5bf9\u5427\uff1f\u77ed\u94fe\u63a5\u7684\u7ec4\u5408\u662f\u968f\u610f\u7684\uff0c\u7136\u540e\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u5b83\u662f\u552f\u4e00\u53ef\u7528\u7684\u5c31\u53ef\u4ee5\uff0c\u5b83\u5047\u5982\u8bf4\u6709\u4e00\u4e9b\u4e0d\u53ef\u7528\u6709\u4ec0\u4e48\u5f71\u54cd\u5417\uff1f\u6ca1\u6709\u5f71\u54cd\u5bf9\u4e0d\u5bf9\uff1f\u65e2\u7136\u6ca1\u6709\u5f71\u54cd\u7684\u8bdd\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u8ba9\u4ed6\u518d\u53bb\u91cd\u590d\u751f\u6210\uff0c\u6bd4\u5982\u8bf4\u628a9\u6539\u62107\uff0c\u5bf9\u5427\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u8981\u7684\u7ed3\u679c\u5c31\u662f\u5b83\u4e0d\u5b58\u5728\u4e8e\u4e0d\u80fd\u8fc7\u6ee4\u5668\uff0c\u8fd9\u79cd\u7684\u8bdd\u6ca1\u95ee\u9898\u7684\u3002\u6240\u4ee5\u8bf4\u6211\u4eec\u7528\u7684\u8fd9\u79cd\u6a21\u578b\u5224\u65ad\u5b83\u4e0d\u5b58\u5728\u5c31\u4e00\u5b9a\u4e0d\u5b58\u5728\u7684\u8fd9\u79cd\u903b\u8f91\uff0c\u5982\u679c\u8bf4\u8fd9\u4e2a\u903b\u8f91\u662f\u6210\u7acb\u7684\u8bdd\uff0c\u8fd9\u91cc\u5176\u5b9e\u5176\u5b9e\u5c31\u6ca1\u6709\u5fc5\u8981\u4e86\u3002\u5bf9\uff0c\u8fd9\u91cc\u5176\u5b9e\u5c31\u6ca1\u5fc5\u8981\u4e86\u3002\u6211\u4eec\u628a\u5b83\u4f18\u5316\u4e00\u4e0b\u30024\u6708\u4efd\u6211\u4eec\u628a\u8fd9\u4e2a\u5f02\u5e38\u6b63\u5e38\u629b\u51fa\u6765\uff0c\u5176\u5b9e\u8fd9\u91cc\u67e5\u8be2\u5c31\u6ca1\u6709\u5fc5\u8981\u4e86\uff0c\u5bf9\u5427\uff1f\u5927\u5bb6\u7406\u89e3\u4e00\u4e0b\u8fd9\u4e2a\u6bd4\u8f83\u4e0d\u80fd\u8fc7\u6ee4\u5668\u91cc\u9762\u6709\u70b9\u7ed5\uff0c\u5927\u5bb6\u53ea\u9700\u8981\u77e5\u9053\u6211\u4eec\u662f\u4e0d\u662f\u6309\u7167\u5b83\u662f\u5426\u5b58\u5728\u53bb\u5224\u65ad\uff0c\u6211\u4eec\u662f\u6309\u7167\u5b83\u8fd4\u56de\u4e0d\u5b58\u5728\u5219\u6570\u636e\u4e00\u5b9a\u4e0d\u5b58\u5728\u7684\u903b\u8f91\u53bb\u5224\u65ad\u7684\u3002\u6709\u4e9b\u540c\u5b66\u53ef\u80fd\u4f1a\u95ee\u4e0d\u80fd\u8fc7\u6ee4\u5668\u91cc\u9762\u5bf9\u5427\uff1f\u8fd9\u91cc\u9762\u5df2\u7ecf\u5728\u54ea\uff1f\u8fd9\u91cc\u9762\u5df2\u7ecf\u5224\u65ad\u4e0d\u5b58\u5728\u4e86\uff0c\u5b83\u8fd8\u4f1a\u53d1\u751f\u7ec4\u4ef6\u51b2\u7a81\u5417\uff1f\u8fd8\u4f1a\u53d1\u751f\u552f\u4e00\u7d22\u5f15\u51b2\u7a81\u5417\uff1f\u4f1a\u7684\uff0c\u56e0\u4e3a\u5b83\u5e76\u53d1\u573a\u666f\u4e0b\u5bf9\u5427\uff1f\u5047\u5982\u8bf4\u6211\u4eec\u6709\u4e24\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u6570\u636e\u540c\u65f6\u8bf7\u6c42\u4e86\uff0c\u8fd9\u4e2a\u65f6\u5019\u8fd8\u6ca1\u8d70\u5230\u6570\u636e\u5e93\uff0c\u5728\u8fd9\u91cc\u9762\u5b83\u80af\u5b9a\u662f\u540c\u65f6\u8fd4\u56de\u5b58\u5728\u7684\uff0c\u5b83\u4e00\u8d77\u53bb\u8bf7\u6c42\u6570\u636e\u5e93\u80af\u5b9a\u53ea\u6709\u4e00\u4e2a\u80fd\u6210\u529f\uff0c\u5927\u5bb6\u61c2\u6211\u610f\u601d\u5427\uff1f\u6240\u4ee5\u8bf4\u6211\u4eec\u90a3\u91cc\u8fd8\u662f\u8981\u53bb\u505a\u552f\u4e00\u7d22\u5f15\u5224\u65ad<\/p>\n\n\n\n<p>\u00a0\u8fd9\u91cc\u9762\u7684\u8bdd\u76f8\u4fe1\u5df2\u7ecf\u7ed9\u5927\u5bb6\u89e3\u60d1\u4e86\u5bf9\u5427\uff1f\u6211\u4eec\u4e5f\u628a\u5224\u65ad\u7ed9\u5220\u9664\u4e86\uff0c\u8fd9\u4e2a\u662f\u56e0\u4e3a\u6211\u4e4b\u524d\u505a\u67b6\u6784\u8bbe\u8ba1\u7684\u65f6\u5019\u8c03\u6574\u4e86\uff0c\u7136\u540e\u8fd9\u4e2a\u91cc\u9762\u7684\u5fd8\u8bb0\u8c03\u6574\uff0c\u7136\u540e\u5bfc\u81f4\u5927\u5bb6\u4e00\u76f4\u5fc3\u91cc\u9762\u7684\u4e00\u4e9b\u7591\u95ee\uff0c\u5f53\u7136\u5927\u5bb6\u5c31\u662f\u63d0\u95ee\u7684\u70b9\u662f\u975e\u5e38\u597d\u7684\uff0c\u52c7\u4e8e\u8d28\u7591\u5bf9\u5427\uff1f\u6211\u53ef\u4ee5\u8d28\u7591\u7684\u5bf9\uff0c\u4f46\u662f\u6211\u89c9\u5f97\u4e0d\u5bf9\u7684\u65f6\u5019\u6211\u5e94\u8be5\u8d28\u7591\u8fd9\u4e2a\u662f\u633a\u597d\u7684\u3002\u7136\u540e\u7b2c\u4e8c\u70b9\u90a3\u5929\u6211\u5728\u538b\u6d4b\u77ed\u94fe\u63a5\u7684\u65f6\u5019\uff0c\u5b83\u5e76\u53d1\u573a\u666f\u4e0b\u4f1a\u51fa\u73b0\u4e00\u4e9b\u77ed\u94fe\u63a5\u751f\u6210\u91cd\u590d\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u524d\u4e24\u5929\u5728\u505a\u538b\u6d4b\u7684\u8fc7\u7a0b\u5f53\u4e2d\uff0c\u538b\u90a3\u4e2a\u65f6\u5019\u4f1a\u51fa\u73b0\u4e00\u4e9b\u77ed\u65f6\u95f4\u751f\u6210\u91cd\u590d\uff0c\u7136\u540e\u6211\u5c31\u5728\u60f3\u8fd9\u4e2a\u95ee\u9898\u53ef\u80fd\u662f\u4ec0\u4e48\u3002\u7136\u540e\u6211\u60f3\u4e86\u4e00\u4e0b\uff0c\u53ef\u80fd\u662f\u5728\u5927\u91cf\u7528\u6237\u540c\u4e00\u6beb\u79d2\u4e0b\u53bb\u8bf7\u6c42\u5bf9\u5427\uff1f\u5047\u5982\u8bf4\u6211\u4eec\u7684\u539f\u59cb\u7684URL\u662f\u4e00\u6837\u7684\uff0c\u5bf9\u5427\uff1f\u6211\u4eec\u7684\u524d\u7f6e\u6761\u4ef6\u662f\u539f\u59cbURL\u662f\u4e00\u6837\u7684\uff0c\u539f\u59cbURL\u7684\u60c5\u51b5\u4e00\u81f4\u7684\u60c5\u51b5\u4e0b\uff0c\u5982\u679c\u6709\u5927\u91cf\u7684\u8bf7\u6c42\u53bb\u8bbf\u95ee\u6211\u4eec\u7684\u6570\u636e\uff0c\u6240\u4ee5\u8bf4\u7528\u8fd9\u4e2a\u5f53\u7136\u6beb\u79d2\u6570\u662f\u6709\u70b9\u95ee\u9898\u7684\u3002\u56e0\u4e3a\u5b83\u5982\u679c\u5728\u77ed\u65f6\u95f4\u5185\u6d8c\u4e0a\u6765\u5927\u91cf\u7684\u5e94\u7528\uff0c\u5927\u91cf\u7684\u8bf7\u6c42\uff0c\u5b83\u7684\u6beb\u79d2\u6570\u662f\u4e00\u81f4\u7684\uff0c\u6240\u4ee5\u8bf4\u8fd9\u91cc\u6709\u4e00\u70b9\u4e0d\u592a\u597d\uff0c\u7136\u540e\u4e4b\u524d\u6709\u4f4d\u540c\u5b66\u8ddf\u6211\u8bf4\u4e86\u8fd9\u4e00\u70b9\uff0c\u7136\u540e\u4e4b\u524d\u8fd8\u662f\u6ca1\u6709\u53bb\u4f18\u5316\uff0c\u7ed3\u5408\u5230\u524d\u4e24\u5929\u6211\u4eec\u7684\u62a5\u9519\u63d0\u9192\uff0c\u7136\u540e\u6211\u60f3\u5230\u4e86\u8fd9\u4e00\u70b9\uff0c\u6211\u4eec\u5e94\u8be5\u628a\u5b83\u6539\u6210\u4ec0\u4e48\uff1f\u628a\u5b83\u6539\u6210UV it\uff0c\u7528\u968f\u673a\u7684U ID\u5c31\u53ef\u4ee5\u4e86\u3002\u7136\u540e\u8fd9\u6837\u7684\u8bdd\u5c31\u80fd\u591f\u5c06\u5b83\u7684\u5c06\u5b83\u7684\u91cd\u590d\u7387\u964d\u5230\u6700\u4f4e\uff0c\u597d\u5427\uff1f\u6211\u4eec\u628a\u8fd9\u4e2a\u4e5f\u5148\u63d0\u4e00\u4e0b\uff0c\u522b\u4eba\u8bf4\u9a6c\u54e5\u4ed6\u51b2\u7a81\u65e0\u6240\u8c13\uff0c\u6211\u4eec\u4e0d\u662f\u552f\u4e00\u7d22\u5f15\uff0c\u5047\u5982\u8bf4\u6709\u4eba\u60f3\u6076\u610f\u653b\u51fb\u4f60\u5bf9\u5427\uff1f\u4ed6\u5c31\u7528\u8fd9\u79cd\u6bd4\u5982\u8bf4\u7528\u6d77\u91cf\u7684\u8fd9\u79cd\u6570\u636e\u8bf7\u6c42\u53bb\u8bbf\u95ee\u4f60\uff0c\u4ed6\u5c31\u662f\u8981\u505a\u7684\uff0c\u5728\u77ed\u65f6\u95f4\u5185\u5168\u90e8\u628a\u6570\u636e\u653e\u5230\u4f60\u7684\u6570\u636e\u5e93\u91cc\u9762\u53bb\uff0c\u90a3\u8fd9\u6837\u7684\u8bdd\u5176\u5b9e\u5b83\u7684\u76ee\u7684\u5df2\u7ecf\u62ff\u5230\u4e86\uff0c\u597d\u5427\uff1f\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u5c3d\u91cf\u7684\u8ba9\u8ba9\u6570\u636e\u5e93\u907f\u514d\u8fd9\u79cd\u884c\u4e3a\u3002\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u5c3d\u53ef\u80fd\u7684\u628a\u4e00\u5207\u80fd\u8003\u8651\u5230\u7684\u70b9\u90fd\u8003\u8651\u5230\uff0c UU ID\u5c31\u662f\u5176\u4e2d\u7684\u4e00\u4e2a\u70b9\u3002\u7136\u540e\u8fd9\u4e2a\u95ee\u9898\u4e5f\u7ed9\u5927\u5bb6\u641e\u5b9a\u4e86\uff0c\u5c31\u662f\u540c\u4e00\u65f6\u95f4\u4e0b\u3002\u77ed\u65f6\u95f4\u3002\u600e\u4e48\u63cf\u8ff0\u65f6\u95f4\uff1f\u8981\u540c\u4e00\u6beb\u7c73\u3002\u5927\u91cf\u8bf7\u6c42\u76f8\u540c\u7684\u539f\u59cb\u94fe\u63a5\u4f1a\u751f\u6210\u91cd\u590d\u77ed\u94fe\u63a5\uff0c\u5224\u65ad\u4e0d\u5b58\u5728\uff0c\u901a\u8fc7\u8be5\u901a\u8fc7\u8be5\u65b9\u5f0f\u8bbf\u95ee\u6570\u636e\u5e93\u3002\u4e3a\u6b64\u6211\u4eec\u4f7f\u7528UI ID\u66ff\u6362\u4e86\u5f53\u524d\u65f6\u95f4\u8bf4\u6765\u4e00\u5b9a\u7a0b\u5ea6\u51cf\u5c11\u91cd\u590d\u7684\u77ed\u94fe\u63a5\u751f\u6210\u3002\u521a\u624d\u6709\u4e00\u70b9\u8ddf\u5927\u5bb6\u8bf4\u9519\u4e86\uff0c\u4e0d\u662f\u4e3a\u4e86\u9632\u6b62\u5927\u91cf\u56fd\u9645\u6570\u636e\u5e93\uff0c\u662f\u4e3a\u4e86\u9632\u6b62\u6211\u4eec\u7684\u77ed\u94fe\u63a5\u8fd4\u56de\u751f\u6210\u91cd\u590d\u7684\u62a5\u9519\u597d\u5427\uff1f\u867d\u7136\u8bf4\u5b83\u53ef\u80fd\u8fd9\u79cd\u4e1c\u897f\u662f\u4e0d\u592a\u53ef\u80fd\u522b\u4eba\u4f1a\u5bf9\u5427\uff1f\u4e00\u76f4\u662f\u8bf7\u6c42\u76f8\u540c\u7684\u8fd9\u79cd\u65ad\u94fe\u63a5\uff0c\u4f46\u662f\u6211\u4eec\u8981\u76f8\u5bf9\u5e94\u7684\u5c31\u6709\u4e00\u4e9b\u63aa\u65bd\u5bf9\u5427\uff1f\u907f\u514d\u8fd9\u79cd\u65e0\u610f\u4e49\u7684\u62a5\u9519\u3002\u7136\u540e\u8fd8\u6709\u4e00\u70b9\u6211\u4eec\u8fd9\u91cc\u9762\u662f\u7528\u5230\u4e86\u4ec0\u4e48\uff1f\u7528\u5230\u4e86\u5c31\u89e3\u51b3\u4e86\u4e24\u4e24\u4e24\u4e2a\u6570\u636e\u5e93\uff0c\u5982\u679c\u8bf4\u5176\u4e2d\u4e00\u4e2a\u62a5\u9519\u6b3e\u6211\u4eec\u80af\u5b9a\u662f\u8981\u56de\u6b3e\u7684\uff0c\u6211\u4eec\u76ee\u524d\u6ca1\u6709\u56de\u6b3e\u7684\u884c\u4e3a\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u5728\u8fd9\u91cc\u9762\u52a0\u4e00\u4e2a\u52a0\u4e2atransaction\u3002Try second one. Look back for exception. \u53ef\u4ee5\u4e86\uff0c\u73b0\u5728\u7684\u8bdd\u76f8\u5f53\u4e8e\u6211\u4eec\u5f88\u591a\u7684\u4e1a\u52a1\u903b\u8f91\u90fd\u5df2\u7ecf\u5b8c\u5584\u4e86\uff0c\u6211\u4eec\u63a5\u4e0b\u6765\u7684\u8bfe\u65f6\u5c31\u8981\u5f00\u59cb\u53bb\u505a\u4ec0\u4e48\uff1f\u505a\u6211\u4eec\u7684\u5fae\u670d\u52a1\u67b6\u6784\u7684\u4e00\u4e2a\u8f6c\u53d8\u4e86\uff0c<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;\u8fd9\u91cc\u6211\u8fd0\u884cvue\u6587\u4ef6\uff0c\u641e\u5f97\u6211\u597d\u9ebb\u70e6\uff0c\u6211\u9009\u5728idea\u4e00\u6b21\u6027\u628a node-sass\u7f16\u8bd1\u5931\u8d25 \u66ff\u6362\u4e3asass \u7136\u540einsta &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[3],"tags":[16,20],"class_list":["post-1213","post","type-post","status-publish","format-standard","hentry","category-3","tag-sql","tag-20"],"_links":{"self":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1213"}],"version-history":[{"count":1,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1213\/revisions"}],"predecessor-version":[{"id":1219,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1213\/revisions\/1219"}],"wp:attachment":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}