{"id":1220,"date":"2025-07-18T10:18:43","date_gmt":"2025-07-18T02:18:43","guid":{"rendered":"https:\/\/eve2333.top\/?p=1220"},"modified":"2025-07-18T10:18:44","modified_gmt":"2025-07-18T02:18:44","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-11-%e5%be%ae%e6%9c%8d%e5%8a%a1%e6%94%b9%e9%80%a0","status":"publish","type":"post","link":"https:\/\/eve2333.top\/?p=1220","title":{"rendered":"SaaS\u77ed\u94fe\u63a5\u7cfb\u7edf-\u65b0\u624b\u4ece\u96f6\u5b66\u4e60 11. \u5fae\u670d\u52a1\u6539\u9020"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">- \u7b2c01\u8282\uff1a\u5982\u4f55\u6539\u9020\u4e3a\u5fae\u670d\u52a1\u67b6\u6784\uff1f<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"udjuc\"><strong>1. \u6a21\u5757\u5316\u548c\u72ec\u7acb\u6027<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5fae\u670d\u52a1\uff1a\u5fae\u670d\u52a1\u67b6\u6784\u901a\u8fc7\u5c06\u5e94\u7528\u62c6\u5206\u4e3a\u5c0f\u578b\u3001\u72ec\u7acb\u7684\u670d\u52a1\uff0c\u6bcf\u4e2a\u670d\u52a1\u4e13\u6ce8\u4e8e\u7279\u5b9a\u7684\u4e1a\u52a1\u529f\u80fd\u3002\u8fd9\u79cd\u6a21\u5757\u5316\u7684\u8bbe\u8ba1\u4f7f\u5f97\u6bcf\u4e2a\u670d\u52a1\u90fd\u53ef\u4ee5\u72ec\u7acb\u5f00\u53d1\u3001\u90e8\u7f72\u3001\u6269\u5c55\u548c\u7ef4\u62a4\u3002<\/strong><\/li>\n\n\n\n<li><strong>\u5355\u4f53\u670d\u52a1\uff1a\u5728\u5355\u4f53\u670d\u52a1\u4e2d\uff0c\u5e94\u7528\u662f\u4e00\u4e2a\u5927\u800c\u81c3\u80bf\u7684\u5355\u4e00\u5355\u5143\uff0c\u4fee\u6539\u4e00\u4e2a\u529f\u80fd\u53ef\u80fd\u4f1a\u5f71\u54cd\u6574\u4e2a\u5e94\u7528\u7684\u90e8\u7f72\u3002<\/strong>\u00a0<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"FJFbR\"><strong>2. \u6280\u672f\u5f02\u6784\u6027<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5fae\u670d\u52a1\uff1a\u5141\u8bb8\u4f7f\u7528\u4e0d\u540c\u7684\u6280\u672f\u6808\u548c\u7f16\u7a0b\u8bed\u8a00\u6765\u6784\u5efa\u4e0d\u540c\u7684\u670d\u52a1\uff0c\u4ee5\u9002\u5e94\u4e0d\u540c\u7684\u9700\u6c42\u3002\u6bcf\u4e2a\u5fae\u670d\u52a1\u53ef\u4ee5\u9009\u62e9\u6700\u9002\u5408\u5176\u7279\u5b9a\u4efb\u52a1\u7684\u6280\u672f\u3002<\/strong><\/li>\n\n\n\n<li><strong>\u5355\u4f53\u670d\u52a1\uff1a\u901a\u5e38\u9700\u8981\u5728\u540c\u4e00\u6280\u672f\u6808\u4e0b\u6784\u5efa\u6574\u4e2a\u5e94\u7528\u3002<\/strong><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"I1XeW\">3. \u72ec\u7acb\u90e8\u7f72\u548c\u6269\u5c55<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5fae\u670d\u52a1\uff1a\u5141\u8bb8\u72ec\u7acb\u90e8\u7f72\u548c\u6269\u5c55\u6bcf\u4e2a\u670d\u52a1\uff0c\u8fd9\u6837\u53ef\u4ee5\u66f4\u7075\u6d3b\u5730\u5e94\u5bf9\u6d41\u91cf\u53d8\u5316\u548c\u9700\u6c42\u53d8\u66f4\u3002<\/li>\n\n\n\n<li>\u5355\u4f53\u670d\u52a1\uff1a\u9700\u8981\u6574\u4f53\u90e8\u7f72\u548c\u6269\u5c55\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u8d44\u6e90\u6d6a\u8d39\u6216\u6027\u80fd\u74f6\u9888\u3002<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ERuzT\">4. \u56e2\u961f\u81ea\u6cbb<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5fae\u670d\u52a1\uff1a\u6bcf\u4e2a\u5fae\u670d\u52a1\u901a\u5e38\u7531\u4e00\u4e2a\u5c0f\u56e2\u961f\u8d1f\u8d23\uff0c\u56e2\u961f\u53ef\u4ee5\u6839\u636e\u5176\u670d\u52a1\u7684\u9700\u6c42\u8fdb\u884c\u72ec\u7acb\u7684\u51b3\u7b56\uff0c\u63d0\u9ad8\u4e86\u5f00\u53d1\u56e2\u961f\u7684\u81ea\u6cbb\u6027\u3002<\/li>\n\n\n\n<li>\u5355\u4f53\u670d\u52a1\uff1a\u6574\u4e2a\u5e94\u7528\u7684\u53d8\u66f4\u9700\u8981\u534f\u8c03\u6574\u4e2a\u56e2\u961f\uff0c\u53ef\u80fd\u5bfc\u81f4\u5f00\u53d1\u901f\u5ea6\u8f83\u6162\u548c\u6c9f\u901a\u6210\u672c\u8f83\u9ad8\u3002<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"MG3GO\"><strong>5. \u5f39\u6027\u548c\u5bb9\u9519\u6027<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5fae\u670d\u52a1\uff1a\u7531\u4e8e\u6bcf\u4e2a\u670d\u52a1\u90fd\u662f\u72ec\u7acb\u7684\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5b9e\u73b0\u670d\u52a1\u7684\u5f39\u6027\u548c\u5bb9\u9519\u3002\u4e00\u4e2a\u670d\u52a1\u7684\u6545\u969c\u4e0d\u4f1a\u5f71\u54cd\u6574\u4e2a\u5e94\u7528\u3002<\/strong><\/li>\n\n\n\n<li><strong>\u5355\u4f53\u670d\u52a1\uff1a\u4e00\u4e2a\u7ec4\u4ef6\u7684\u6545\u969c\u53ef\u80fd\u5bfc\u81f4\u6574\u4e2a\u5e94\u7528\u7684\u5d29\u6e83\u3002<\/strong><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"nnzhr\"><strong>6. \u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6d4b\u8bd5\u6027<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5fae\u670d\u52a1\uff1a\u6bcf\u4e2a\u5fae\u670d\u52a1\u7684\u5c0f\u89c4\u6a21\u548c\u6e05\u6670\u7684\u804c\u8d23\u8303\u56f4\u4f7f\u5f97\u4ee3\u7801\u66f4\u5bb9\u6613\u7406\u89e3\u3001\u7ef4\u62a4\u548c\u6d4b\u8bd5\u3002<\/strong><\/li>\n\n\n\n<li><strong>\u5355\u4f53\u670d\u52a1\uff1a\u5355\u4f53\u5e94\u7528\u7684\u590d\u6742\u6027\u53ef\u80fd\u5bfc\u81f4\u4ee3\u7801\u96be\u4ee5\u7406\u89e3\uff0c\u96be\u4ee5\u7ef4\u62a4\u548c\u6d4b\u8bd5\u3002<\/strong><\/li>\n<\/ul>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"215\" width=\"509\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/e084bdbcb0f9451fa1673fab7ce85c1a.png\" alt=\"\"><\/p>\n\n\n\n<p>\u7136\u540e\u8fd9\u4e2a\u65f6\u5019\u5230\u6211\u4eec\u7684\u7b2c\u4e8c\u7248\u672c\uff0c \u56db\u4e2a\u5e94\u7528\u662f\u5206\u522b\u7684\u5e94\u7528\uff0c<img loading=\"lazy\" decoding=\"async\" height=\"195\" width=\"521\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/c92a2561944f4f389458f8c9c908edf9.png\" alt=\"\"><\/p>\n\n\n\n<p>&nbsp;\u5f53\u7136\u4e5f\u4f1a\u770b\u5230nginx\u6765\u5b9e\u73b0\uff0c\u8fd9\u65f6\u4f1a\u505a\u4e00\u4e2a\u5927\u7684\u865a\u62df\u4f53<\/p>\n\n\n\n<p>\u5982\u679c\u73ed\u7ea7\u8c03\u7528\u7684\u8bdd\u6211\u4eec\u6211\u4eec\u73b0\u5728\u77ed\u94fe\u63a5\u91cc\u9762\u662f\u600e\u4e48\u505a\u7684\uff0c\u77e5\u9053\u4ed6\u7684IP\u548c\u7aef\u53e3\uff1b\u6211\u4eec\u5f53\u524d\u7684\u903b\u8f91\u5c31\u662f\u8fd9\u4e48\u53bb\u5b9e\u73b0 \u7684\uff1b\u4f46\u662f\u5982\u679c\u6211\u4eec\u7684\u4eba\u5458\u67093\u4e2a\u5e94\u7528\u96c6\u7fa4\uff0c\u90a3\u4e48localhost8080\u5c31\u4e0d\u884c\u7684\uff0c\u5982\u4e0b\u56fe<img loading=\"lazy\" decoding=\"async\" height=\"238\" width=\"584\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/1b9ae8f90e364802bafcd977dcb8c533.png\" alt=\"\"><\/p>\n\n\n\n<p>\u4e8e\u662f\u6211\u4eec\u9700\u8981\u4e00\u4e2a\u6ce8\u518c\u4e2d\u5fc3nacos\uff0c\u90a3\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u5047\u5982\u8bf4\u6211\u4eec\u73ed\u7ea7\u670d\u52a1\u60f3\u8981\u8c03\u4eba\u5458\u670d\u52a1\u8be5\u600e\u4e48\u529e\uff0c\u8981\u77e5\u90533\u4e2a\u5e94\u7528\u7684\u5177\u4f53ip\uff1b\u56e0\u6b64\u5728\u5e94\u7528\u542f\u52a8\u7684\u65f6\u5019\u53d1\u8d77\u670d\u52a1\u6ce8\u518c\uff1b\u9644\u5e26\u7684\u6d88\u606f\u91cc\u9762\u5fc5\u7136\u6709\u7279\u5f81\uff1a\u5305\u62ec\u670d\u52a1\u540d\u548cip\uff1b<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"394\" width=\"585\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/8b9abea1fd734c1caa2e5242efb34594.png\" alt=\"\"><\/p>\n\n\n\n<p>\u73ed\u7ea7\u5e94\u7528\u4e2d\u4ed6\u4e0d\u9700\u8981\u88ab\u5916\u90e8\u6240\u8c03\u7528\uff0c\u90a3\u4ed6\u5c31\u6ca1\u5fc5\u8981\u53bb\u53d1\u8d77\u6ce8\u518c\uff1b\u4f46\u662f\u5462\u4ed6\u9700\u8981\u8c03\u7528\u8fd9\u4e2a\u4eba\u5458\u670d\u52a1\uff0c\u90a3\u5c31\u9700\u8981\u53bb\u62c9\u53d6\uff1bperson service\u6240\u5bf9\u5e94\u7684<\/p>\n\n\n\n<p>\u8981\u628a\u8fd9\u4e2a\u6211\u4eec\u8981\u8c03\u7528\u7684\u8fd9\u4e2a\u5e94\u7528\u5b83\u5bf9\u5e94\u7684\u5143\u670d\u52a1\u4fe1\u606f\u5143\u6570\u636e\u7ed9\u62ff\u5230\u6211\u4eec\u672c\u5730\u6765\uff1b\u8fd9\u6837\u6211\u4eec\u5728\u8c03\u7528\u7684\u65f6\u5019\u6839\u636e\u6211\u4eec\u7684\u8c03\u7528\u6807\u8bc6\u662f\u4ed6\u7684\u670d\u52a1\u540d\uff1b\u6839\u636e\u670d\u52a1\u540d\u67e5\u8be2\u4e0b\u9762\u7684ip\uff1b<img loading=\"lazy\" decoding=\"async\" height=\"309\" width=\"648\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/f55fb97abceb4165a7936d080222f93e.png\" alt=\"\"><\/p>\n\n\n\n<p>&nbsp;\u5982\u679c\u8bf4\u6211\u91cd\u65b0\u53d1\u5e03\u4e86\uff0cip\u662f\u65b0\u7684\u600e\u4e48\u529e\uff1f\uff1f\uff1f\u5b9e\u9645\u4e0a\u4ed6\u4f1a\u5411nacos\u53d1\u8d77\u6ce8\u9500\u63a5\u53e3\uff0c\u628a\u5f53\u524d\u7684\u5b9e\u4f8b\u6ce8\u9500\u6389\uff1b\u670d\u52a1\u4e0b\u9762\u591a\u89c1\u7684\u662fip\u8bb0\u5f55\u7684\uff1b<br>\u90a3\u4e48remove\u6389\u540e\u4ed6\u7684\u8fd9\u4e2a\u5462\u5bf9\u5e94\u7684IP\u4ed6\u5982\u679c\u4e0d\u53d8\u7684\u8bdd\uff0c\u6211\u53bb\u8c03\u7528\u4ed6\u7684\uff0c\u5c82\u4e0d\u662f\u4f1a\u5931\u8d25\u5417\uff1b\u6709\u4e00\u4e2a\u4f18\u96c5\u4e0a\u4e0b\u7ebf\u7684\u95ee\u9898\uff1b\uff08\u8be6\u89c1\u5927\u8bdd\u9762\u8bd5\uff09<\/p>\n\n\n\n<p>\u628a\u8fd9\u4e2a\u5fae\u670d\u52a1\u91cc\u9762\u7684\u6ce8\u518c\u4e2d\u5fc3\u8bf4\u4e00\u4e0b\u8fd8\u6709sentinel\u5b83\u4e3b\u8981\u5c31\u662f\u505a\u8fd9\u4e2a\u5c01\u63a7<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"f0A1O\">\u77ed\u94fe\u63a5\u5982\u4f55\u6539\u9020\u5fae\u670d\u52a1<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"B9L4i\">1. \u4e0b\u8f7d Nacos<\/h3>\n\n\n\n<p id=\"u83b607d4\">\u4e4b\u524d 12306 \u672c\u5730\u5b89\u88c5\u7684 Nacos 2.1.1 \u7248\u672c\u662f\u5426\u53ef\u7528\uff1f\u53ef\u4ee5\uff0c\u5982\u679c\u4e4b\u524d\u5df2\u7ecf\u5b89\u88c5 Nacos\uff0c\u672c\u8282\u8df3\u8fc7\u3002<\/p>\n\n\n\n<p id=\"u2262273d\">Nacos GitHub 2.1.1\u4e0b\u8f7d\u5730\u5740\uff1a<a href=\"https:\/\/github.com\/alibaba\/nacos\/releases\/tag\/2.1.1\" target=\"_blank\"  rel=\"nofollow\" >Release 2.1.1 (Aug 8th, 2022) \u00b7 alibaba\/nacos<\/a><\/p>\n\n\n\n<p id=\"u978f5575\">Nacos \u90e8\u7f72\u624b\u518c\uff1a<a href=\"https:\/\/nacos.io\/docs\/v2\/guide\/admin\/deployment\/\" target=\"_blank\"  rel=\"nofollow\" >Nacos\u652f\u6301\u4e09\u79cd\u90e8\u7f72\u6a21\u5f0f | Nacos \u5b98\u7f51<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.cnblogs.com\/zxtceq\/articles\/17916153.html\" target=\"_blank\"  rel=\"nofollow\" >Nacos\u4e0b\u8f7d\u3001\u5b89\u88c5\u3001\u4f7f\u7528\u5165\u95e8\u7ea7\u6559\u7a0b\uff08windows\u7248\uff09 - \u4ece\u672a\u88ab\u8d85\u8d8a - \u535a\u5ba2\u56ed<\/a><\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"1162\" width=\"1801\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/27185170b5b24a93b11bd35c8877088c.png\" alt=\"\">\u8d26\u53f7\u5bc6\u7801\u90fd\u662fnacos<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"iJZYM\">2. \u670d\u52a1\u4e2d\u5f15\u5165 Nacos \u8fdb\u884c\u670d\u52a1\u6ce8\u518c<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"KijYO\">2.1. \u5f15\u5165 Pom \u6587\u4ef6<\/h4>\n\n\n\n<p id=\"u1a81f906\">\u670d\u52a1\u81ea\u4e3b\u53d1\u8d77\u6ce8\u518c\u3002<\/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-nacos-discovery&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n\n\n\n<p>\u5982\u679c\u662f\u8c03\u7528\u65b9\uff0c\u9700\u8981\u5f15\u5165 OpenFeign \u7ec4\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n\n&lt;!-- openfeign \u5df2\u4e0d\u518d\u63d0\u4f9b\u9ed8\u8ba4\u8d1f\u8f7d\u5747\u8861\u5668 --&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-loadbalancer&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n\n\n\n<p>\u542f\u52a8\u7c7b\u6dfb\u52a0 Nacos \u6ce8\u518c\u4e2d\u5fc3\u6ce8\u89e3<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@EnableDiscoveryClient<\/code><\/pre>\n\n\n\n<p>&nbsp;2.2. \u914d\u7f6e yaml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spring:\n  cloud:\n    nacos:\n      discovery:\n        server-addr: 127.0.0.1:8848<\/code><\/pre>\n\n\n\n<p>&nbsp;\u6539\u9020\u73b0\u6709\u4ee3\u7801\u901a\u8fc7 OpenFeign<\/p>\n\n\n\n<p>\u8c03\u7528\u521b\u5efa OpenFeign \u8fdc\u7a0b\u8c03\u7528\u670d\u52a1<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@FeignClient(\"short-link-project\")\npublic interface ShortLinkActualRemoteService {\n\t\/\/ \u8c03\u7528\u63a5\u53e3\n}<\/code><\/pre>\n\n\n\n<p>\u4e1a\u52a1\u4ee3\u7801\u4e2d\u5f15\u7528<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\nshortLinkActualRemoteService.xxx();<\/code><\/pre>\n\n\n\n<p>\u5fae\u670d\u52a1\u600e\u4e48\u6539\u9020\uff1f\u9996\u5148\u7b2c\u4e00\u4e0b\u8f7dNacos\u3002\u7b2c\u4e8c\uff0c\u670d\u52a1\u4e2d\u5f15\u5165Nacos\uff0c\u8fdb\u884c\u670d\u52a1\u6ce8\u518c\u3002\u7b2c\u4e09\uff0c\u6539\u9020\u73b0\u6709\u4ee3\u7801\u901a\u8fc7OpenFeign\u8c03\u7528\u3002\u518d\u7136\u540e\u662f\u7f51\u5173\u3002Spring Cloud Gateway\u91cd\u6784\u3002\u524d\u9762\u4e09\u4e2a\u6bd4\u8f83\u5bb9\u6613\u7406\u89e3\uff0c\u6211\u4eec\u628aNacos\u4e0b\u8f7d\u5230\u672c\u5730\u5bf9\u5427\uff1f\u8ba9\u5b83\u542f\u52a8\u8d77\u6765\uff0c\u7136\u540e\u6211\u4eec\u5728\u670d\u52a1\u91cc\u9762\u5f15\u5165Nacos\u76f8\u5173\u7684\u5305\uff0c\u7136\u540e\u628a\u81ea\u5df1\u5f53\u524d\u7684\u670d\u52a1\u6ce8\u518c\u5230Nacos\u4e0a\u9762\u53bb\uff0c\u7136\u540e\u6211\u4eec\u5728\u8c03\u7528\u7684\u65f6\u5019\u901a\u8fc7OpenFeign\u53bb\u53d1\u8d77\u8c03\u7528\uff0c\u5b83\u7684\u539f\u7406\u5c31\u662f\u4f20\u5165\u4e00\u4e2a\u670d\u52a1\u540d\uff0c\u6bd4\u5982\u8bf4\u6211\u4f20\u4e00\u4e2aperson-service\uff0c\u7136\u540e\u5b83\u4f1a\u901a\u8fc7\u4e00\u7cfb\u5217\u89c4\u5219\u62ff\u5230\u5bf9\u5e94\u7684\u4e00\u4e9b\u53ef\u7528IP\u3002\u5f53\u7136\u8fd9\u4e9b\u6709\u7b56\u7565\uff0c\u9ed8\u8ba4\u7684\u8bdd\u6211\u8bb0\u5f97\u662f\u8f6e\u8be2\uff0c\u6211\u8bb0\u5f97\u9ed8\u8ba4\u5e94\u8be5\u662f\u8f6e\u8be2\uff0c\u8fd8\u662f\u4ec0\u4e48\u6211\u6709\u70b9\u8bb0\u4e0d\u6e05\u4e86\u3002\u6211\u8bb0\u5f97\u5f53\u65f6\u597d\u50cf\u662fRegion\u90a3\u79cd\u5f62\u5f0f\uff0c\u597d\u50cf\u662f\u5565\u6211\u6709\u70b9\u8bb0\u4e0d\u6e05\u4e86\uff0c\u4e4b\u524d\u6211\u8bb0\u5f97\u8fd8\u770b\u8fc7\u4ed6\u4eec\u7684\u6e90\u7801\u6765\u7740\uff0c\u7136\u540e\u62ff\u5230\u4e00\u4e2a\u53ef\u7528\u7684IP\u4e4b\u540e\uff0c\u6211\u4eec\u5e72\u4ec0\u4e48\uff1f\u6211\u4eec\u76f4\u63a5\u548cURL\u4e00\u62fc\uff0c\u62fc\u597d\u4e4b\u540e\u53d1\u8d77\u8c03\u7528\uff0c\u7136\u540e\u62ff\u5230\u7ed3\u679c\u8fd4\u56de\u3002\u7136\u540e\u81f3\u6b64\u7684\u8bdd\uff0c\u6211\u4eec\u5c31\u6539\u9020\u6210\u8fd9\u79cd\u57fa\u4e8e\u5fae\u670d\u52a1\u67b6\u6784\u4e0b\u7684\u591a\u670d\u52a1\u8c03\u7528\uff0c\u5230\u8fd9\u91cc\u7684\u8bdd\uff0c\u6211\u4eec\u7684\u5fae\u670d\u52a1\u6539\u9020\u5df2\u7ecf\u7b97\u662f\u5b8c\u6210\u4e86\uff0c\u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\u6211\u4eec\u751f\u4ea7\u73af\u5883\u90fd\u5df2\u7ecf\u90e8\u7f72\u4e86\u5bf9\u5427\uff1f\u57fa\u4e8e\u662f\u4e0d\u77e5\u9053\u963f\u91cc\u5df4\u5df4\u7684\u751f\u4ea7\u73af\u5883\u7684\uff0c\u7136\u540e\u6211\u4eec\u628a\u670d\u52a1\u6ce8\u518c\u5230Nacos\u91cc\u9762\u53bb\uff0c\u7136\u540e\u901a\u8fc7OpenFeign\u505a\u591a\u670d\u52a1\u4e4b\u95f4\u7684\u8c03\u7528\uff0c\u7136\u540e\u6211\u4eec\u4f1a\u628a\u8ba4\u8bc1\u7528\u6237\u7684\u4e00\u4e9b\u4fe1\u606f\u91cd\u6784\u5230\u6211\u4eec\u7684Spring Cloud Gateway\u91cc\u9762\u53bb\u3002<\/p>\n\n\n\n<p>\u53ef\u80fd\u6709\u540c\u5b66\u4f1a\u8bf4\uff0c\u6211\u4eec\u4e3a\u4ec0\u4e48\u8981\u628a\u76f8\u5173\u7684\u4e00\u4e9b\u9a8c\u8bc1\u653e\u5230\u7cfb\u7edf\u7684\u5916\u56f4\uff0c\u653e\u5230\u73b0\u5728\u7684\u7f51\u5173\u91cc\u9762\uff0c\u6211\u89c9\u5f97\u4e5f\u633a\u597d\u7684\u3002\u5176\u5b9e\u8fd9\u4f1a\u6d89\u53ca\u5230\u4e00\u4e2a\u8d44\u6e90\u5229\u7528\u7684\u95ee\u9898\uff0c\u4ee5\u53ca\u670d\u52a1\u8fb9\u754c\u7684\u4e8b\u60c5\u3002\u9996\u5148\u5982\u679c\u8bf4\u7eaf\u7cb9\u7684\u4ece\u5fae\u670d\u52a1\u7684\u89d2\u5ea6\u4e0a\u53bb\u770b\u7684\u8bdd\uff0c\u666e\u5361\uff08Nacos\uff09\u7ed9\u5b83\u62e5\u6709\u66f4\u597d\u7684\u6027\u80fd\uff0c\u5047\u5982\u8bf4\u4f60\u5f53\u524d\u7684\u7528\u6237\u6ca1\u6709\u767b\u5f55\uff0c\u4f60\u8981\u5728\u7f51\u5173\u91cc\u9762\u53bb\u9a8c\u8bc1\u7684\u8bdd\uff0c\u5b83\u4f1a\u5360\u7528\u5f53\u524d\u7684\u8fde\u63a5\u4ee5\u53ca\u5f53\u524d\u7684\u5904\u7406\u7ebf\u7a0b\uff0c\u4f60\u5982\u679c\u8bf4\u9a8c\u8bc1\u7684\u65f6\u5019\u5360\u7528\u4e86\u5176\u4ed6\u8d44\u6e90\uff0c\u8bbf\u95ee\u8d44\u6e90\u5c31\u5f97\u6392\u961f\u3002\u5982\u679c\u8bf4\u4f60\u5728\u7f51\u5173\u91cc\u9762\u53bb\u505a\uff0c\u56e0\u4e3a\u5b83\u662f\u57fa\u4e8eReactor\u7684\u54cd\u5e94\u5f0f\u6a21\u578b\uff0c\u5b83\u662f\u5f88\u5feb\u7684\uff0c\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u628a\u4e00\u4e9b\u6bd4\u8f83\u901a\u7528\u7684\u6216\u8005\u8bf4\u516c\u7528\u7684\u4e1c\u897f\u80fd\u62bd\u51fa\u6765\u7684\uff0c\u90fd\u5c3d\u91cf\u653e\u5230\u7f51\u5173\u91cc\u9762\u53bb\u505a\uff0c\u6bd4\u5982\u8bf4\u7528\u6237\u8ba4\u8bc1\uff0c\u7136\u540e\u9274\u6743\u5c31\u662f\u9a8c\u7b7e\uff0c\u6211\u4eec\u90fd\u5e94\u8be5\u653e\u5230\u7f51\u5173\u3002\u7136\u540e\u56e0\u4e3a\u6211\u4eecSpring Cloud Gateway\uff0c\u600e\u4e48\u8bf4\uff0c\u6211\u4e2a\u4eba\u8fd8\u633a\u4e0d\u770b\u597d\u5b83\u7684\uff0c\u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\u5b83\u7684\u95ee\u9898\u633a\u591a\u7684\uff0c\u5982\u679c\u8bf4\u4f60\u771f\u6b63\u751f\u4ea7\u7528\u8fc7\u7684\u8bdd\u8fd8\u633a\u591a\u7684\uff0c\u4f46\u662f\u600e\u4e48\u8bf4\uff0c\u56e0\u4e3a\u5b83\u662fSpring Cloud\u7684\u5b98\u65b9\u7ec4\u4ef6\uff0c\u7cfb\u5217\u6574\u5408\u91cc\u9762\u5c31\u662f\u5f00\u7bb1\u5373\u7528\u4e00\u4e9b\u529f\u80fd\uff0c\u6240\u4ee5\u8bf4\u7528\u5b83\u7684\u4eba\u4f1a\u6bd4\u8f83\u591a\uff0c\u4f46\u662f\u8fd9\u4e0d\u610f\u5473\u7740\u5b83\u6ca1\u6709\u95ee\u9898\uff0c\u6240\u4ee5\u8bf4\u5927\u5bb6\u4ee5\u540e\u5728\u516c\u53f8\u751f\u4ea7\u91cc\u9762\u505a\u7f51\u5173\u8c03\u7814\u7684\u8bdd\uff0c\u53ef\u4ee5\u597d\u597d\u53bb\u8c03\u7814\u4e00\u4e0b\uff0c\u5c3d\u91cf\u5728\u8bf4\u5c3d\u91cf\u80fd\u5f15\u5165\u6bd4\u8f83\u65b0\u7684Spring Cloud Gateway\u7248\u672c\u5c31\u5f15\u5165\u65b0\u7684\uff0c\u56e0\u4e3a\u8001\u7248\u672c\u53ef\u80fd\u4f1a\u6bd4\u8f83\u591a\u597d\u5427\uff1f\u4f60\u8981\u77e5\u9053\u5f15\u5165\u4e00\u4e2a\u7248\u672c\u4e4b\u540e\uff0c\u8981\u60f3\u5f80\u540e\u5347\u7ea7\u662f\u6709\u70b9\u9ebb\u70e6\u7684\uff0c\u56e0\u4e3a\u4f60\u8981\u5012\u4e0d\u662f\u8bf4\u4e0d\u80fd\u5347\uff0c\u800c\u662f\u8bf4\u4f60\u5347\u7ea7\u7684\u8bdd\uff0c\u5b83\u5bf9\u5e94\u7684\u4e00\u7cfb\u5217\u9a8c\u8bc1\u903b\u8f91\u5c31\u4f1a\u975e\u5e38\u590d\u6742\uff0c\u5c24\u5176\u662f\u50cf\u7f51\u5173\u8fd9\u79cd\u95e8\u6237\u2014\u2014\u6574\u4e2a\u7cfb\u7edf\u7684\u524d\u7f6e\u95e8\u6237\uff0c\u5bf9\u5427\uff1f\u6539\u4e00\u5904\u6240\u6709\u7684\u90fd\u5f97\u8ddf\u7740\uff0c\u6240\u6709\u53ef\u80fd\u90fd\u4f1a\u6709\u5f71\u54cd\u7684\u8fd9\u79cd\u614e\u4e4b\u53c8\u614e\u3002\u6240\u4ee5\u8bf4\u5927\u5bb6\u8981\u7406\u667a\u4e00\u4e9b\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c02\u8282\uff1a\u5982\u4f55\u5c06\u9879\u76ee\u6539\u9020\u4e3a\u5fae\u670d\u52a1\u8c03\u7528\uff08\u4e0a\uff09<\/h2>\n\n\n\n<p>\u4e3aadmin\u7684pom\u6dfb\u52a0<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;dependency&gt;\n    &lt;groupId&gt;com.alibaba.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n\n&lt;!-- openfeign \u5df2\u4e0d\u518d\u63d0\u4f9b\u9ed8\u8ba4\u8d1f\u8f7d\u5747\u8861\u5668 --&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-loadbalancer&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/pre>\n\n\n\n<p>\u4e3aproject\u7684pom\u6dfb\u52a0<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&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;\n\n&lt;dependency&gt;\n    &lt;groupId&gt;com.alibaba.cloud&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/pre>\n\n\n\n<p>\u4e3a\u542f\u52a8\u670d\u52a1\u6dfb\u52a0ShortLinkAdminApplication<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import org.springframework.cloud.client.discovery.EnableDiscoveryClient;\nimport org.springframework.cloud.openfeign.EnableFeignClients;\n\n@SpringBootApplication\n@EnableDiscoveryClient\n@EnableFeignClients(\"com.nageoffer.shortlink.admin.remote\")\n@MapperScan(\"com.nageoffer.shortlink.admin.dao.mapper\")<\/pre>\n\n\n\n<p>&nbsp;\u914d\u7f6eyaml<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">spring:\n  application:\n    name: short-link-admin\n  datasource:\n    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver\n    url: jdbc:shardingsphere:classpath:shardingsphere-config.yaml\n  data:\n    redis:\n      host: 192.168.111.130\n      password: 123321\n      port: 6379\n  cloud:\n    nacos:\n      discovery:\n        server-addr: 127.0.0.1:8848<\/pre>\n\n\n\n<p>\u6709\u4e00\u4e2ah2\u7684\u5d4c\u5165\u5f0f\u5185\u5b58\u6570\u636e\u5e93\uff0c\u6211\u4eec\u5df2\u7ecf\u914d\u4e86mysql\u7684\u6570\u636e\u5e93<\/p>\n\n\n\n<p>\u63a5\u4e0b\u6765\u7684\u6539\u9020\u5c31\u662f\u628aremote\u6765\u6539\u4e00\u4e0b\uff0c\u65b0\u5efaShortLinkActualRemoteService\uff0c\u5220\u9664\u539f\u6765\u7684remoteservice<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.admin.remote;\n\n\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinRecoverReqDTO;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinRemoveReqDTO;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinSaveReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkBatchCreateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkCreateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkUpdateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkBatchCreateRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkCreateRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkGroupCountQueryRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkPageRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkStatsAccessRecordRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkStatsRespDTO;\nimport org.springframework.cloud.openfeign.FeignClient;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u4e2d\u53f0\u8fdc\u7a0b\u8c03\u7528\u670d\u52a1\n *\/\n@FeignClient(\"short-link-project\")\npublic interface ShortLinkActualRemoteService {\n\n    \/**\n     * \u521b\u5efa\u77ed\u94fe\u63a5\n     *\n     * @param requestParam \u521b\u5efa\u77ed\u94fe\u63a5\u8bf7\u6c42\u53c2\u6570\n     * @return \u77ed\u94fe\u63a5\u521b\u5efa\u54cd\u5e94\n     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/create\")\n    Result&lt;ShortLinkCreateRespDTO&gt; createShortLink(@RequestBody ShortLinkCreateReqDTO requestParam);\n\n    \/**\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     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/create\/batch\")\n    Result&lt;ShortLinkBatchCreateRespDTO&gt; batchCreateShortLink(@RequestBody ShortLinkBatchCreateReqDTO requestParam);\n\n    \/**\n     * \u4fee\u6539\u77ed\u94fe\u63a5\n     *\n     * @param requestParam \u4fee\u6539\u77ed\u94fe\u63a5\u8bf7\u6c42\u53c2\u6570\n     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/update\")\n    void updateShortLink(@RequestBody ShortLinkUpdateReqDTO requestParam);\n\n    \/**\n     * \u5206\u9875\u67e5\u8be2\u77ed\u94fe\u63a5\n     *\n     * @param gid      \u5206\u7ec4\u6807\u8bc6\n     * @param orderTag \u6392\u5e8f\u7c7b\u578b\n     * @param current  \u5f53\u524d\u9875\n     * @param size     \u5f53\u524d\u6570\u636e\u591a\u5c11\n     * @return \u67e5\u8be2\u77ed\u94fe\u63a5\u54cd\u5e94\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/page\")\n    Result&lt;Page&lt;ShortLinkPageRespDTO&gt;&gt; pageShortLink(@RequestParam(\"gid\") String gid,\n                                                     @RequestParam(\"orderTag\") String orderTag,\n                                                     @RequestParam(\"current\") Long current,\n                                                     @RequestParam(\"size\") Long size);\n\n    \/**\n     * \u67e5\u8be2\u5206\u7ec4\u77ed\u94fe\u63a5\u603b\u91cf\n     *\n     * @param requestParam \u5206\u7ec4\u77ed\u94fe\u63a5\u603b\u91cf\u8bf7\u6c42\u53c2\u6570\n     * @return \u67e5\u8be2\u5206\u7ec4\u77ed\u94fe\u63a5\u603b\u91cf\u54cd\u5e94\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/count\")\n    Result&lt;List&lt;ShortLinkGroupCountQueryRespDTO&gt;&gt; listGroupShortLinkCount(@RequestParam(\"requestParam\") List&lt;String&gt; requestParam);\n\n    \/**\n     * \u6839\u636e URL \u83b7\u53d6\u6807\u9898\n     *\n     * @param url \u76ee\u6807\u7f51\u7ad9\u5730\u5740\n     * @return \u7f51\u7ad9\u6807\u9898\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/title\")\n    Result&lt;String&gt; getTitleByUrl(@RequestParam(\"url\") String url);\n\n    \/**\n     * \u4fdd\u5b58\u56de\u6536\u7ad9\n     *\n     * @param requestParam \u8bf7\u6c42\u53c2\u6570\n     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/recycle-bin\/save\")\n    void saveRecycleBin(@RequestBody RecycleBinSaveReqDTO requestParam);\n\n    \/**\n     * \u5206\u9875\u67e5\u8be2\u56de\u6536\u7ad9\u77ed\u94fe\u63a5\n     *\n     * @param gidList \u5206\u7ec4\u6807\u8bc6\u96c6\u5408\n     * @param current \u5f53\u524d\u9875\n     * @param size    \u5f53\u524d\u6570\u636e\u591a\u5c11\n     * @return \u67e5\u8be2\u77ed\u94fe\u63a5\u54cd\u5e94\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/recycle-bin\/page\")\n    Result&lt;Page&lt;ShortLinkPageRespDTO&gt;&gt; pageRecycleBinShortLink(@RequestParam(\"gidList\") List&lt;String&gt; gidList,\n                                                               @RequestParam(\"current\") Long current,\n                                                               @RequestParam(\"size\") Long size);\n\n    \/**\n     * \u6062\u590d\u77ed\u94fe\u63a5\n     *\n     * @param requestParam \u77ed\u94fe\u63a5\u6062\u590d\u8bf7\u6c42\u53c2\u6570\n     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/recycle-bin\/recover\")\n    void recoverRecycleBin(@RequestBody RecycleBinRecoverReqDTO requestParam);\n\n    \/**\n     * \u79fb\u9664\u77ed\u94fe\u63a5\n     *\n     * @param requestParam \u77ed\u94fe\u63a5\u79fb\u9664\u8bf7\u6c42\u53c2\u6570\n     *\/\n    @PostMapping(\"\/api\/short-link\/v1\/recycle-bin\/remove\")\n    void removeRecycleBin(@RequestBody RecycleBinRemoveReqDTO requestParam);\n\n\n    \/**\n     * \u8bbf\u95ee\u5355\u4e2a\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u6570\u636e\n     *\n     * @param fullShortUrl \u5b8c\u6574\u77ed\u94fe\u63a5\n     * @param gid          \u5206\u7ec4\u6807\u8bc6\n     * @param startDate    \u5f00\u59cb\u65f6\u95f4\n     * @param endDate      \u7ed3\u675f\u65f6\u95f4\n     * @return \u77ed\u94fe\u63a5\u76d1\u63a7\u4fe1\u606f\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/stats\")\n    Result&lt;ShortLinkStatsRespDTO&gt; oneShortLinkStats(@RequestParam(\"fullShortUrl\") String fullShortUrl,\n                                                    @RequestParam(\"gid\") String gid,\n                                                    @RequestParam(\"startDate\") String startDate,\n                                                    @RequestParam(\"endDate\") String endDate);\n\n    \/**\n     * \u8bbf\u95ee\u5206\u7ec4\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u6570\u636e\n     *\n     * @param gid       \u5206\u7ec4\u6807\u8bc6\n     * @param startDate \u5f00\u59cb\u65f6\u95f4\n     * @param endDate   \u7ed3\u675f\u65f6\u95f4\n     * @return \u5206\u7ec4\u77ed\u94fe\u63a5\u76d1\u63a7\u4fe1\u606f\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/stats\/group\")\n    Result&lt;ShortLinkStatsRespDTO&gt; groupShortLinkStats(@RequestParam(\"gid\") String gid,\n                                                      @RequestParam(\"startDate\") String startDate,\n                                                      @RequestParam(\"endDate\") String endDate);\n\n    \/**\n     * \u8bbf\u95ee\u5355\u4e2a\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u8bbf\u95ee\u8bb0\u5f55\u6570\u636e\n     *\n     * @param fullShortUrl \u5b8c\u6574\u77ed\u94fe\u63a5\n     * @param gid          \u5206\u7ec4\u6807\u8bc6\n     * @param startDate    \u5f00\u59cb\u65f6\u95f4\n     * @param endDate      \u7ed3\u675f\u65f6\u95f4\n     * @return \u77ed\u94fe\u63a5\u76d1\u63a7\u8bbf\u95ee\u8bb0\u5f55\u4fe1\u606f\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/stats\/access-record\")\n    Result&lt;Page&lt;ShortLinkStatsAccessRecordRespDTO&gt;&gt; shortLinkStatsAccessRecord(@RequestParam(\"fullShortUrl\") String fullShortUrl,\n                                                                               @RequestParam(\"gid\") String gid,\n                                                                               @RequestParam(\"startDate\") String startDate,\n                                                                               @RequestParam(\"endDate\") String endDate);\n\n    \/**\n     * \u8bbf\u95ee\u5206\u7ec4\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u8bbf\u95ee\u8bb0\u5f55\u6570\u636e\n     *\n     * @param gid       \u5206\u7ec4\u6807\u8bc6\n     * @param startDate \u5f00\u59cb\u65f6\u95f4\n     * @param endDate   \u7ed3\u675f\u65f6\u95f4\n     * @return \u5206\u7ec4\u77ed\u94fe\u63a5\u76d1\u63a7\u8bbf\u95ee\u8bb0\u5f55\u4fe1\u606f\n     *\/\n    @GetMapping(\"\/api\/short-link\/v1\/stats\/access-record\/group\")\n    Result&lt;Page&lt;ShortLinkStatsAccessRecordRespDTO&gt;&gt; groupShortLinkStatsAccessRecord(@RequestParam(\"gid\") String gid,\n                                                                                    @RequestParam(\"startDate\") String startDate,\n                                                                                    @RequestParam(\"endDate\") String endDate);\n}<\/code><\/pre>\n\n\n\n<p>\u76f8\u5e94\u7684shortLinkController<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.admin.controller;\n\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.common.convention.result.Results;\nimport com.nageoffer.shortlink.admin.remote.ShortLinkActualRemoteService;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkBatchCreateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkCreateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkPageReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkUpdateReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkBaseInfoRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkBatchCreateRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkCreateRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkPageRespDTO;\nimport com.nageoffer.shortlink.admin.toolkit.EasyExcelWebUtil;\nimport jakarta.servlet.http.HttpServletResponse;\nimport lombok.RequiredArgsConstructor;\nimport lombok.SneakyThrows;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RestController;\n\nimport java.util.List;\n\n\/**\n * \u77ed\u94fe\u63a5\u540e\u7ba1\u63a7\u5236\u5c42\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@RestController\n@RequiredArgsConstructor\npublic class ShortLinkController {\n\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\n    \/**\n     * \u521b\u5efa\u77ed\u94fe\u63a5\n     *\/\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/create\")\n    public Result&lt;ShortLinkCreateRespDTO&gt; createShortLink(@RequestBody ShortLinkCreateReqDTO requestParam) {\n        return shortLinkActualRemoteService.createShortLink(requestParam);\n    }\n\n    \/**\n     * \u6279\u91cf\u521b\u5efa\u77ed\u94fe\u63a5\n     *\/\n    @SneakyThrows\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/create\/batch\")\n    public void batchCreateShortLink(@RequestBody ShortLinkBatchCreateReqDTO requestParam, HttpServletResponse response) {\n        Result&lt;ShortLinkBatchCreateRespDTO&gt; shortLinkBatchCreateRespDTOResult = shortLinkActualRemoteService.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    }\n\n    \/**\n     * \u4fee\u6539\u77ed\u94fe\u63a5\n     *\/\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/update\")\n    public Result&lt;Void&gt; updateShortLink(@RequestBody ShortLinkUpdateReqDTO requestParam) {\n        shortLinkActualRemoteService.updateShortLink(requestParam);\n        return Results.success();\n    }\n\n    \/**\n     * \u5206\u9875\u67e5\u8be2\u77ed\u94fe\u63a5\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/page\")\n    public Result&lt;Page&lt;ShortLinkPageRespDTO&gt;&gt; pageShortLink(ShortLinkPageReqDTO requestParam) {\n        return shortLinkActualRemoteService.pageShortLink(requestParam.getGid(), requestParam.getOrderTag(), requestParam.getCurrent(), requestParam.getSize());\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>GroupServiceImpl\u4fee\u6539\u5982\u4e0b&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public class GroupServiceImpl extends ServiceImpl&lt;GroupMapper, GroupDO&gt; implements GroupService {\n\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\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\n\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701remoteservice\u53d8\u6210ActualRemoteService\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\u7701\u7565\nResult&lt;List&lt;ShortLinkGroupCountQueryRespDTO&gt;&gt; listResult = shortLinkActualRemoteService\n        .listGroupShortLinkCount(groupDOList.stream().map(GroupDO::getGid).toList());\nList&lt;ShortLinkGroupRespDTO&gt; shortLinkGroupRespDTOList = BeanUtil.copyToList(groupDOList, ShortLinkGroupRespDTO.class);\nshortLinkGroupRespDTOList.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<\/pre>\n\n\n\n<p>\u5982\u679c\u8c03\u7528project\u5fae\u670d\u52a1\u51fa\u73b0\u4e1a\u52a1\u5f02\u5e38\uff0c\u8fdb\u884c\u5168\u5c40\u5f02\u5e38\u5904\u7406\u5668\u62e6\u622a\u8fd4\u56deResult&lt;Void&gt;\u5bf9\u8c61\uff0c\u8fd9\u65f6\u5019admin\u670d\u52a1\u6ca1\u6709\u8fdb\u884c\u5904\u7406\u5c31\u76f4\u63a5\u8d4b\u503c\u7ed9Result&lt;ShortLinkBatchCreateRespDTO&gt;\uff0c\u8fd9\u6837\u4e0d\u4f1a\u6709\u95ee\u9898\u5417<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;\u8d70\u5b8c\u8fd9\u6bb5\u8def\uff1a\u53ef\u4ee5\u5c1d\u8bd5\u4e0b\uff0c\u5e94\u8be5\u4f1a\u76f4\u63a5\u88ab admin \u7684\u5168\u5c40\u5f02\u5e38\u62e6\u622a\u5668\u6355\u83b7<\/p>\n\n\n\n<p><strong>\u8fd9\u91cc\u4f7f\u7528\u7684Page\u5176\u5b9e\u5c31\u662f\u56e0\u4e3aopenFeign\u662f\u4f7f\u7528\u52a8\u6001\u4ee3\u7406\u5e2e\u4f60\u5b9e\u73b0\u4e86\u8fd9\u4e9b\u53d1\u9001\u8bf7\u6c42\u7684\u529f\u80fd,\u4f46\u662f\u4f60\u8981\u53d1\u9001\u7684\u6570\u636e\u8981\u662fjson\u7684,project\u90a3\u8fb9\u53ea\u6536json\u683c\u5f0f(\u6240\u4ee5\u5f97\u5e8f\u5217\u5316)\u3002\u8fd9\u91cc\u901a\u8fc7\u53cd\u5c04\u6765\u83b7\u53d6\u63a5\u53e3\u7684\u8fd4\u56de\u5bf9\u8c61\u3002\u4f46\u662fIpage\u662f\u4e2a\u63a5\u53e3\u3002\u63a5\u53e3\u662f\u751f\u6210\u4e0d\u4e86\u5bf9\u8c61\u7684,\u800c\u4e14\u4e5f\u4e0d\u77e5\u9053\u4f60\u5bf9\u5e94\u7684\u5b9e\u73b0\u7c7b\u662f\u90a3\u4e2a\u3002<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c03\u8282\uff1a\u5982\u4f55\u5c06\u9879\u76ee\u6539\u9020\u4e3a\u5fae\u670d\u52a1\u8c03\u7528\uff08\u4e0b\uff09<\/h2>\n\n\n\n<p>&nbsp;RecycleBinController\u4fee\u4e3a\u5fae\u670d\u52a1<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.controller;\n\nimport com.baomidou.mybatisplus.core.metadata.IPage;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.common.convention.result.Results;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinRecoverReqDTO;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinRemoveReqDTO;\nimport com.nageoffer.shortlink.admin.dto.req.RecycleBinSaveReqDTO;\n\nimport com.nageoffer.shortlink.admin.remote.ShortLinkActualRemoteService;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkRecycleBinPageReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkPageRespDTO;\nimport com.nageoffer.shortlink.admin.service.RecycleBinService;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.PostMapping;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RestController;\n\n\/**\n * \u56de\u6536\u7ad9\u7ba1\u7406\u63a7\u5236\u5c42\n *\/\n@RestController\n@RequiredArgsConstructor\npublic class RecycleBinController {\n\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\n\n    private final RecycleBinService recycleBinService;\n\n    \/**\n     * \u4fdd\u5b58\u56de\u6536\u7ad9\n     *\/\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/recycle-bin\/save\")\n    public Result&lt;Void&gt; saveRecycleBin(@RequestBody RecycleBinSaveReqDTO requestParam) {\n        shortLinkActualRemoteService.saveRecycleBin(requestParam);\n        return Results.success();\n    }\n\n    \/**\n     * \u5206\u9875\u67e5\u8be2\u56de\u6536\u7ad9\u77ed\u94fe\u63a5\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/recycle-bin\/page\")\n    public Result&lt;Page&lt;ShortLinkPageRespDTO&gt;&gt; pageShortLink(ShortLinkRecycleBinPageReqDTO requestParam) {\n        return recycleBinService.pageRecycleBinShortLink(requestParam);\n    }\n    \/**\n     * \u6062\u590d\u77ed\u94fe\u63a5\n     *\/\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/recycle-bin\/recover\")\n    public Result&lt;Void&gt; recoverRecycleBin(@RequestBody RecycleBinRecoverReqDTO requestParam) {\n        shortLinkActualRemoteService.recoverRecycleBin(requestParam);\n        return Results.success();\n    }\n\n    \/**\n     * \u79fb\u9664\u77ed\u94fe\u63a5\n     *\/\n    @PostMapping(\"\/api\/short-link\/admin\/v1\/recycle-bin\/remove\")\n    public Result&lt;Void&gt; removeRecycleBin(@RequestBody RecycleBinRemoveReqDTO requestParam) {\n        shortLinkActualRemoteService.removeRecycleBin(requestParam);\n        return Results.success();\n    }\n}<\/pre>\n\n\n\n<p>\u540c\u65f6\u4fee\u6539RecycleBinService\u91cc\u9762\u7684\u4e5f\u8981\u7528Page<\/p>\n\n\n\n<p>RecycleBinServiceImpl\u4fee\u6539<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.service.impl;\n\n\nimport cn.hutool.core.collection.CollUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;\nimport com.baomidou.mybatisplus.core.metadata.IPage;\nimport com.baomidou.mybatisplus.core.toolkit.Wrappers;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.nageoffer.shortlink.admin.common.biz.user.UserContext;\nimport com.nageoffer.shortlink.admin.common.convention.exception.ServiceException;\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.remote.ShortLinkActualRemoteService;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkRecycleBinPageReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkPageRespDTO;\nimport com.nageoffer.shortlink.admin.service.RecycleBinService;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\n\n\/**\n * URL \u56de\u6536\u7ad9\u63a5\u53e3\u5b9e\u73b0\u5c42\n *\/\n@Service\n@RequiredArgsConstructor\npublic class RecycleBinServiceImpl implements RecycleBinService {\n\n    private final GroupMapper groupMapper;\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\n\n    @Override\n    public Result&lt;Page&lt;ShortLinkPageRespDTO&gt;&gt; pageRecycleBinShortLink(ShortLinkRecycleBinPageReqDTO requestParam) {\n        LambdaQueryWrapper&lt;GroupDO&gt; queryWrapper = Wrappers.lambdaQuery(GroupDO.class)\n                .eq(GroupDO::getUsername, UserContext.getUsername())\n                .eq(GroupDO::getDelFlag, 0);\n        List&lt;GroupDO&gt; groupDOList = groupMapper.selectList(queryWrapper);\n        if (CollUtil.isEmpty(groupDOList)) {\n            throw new ServiceException(\"\u7528\u6237\u65e0\u5206\u7ec4\u4fe1\u606f\");\n        }\n        requestParam.setGidList(groupDOList.stream().map(GroupDO::getGid).toList());\n        return shortLinkActualRemoteService.pageRecycleBinShortLink(requestParam.getGidList(), requestParam.getCurrent(), requestParam.getSize());\n    }\n}\n<\/pre>\n\n\n\n<p>UrlTitleController\u600e\u4e48\u6837\uff1f&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.controller;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.remote.ShortLinkActualRemoteService;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.RestController;\n\n\/**\n * URL \u6807\u9898\u63a7\u5236\u5c42\n *\/\n@RestController\n@RequiredArgsConstructor\npublic class UrlTitleController {\n\n\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\n    \/**\n     * \u6839\u636eURL\u83b7\u53d6\u5bf9\u5e94\u7f51\u7ad9\u7684\u6807\u9898\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/title\")\n    public Result&lt;String&gt; getTitleByUrl(@RequestParam(\"url\") String url) {\n        return shortLinkActualRemoteService.getTitleByUrl(url);\n    }\n}<\/pre>\n\n\n\n<p>\u4e0b\u554a&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.admin.controller;\n\nimport com.baomidou.mybatisplus.core.metadata.IPage;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.nageoffer.shortlink.admin.common.convention.result.Result;\nimport com.nageoffer.shortlink.admin.remote.ShortLinkActualRemoteService;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkGroupStatsAccessRecordReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkGroupStatsReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkStatsAccessRecordReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.req.ShortLinkStatsReqDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkStatsAccessRecordRespDTO;\nimport com.nageoffer.shortlink.admin.remote.dto.resp.ShortLinkStatsRespDTO;\nimport lombok.RequiredArgsConstructor;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RestController;\n\n\/**\n * \u77ed\u94fe\u63a5\u76d1\u63a7\u63a7\u5236\u5c42\n *\/\n@RestController\n@RequiredArgsConstructor\npublic class ShortLinkStatsController {\n\n    private final ShortLinkActualRemoteService shortLinkActualRemoteService;\n\n    \/**\n     * \u8bbf\u95ee\u5355\u4e2a\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u6570\u636e\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/stats\")\n    public Result&lt;ShortLinkStatsRespDTO&gt; shortLinkStats(ShortLinkStatsReqDTO requestParam) {\n        return shortLinkActualRemoteService.oneShortLinkStats(requestParam.getFullShortUrl(), requestParam.getGid(), requestParam.getStartDate(), requestParam.getEndDate());\n    }\n\n    \/**\n     * \u8bbf\u95ee\u5206\u7ec4\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u76d1\u63a7\u6570\u636e\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/stats\/group\")\n    public Result&lt;ShortLinkStatsRespDTO&gt; groupShortLinkStats(ShortLinkGroupStatsReqDTO requestParam) {\n        return shortLinkActualRemoteService.groupShortLinkStats(requestParam.getGid(), requestParam.getStartDate(), requestParam.getEndDate());\n    }\n\n    \/**\n     * \u8bbf\u95ee\u5355\u4e2a\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u8bbf\u95ee\u8bb0\u5f55\u76d1\u63a7\u6570\u636e\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/stats\/access-record\")\n    public Result&lt;Page&lt;ShortLinkStatsAccessRecordRespDTO&gt;&gt; shortLinkStatsAccessRecord(ShortLinkStatsAccessRecordReqDTO requestParam) {\n        return shortLinkActualRemoteService.shortLinkStatsAccessRecord(requestParam.getFullShortUrl(), requestParam.getGid(), requestParam.getStartDate(), requestParam.getEndDate());\n    }\n\n    \/**\n     * \u8bbf\u95ee\u5206\u7ec4\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u8bbf\u95ee\u8bb0\u5f55\u76d1\u63a7\u6570\u636e\n     *\/\n    @GetMapping(\"\/api\/short-link\/admin\/v1\/stats\/access-record\/group\")\n    public Result&lt;Page&lt;ShortLinkStatsAccessRecordRespDTO&gt;&gt; groupShortLinkStatsAccessRecord(ShortLinkGroupStatsAccessRecordReqDTO requestParam) {\n        return shortLinkActualRemoteService.groupShortLinkStatsAccessRecord(requestParam.getGid(), requestParam.getStartDate(), requestParam.getEndDate());\n    }\n}\n<\/pre>\n\n\n\n<p><s><u>Is I think suddenly not. \u76f8\u5f53\u4e8e\u5b83\u7684\u63a5\u8fd1\u4f20\u8fc7\u6765\u3002\u6211\u4eec\u770b\u4e00\u4e0b\uff0c\u5230\u5bb6\u91cc\u53ef\u80fd\u662f\u7a7a\u7684\uff0c\u5728\u8fd9\u8fb9\u662f\u623f\u95f4\u91cc\u9762\u3002\u4ed6\u73b0\u5728\u65f6\u95f4\u786e\u5b9e\u754c\u5b9a PPT\u73b0\u5728\u662f\u6211\u60f3\u60f3\uff0c\u5927\u5bb6\u51c6\u5907\u5728\u505a\u4ec0\u4e48\uff1fIt's ok. So teacher are people. Sure\u3002\u8fd9\u90fd\u4e0d\u4f20\u4e86\u5417\uff1f\u4f46\u662f\u5177\u4f53\u7684\u8718\u86db\u732b\u4fa0\uff0c\u8fd9\u5e94\u8be5\u662f\u4e2a\u7b80\u5355\u7684bug\uff0c\u6ca1\u5173\u7cfb\uff0c\u540e\u7eed\u7684\u8bdd\u8ba9\u524d\u7aef\u90a3\u8fb9\u4fee\u4e00\u4e0b\u653e\u5230\u5355\u4e2a\u4e13\u9898\u6587\u4ef6\uff0c\u4f60\u628a\u5b83\u5f04\u51fa\u6765\u3002\u5220\u6389\u30021234-. \u7b2c\u4e8c\u4e2a\u76ee\u6807orders\uff0c\u8bbf\u95ee\u5206\u7ec4\u77ed\u94fe\u63a5\u6307\u5b9a\u65f6\u95f4\u5185\u3002\u5e94\u8be5\u4e0d\u7528\u6211\u5c31\u9996\u5148\u662f\u7b2c\u4e00\u4e2a\uff0c\u7136\u540e\u5e94\u8be5\u662f\u5728\u5357\u5e73\uff0c\u7136\u540e\u5220\u6389\u3002<\/u><\/s><\/p>\n\n\n\n<p><s><u>\u7b49\u4e00\u4e0b\u3002getmapper\u7684\u8bdd\u5b83\u90fd\u63a5\u5565\uff1fRemote. 1234\u76f8\u5f53\u4e8e\u6211\u4eec\u5c31\u4e0d\u518d\u4f20\u4e0d\u4f20\u989c\u8272\u7684\u4e1c\u897f\uff0c\u76f4\u63a5\u628a\u53c2\u6570\u6765\u53d6\u51fa\u6765\u5c31\u53ef\u4ee5\u4e86\u3002\u7b2c\u4e00\u4e2a\uff1b\u7b2c\u4e8c\u4e2a\uff0c\u6211\u600e\u4e48\u770b\uff1f\u5b83\u53ea\u80fd\u7ed9\u5b83\u4e0a\u9762\u81ea\u52a8\u52a0\u7801\u3002\u7136\u540e\u4f60\u628a\u5b83\u7136\u540e\u518d\u52a0\u4e00\u4e2a\u54c1\u724c\uff0c\u8fdb\u884c\u5206\u7ec4\u6838\u5b9e\u3002\u6211\u4eec\u5c31\u8fd9\u4e09\u4e2a\u73af\u8282\u4f60\u53bb\u4e86\uff0c\u4f46\u662f\u6ca1\u6709\u5b8c\u6210\u5173\u952e\u9636\u6bb5\u3002\u641e\u8fd9\u4e2a\u5206\u7ec4\u4ed6\u89c9\u5f97\u4ed6\u4eec\u7684\u5173\u952e\u7136\u540e\u5220\u6389\u3002\u7136\u540e\u8fd9\u4e2a\u7684\u8bdd\u8fd8\u6210\u4e864\u4e2a\u53c2\u6570\uff0c\u4e0d\u8981\u7136\u540e\u628a\u8fd9\u4e9b\u590d\u5236\u4e0a\u53bb\u3002\u4ec0\u4e48\uff1f\u7136\u540e\u68c0\u67e5\u4e00\u4e0b\u62a5\u544a\u7684\u7f16\u4e00\u4e0b\u3002\u91cd\u542f\u4e00\u4e0b\uff0c\u7136\u540e\u9632\u8303\u76d1\u63a7\u53bb\u3002\u53ef\u4ee5\u3002\u628a\u9632\u63a7\u5206\u5e03\u51fa\u53bb\u53ef\u4ee5\u4e5f\u6ca1\u95ee\u9898\uff0c\u7136\u540e\u521a\u624d\u611f\u89c9\u6539\u7684\u5565\u633a\u591a\u7684\uff0c\u54b1\u4eec\u8fd8\u6709\u6ca1\u6709\u5730\u65b9\u7528\u7684\uff1fOk\u6700\u540e\u4e00\u4e2a\u65b9\u5411\u4ed6\u5c31\u53ef\u4ee5\u5e2e\u4ed6\u4e0b\u5c97\u4e86\u3002\u7136\u540e\u5c06\u6765\u662f\u6211\u4eec\u7136\u540e\u6211\u770b\u4e00\u4e0b\u76d1\u63a7\u8fd9\u4e00\u5757\uff0c\u54b1\u4eec\u622a\u6b62\u4e00\u5b9a\u65f6\u95f4\u5185\u6211\u60f3\u8d77\u6765\u4e86\uff0c\u8fd8\u6709\u8fd9\u91cc\u6709\u4ec0\u4e48\uff1f\u4e0d\u9519\u4e86\u5417\uff1f\u4e0d\u9519\u3002 Ip\u7b49\u4e00\u4e0b\u3002Ip\u662f\u3002\u53ef\u4ee5\u4e86\u6ca1\u95ee\u9898\uff0c\u8fd9\u6b21\u7684\u8bdd\u6211\u4eec\u77ed\u94fe\u63a5\u4e2d\u53f0\u548c\u540e\u7ba1\u7684\u5fae\u670d\u52a1\u6539\u9020\u5c31\u5230\u6b64\u7ed3\u675f\u4e86\uff0c\u7136\u540e\u6211\u4eec\u4e0b\u8282\u8bfe\u7684\u8bdd\u4f1a\u8ddf\u5927\u5bb6\u8bb2\u4e00\u4e0b\uff0c\u600e\u4e48\u628a\u540e\u7ba1\u91cc\u9762\u5173\u4e8e\u5e94\u7528\u9274\u6743\u7684\u4e00\u4e9b\u4e8b\u60c5\u653e\u5230\u6211\u4eec\u7684\u7f51\u5173\u91cc\u9762\u53bb\uff0c\u6211\u4eec\u628a\u4ee3\u7801\u5148\u6572\u4e00\u4e0b\u3002<\/u><\/s><\/p>\n\n\n\n<p>&nbsp;\u4e00\u822c\u6765\u8bf4\u5c31\u662f\u627e\u5230\u8fdc\u7a0b\u8c03\u7528\u7684\u672c\u5730\u63a5\u53e3\u7136\u540e\u590d\u5236\u8fc7\u6765\uff0c\u628a\u65b9\u6cd5\u4f53\u5220\u4e86\u5c31\u662f\u4e86\u3002<\/p>\n\n\n\n<p>\u8fdc\u7a0b\u8c03\u7528\u91cc\u7684GET\u8bf7\u6c42\u5982\u679c\u6709\u5bf9\u8c61\u4f5c\u4e3a\u53c2\u6570\u7684\u8bdd\u5176\u5b9e\u4e0d\u9700\u8981\u62c6\u5f00\uff0c\u53ea\u7528\u52a0\u4e2a@SpringQueryMap\u6ce8\u89e3\u5373\u53ef\uff0c\u4f8b\u5982\uff1a \/** * \u8fdc\u7a0b\u8c03\u7528, \u5355\u4e2a\u77ed\u94fe\u63a5\u7684\u6307\u5b9a\u65f6\u95f4\u5185\u5404\u79cd\u76d1\u63a7 *\/ @GetMapping(\"\/api\/shortlink\/v1\/stats\") Result&lt;ShortLinkStatsRespDTO&gt; shortLinkStats(@SpringQueryMap ShortLinkStatsReqDTO requestParam);<\/p>\n\n\n\n<p>Mirac&nbsp;\u56de\u590d&nbsp;w\uff1aSpring Cloud OpenFeign \u63d0\u4f9b\u4e86\u7b49\u6548\u7684@SpringQueryMap\u6ce8\u89e3\uff0c\u7528\u4e8e\u5c06 POJO \u6216 Map \uff0c\u6620\u5c04\u4e3a GET \u65b9\u6cd5\u7684\u53c2\u6570\u3002<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;w\uff1a\u8fd9\u4e2a\u633a\u597d\uff0c\u6211\u4e4b\u524d\u6ca1\u7528\u8fc7\u8fd9\u4e2a\uff0c\u4ee5\u524d\u5728\u516c\u53f8\u91cc\u90fd\u662f\u5c01\u88c5 OpenFeign \u7684\u6269\u5c55\u65b9\u6cd5\u652f\u6301\u4f20\u9012\u5bf9\u8c61<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c04\u8282\uff1a\u5f15\u5165\u7f51\u5173\u67b6\u6784SpringCloud-Gateway\uff08\u4e0a\uff09<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"eBbdq\">\u4e3a\u4ec0\u4e48\u9700\u8981\u7f51\u5173<\/h2>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"762\" width=\"886\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/eeb84947c9087095f5577618023505ee.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"u0461e95e\">\u6ca1\u6709\u7f51\u5173\u5b58\u5728\u7684\u4e00\u4e9b\u95ee\u9898\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u8def\u7531\u7ba1\u7406&amp;\u670d\u52a1\u53d1\u73b0\u56f0\u96be\u3002<\/li>\n\n\n\n<li>\u5b89\u5168\u6027\u96be\u4ee5\u7ba1\u7406\uff1ahttps \u8bbf\u95ee\u3001\u9ed1\u767d\u540d\u5355\u3001\u7528\u6237\u767b\u5f55\u548c\u6570\u636e\u8bf7\u6c42\u52a0\u5bc6\u9632\u7be1\u6539\u7b49\u3002\u00a0<\/li>\n\n\n\n<li>\u8d1f\u8f7d\u5747\u8861\u95ee\u9898\u3002<\/li>\n\n\n\n<li>\u76d1\u63a7\u548c\u65e5\u5fd7\u96be\u4ee5\u96c6\u4e2d\u7ba1\u7406\u3002<\/li>\n\n\n\n<li>\u7f3a\u4e4f\u7edf\u4e00\u7684 API \u7ba1\u7406\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u524d\u7aef\u662f\u4e0d\u77e5\u9053\u4ed6\u8c03\u7528\u54ea\u4e00\u4e2a \u7684\uff0c\u5982\u679c\u4f60\u628a\u8fd9\u4e00\u5757\u4e1c\u897f\u653e\u524d\u7aef\u4e86&nbsp;\uff0c\u8fdd\u80cc\u4e86\u8bbe\u8ba1\u539f\u5219\uff0c\u5c31\u53eb\u8f7b\u524d\u7aef\u91cd\u540e\u7aef<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"827\" width=\"883\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/8a88552f515f16329aef7ebbfe2fa201.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"BU65G\">1. \u65e9\u671f\u5e94\u7528\u67b6\u6784<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"589\" width=\"868\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/c7887215598e2f77739979db03f0ab25.png\" alt=\"\"><\/p>\n\n\n\n<p id=\"u944965de\">F5 \u6700\u5927\u7684\u7f3a\u9677\u5c31\u662f\u786c\u4ef6\u8d35\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"t0d9c\">2. \u5f15\u5165\u8f6f\u4ef6\u7f51\u5173\u7ec4\u4ef6<\/h3>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" height=\"417\" width=\"1170\" src=\"https:\/\/i-blog.csdnimg.cn\/img_convert\/fc18aef0282767c8b7d9e8a51e91fd18.png\" alt=\"\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"VVYL2\">3. \u66f4\u590d\u6742\u7684\u7f51\u5173\u67b6\u6784<\/h3>\n\n\n\n<p id=\"ud9b371cc\">\u6d41\u91cf\u7f51\u5173\u548c\u4e1a\u52a1\u7f51\u5173\u7b49\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"u58Y8\">\u5f15\u5165 SpringCloud Gateway<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"f08IB\">1. \u5f15\u5165 Pom \u6587\u4ef6<\/h3>\n\n\n\n<p id=\"udb3d3cf3\">\u5f15\u5165 SpringCloud Gateway \u76f8\u5173\u7684 Pom \u7ec4\u4ef6\u3002\u89c6\u9891\u8bb2\u89e3\u4e2d\u6f0f\u6389\u4e00\u4e2a build \u6807\u7b7e\uff0c\u6b63\u5e38\u4e0d\u4f1a\u5f71\u54cd\u8fd0\u884c\uff0c\u4f46\u662f\u6253\u5305\u7684 Jar \u6587\u4ef6\u4e0d\u80fd\u8fd0\u884c\uff0c\u5927\u5bb6\u52a0\u4e0a\u5373\u53ef\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pom \u6587\u4ef6\u4e2d\u6f0f\u6389\u4e00\u4e2a build \u6807\u7b7e\uff0c\u5bf9\u4ee3\u7801\u8fd0\u884c\u6ca1\u6709\u5f71\u54cd\uff0c\u6253\u5305\u4f1a\u6709\u95ee\u9898\u3002\u6240\u4ee5\u5927\u5bb6\u8865\u5145\u4e0a\u5373\u53ef\u3002\n\n&lt;dependencies&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-cloud-starter-gateway&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.cloud&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-cloud-loadbalancer&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider xxx --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;io.netty&lt;\/groupId&gt;\n        &lt;artifactId&gt;netty-all&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;dependency&gt;\n        &lt;groupId&gt;com.alibaba.cloud&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-cloud-starter-alibaba-nacos-discovery&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-boot-starter-data-redis&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;dependency&gt;\n        &lt;groupId&gt;com.alibaba.fastjson2&lt;\/groupId&gt;\n        &lt;artifactId&gt;fastjson2&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n&lt;\/dependencies&gt;\n\n&lt;build&gt;\n    &lt;finalName&gt;${project.artifactId}&lt;\/finalName&gt;\n    &lt;plugins&gt;\n        &lt;plugin&gt;\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n            &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\n            &lt;executions&gt;\n                &lt;execution&gt;\n                    &lt;goals&gt;\n                        &lt;goal&gt;repackage&lt;\/goal&gt;\n                    &lt;\/goals&gt;\n                &lt;\/execution&gt;\n            &lt;\/executions&gt;\n        &lt;\/plugin&gt;\n    &lt;\/plugins&gt;\n&lt;\/build&gt;<\/code><\/pre>\n\n\n\n<p>&nbsp;\u56e0\u4e3a\u6211\u4eec\u7f51\u5173\u8981\u505a\u8fd9\u79cd\u8def\u7531\u8f6c\u53d1--\u670d\u52a1\u53d1\u73b0\uff0c\u5c31\u662f\u4ed6\u4f1a\u628a\u7f51\u5173\u4e5f\u6ce8\u518c\u5230nacos\u91cc\u9762\u53bb\uff0c\u53bb\u53d1\u73b0\u5176\u4e2d\u7684\u77ed\u94fe\u63a5\u540e\u7ba1\u548c\u77ed\u94fe\u63a5\u4e2d\u53f0\uff0c<\/p>\n\n\n\n<p>&nbsp;2. \u521b\u5efa\u7f51\u5173\u542f\u52a8\u7c7b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.gateway;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n\/**\n * \u7f51\u5173\u670d\u52a1\u5e94\u7528\u542f\u52a8\u5668\n *\/\n@SpringBootApplication\npublic class GatewayServiceApplication {\n\n    public static void main(String&#91;] args) {\n        SpringApplication.run(GatewayServiceApplication.class, args);\n    }\n}<\/code><\/pre>\n\n\n\n<p>&nbsp;3. \u6dfb\u52a0\u7f51\u5173\u914d\u7f6e\u6587\u4ef6<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server:\n  port: 8000\nspring:\n  application:\n    name: short-link-gateway\n  data:\n    redis:\n      host: 127.0.0.1\n      port: 6379\n      password: 123456\n  cloud:\n    nacos:\n      discovery:\n        server-addr: 127.0.0.1:8848\n    gateway:\n      routes:\n        - id: short-link-admin\n          uri: lb:\/\/short-link-admin\/api\/short-link\/admin\/**\n          predicates:\n            - Path=\/api\/short-link\/admin\/**\n          filters:\n            - name: TokenValidate\n              args:\n                whitePathList:\n                  - \/api\/short-link\/admin\/v1\/user\/login\n                  - \/api\/short-link\/admin\/v1\/user\/has-username\n\n        - id: short-link-project\n          uri: lb:\/\/short-link-project\/api\/short-link\/**\n          predicates:\n            - Path=\/api\/short-link\/**\n          filters:\n            - name: TokenValidate<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"FLGzb\">4. \u6dfb\u52a0\u7528\u6237\u767b\u5f55\u62e6\u622a\u5668<\/h3>\n\n\n\n<p id=\"u0b727321\">\u6dfb\u52a0\u767d\u540d\u5355\u914d\u7f6e\u7c7b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.gateway.config;\n\nimport lombok.Data;\n\nimport java.util.List;\n\n\/**\n * \u8fc7\u6ee4\u5668\u914d\u7f6e\n *\/\n@Data\npublic class Config {\n\n    \/**\n     * \u767d\u540d\u5355\u524d\u7f6e\u8def\u5f84\n     *\/\n    private List&lt;String&gt; whitePathList;\n}\n<\/code><\/pre>\n\n\n\n<p>\u6dfb\u52a0\u7f51\u5173\u9519\u8bef\u8fd4\u56de\u4fe1\u606f\u3002&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.gateway.dto;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\n\n\/**\n * \u7f51\u5173\u9519\u8bef\u8fd4\u56de\u4fe1\u606f\n *\/\n@Data\n@Builder\n@NoArgsConstructor\n@AllArgsConstructor\npublic class GatewayErrorResult {\n\n    \/**\n     * HTTP \u72b6\u6001\u7801\n     *\/\n    private Integer status;\n\n    \/**\n     * \u8fd4\u56de\u4fe1\u606f\n     *\/\n    private String message;\n}\n<\/code><\/pre>\n\n\n\n<p>&nbsp;\u6dfb\u52a0\u7528\u6237\u767b\u5f55\u62e6\u622a\u5668<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.gateway.filter;\n\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONObject;\nimport com.nageoffer.shortlink.gateway.config.Config;\nimport com.nageoffer.shortlink.gateway.dto.GatewayErrorResult;\nimport org.springframework.cloud.gateway.filter.GatewayFilter;\nimport org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;\nimport org.springframework.core.io.buffer.DataBufferFactory;\nimport org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.http.HttpStatus;\nimport org.springframework.http.server.reactive.ServerHttpRequest;\nimport org.springframework.http.server.reactive.ServerHttpResponse;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.CollectionUtils;\nimport org.springframework.util.StringUtils;\nimport reactor.core.publisher.Mono;\n\nimport java.net.URLEncoder;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.Objects;\n\n\/**\n * SpringCloud Gateway Token \u62e6\u622a\u5668\n *\/\n@Component\npublic class TokenValidateGatewayFilterFactory extends AbstractGatewayFilterFactory&lt;Config&gt; {\n\n    private final StringRedisTemplate stringRedisTemplate;\n\n    public TokenValidateGatewayFilterFactory(StringRedisTemplate stringRedisTemplate) {\n        super(Config.class);\n        this.stringRedisTemplate = stringRedisTemplate;\n    }\n\n    @Override\n    public GatewayFilter apply(Config config) {\n        return (exchange, chain) -&gt; {\n            ServerHttpRequest request = exchange.getRequest();\n            String requestPath = request.getPath().toString();\n            String requestMethod = request.getMethod().name();\n            if (!isPathInWhiteList(requestPath, requestMethod, config.getWhitePathList())) {\n                String username = request.getHeaders().getFirst(\"username\");\n                String token = request.getHeaders().getFirst(\"token\");\n                Object userInfo;\n                if (StringUtils.hasText(username) &amp;&amp; StringUtils.hasText(token) &amp;&amp; (userInfo = stringRedisTemplate.opsForHash().get(\"short-link:login:\" + username, token)) != null) {\n                    JSONObject userInfoJsonObject = JSON.parseObject(userInfo.toString());\n                    ServerHttpRequest.Builder builder = exchange.getRequest().mutate().headers(httpHeaders -&gt; {\n                        httpHeaders.set(\"userId\", userInfoJsonObject.getString(\"id\"));\n                        httpHeaders.set(\"realName\", URLEncoder.encode(userInfoJsonObject.getString(\"realName\"), StandardCharsets.UTF_8));\n                    });\n                    return chain.filter(exchange.mutate().request(builder.build()).build());\n                }\n                ServerHttpResponse response = exchange.getResponse();\n                response.setStatusCode(HttpStatus.UNAUTHORIZED);\n                return response.writeWith(Mono.fromSupplier(() -&gt; {\n                    DataBufferFactory bufferFactory = response.bufferFactory();\n                    GatewayErrorResult resultMessage = GatewayErrorResult.builder()\n                            .status(HttpStatus.UNAUTHORIZED.value())\n                            .message(\"Token validation error\")\n                            .build();\n                    return bufferFactory.wrap(JSON.toJSONString(resultMessage).getBytes());\n                }));\n            }\n            return chain.filter(exchange);\n        };\n    }\n\n    private boolean isPathInWhiteList(String requestPath, String requestMethod, List&lt;String&gt; whitePathList) {\n        return (!CollectionUtils.isEmpty(whitePathList) &amp;&amp; whitePathList.stream().anyMatch(requestPath::startsWith)) || (Objects.equals(requestPath, \"\/api\/short-link\/admin\/v1\/user\") &amp;&amp; Objects.equals(requestMethod, \"POST\"));\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"O8vno\">5. \u540e\u7ba1\u7cfb\u7edf\u6539\u9020\u4e8b\u9879<\/h3>\n\n\n\n<p id=\"u52f45c4d\">\u5927\u6982\u6d89\u53ca\u5230\u4e09\u5904\u6539\u52a8\uff0c\u5176\u4e2d\u8fd8\u5305\u62ec\u524d\u7aef\u6539\u9020\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"CRai2\">5.1. \u5220\u9664\u7528\u6237\u672a\u767b\u5f55\u9519\u8bef\u7801<\/h4>\n\n\n\n<p id=\"u0059b140\">\u56e0\u4e3a\u901a\u8fc7 HTTP status 401 \u6765\u6807\u8bc6\u7528\u6237\u672a\u767b\u5f55\uff0c\u6240\u4ee5\u9700\u8981\u5220\u9664\u540e\u7ba1\u4e2d\u7684\u81ea\u5b9a\u4e49\u9519\u8bef\u7801\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.admin.common.enums;\n\nimport com.nageoffer.shortlink.admin.common.convention.errorcode.IErrorCode;\n\n\/**\n * \u7528\u6237\u9519\u8bef\u7801\n *\/\npublic enum UserErrorCodeEnum implements IErrorCode {\n\n    \/\/ \u9700\u8981\u5220\u9664\n    USER_TOKEN_FAIL(\"A000200\", \"\u7528\u6237Token\u9a8c\u8bc1\u5931\u8d25\"),\n\n    USER_NULL(\"B000200\", \"\u7528\u6237\u8bb0\u5f55\u4e0d\u5b58\u5728\"),\n\n    USER_NAME_EXIST(\"B000201\", \"\u7528\u6237\u540d\u5df2\u5b58\u5728\"),\n\n    USER_EXIST(\"B000202\", \"\u7528\u6237\u8bb0\u5f55\u5df2\u5b58\u5728\"),\n\n    USER_SAVE_ERROR(\"B000203\", \"\u7528\u6237\u8bb0\u5f55\u65b0\u589e\u5931\u8d25\");\n\n    private final String code;\n\n    private final String message;\n\n    UserErrorCodeEnum(String code, String message) {\n        this.code = code;\n        this.message = message;\n    }\n\n    @Override\n    public String code() {\n        return code;\n    }\n\n    @Override\n    public String message() {\n        return message;\n    }\n}\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"iY57Y\">5.2. \u4fee\u6539\u7528\u6237\u62e6\u622a\u5668<\/h4>\n\n\n\n<p id=\"u434ee71e\">\u5c06\u4e4b\u524d\u7684\u64cd\u4f5c\u5df2\u7ecf\u8fc1\u79fb\u81f3\u7f51\u5173\u8bc6\u522b\uff0c\u4e3a\u6b64\uff0c\u8be5\u62e6\u622a\u5668\u53ea\u9700\u8981\u4fdd\u7559\u7528\u6237\u4e0a\u4e0b\u6587\u4ee3\u7801\u5373\u53ef\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.shortlink.admin.common.biz.user;\n\nimport cn.hutool.core.util.StrUtil;\nimport jakarta.servlet.Filter;\nimport jakarta.servlet.FilterChain;\nimport jakarta.servlet.ServletRequest;\nimport jakarta.servlet.ServletResponse;\nimport jakarta.servlet.http.HttpServletRequest;\nimport lombok.RequiredArgsConstructor;\nimport lombok.SneakyThrows;\n\n\/**\n * \u7528\u6237\u4fe1\u606f\u4f20\u8f93\u8fc7\u6ee4\u5668\n *\/\n@RequiredArgsConstructor\npublic class UserTransmitFilter implements Filter {\n\n    @SneakyThrows\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {\n        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;\n        String username = httpServletRequest.getHeader(\"username\");\n        if (StrUtil.isNotBlank(username)) {\n            String userId = httpServletRequest.getHeader(\"userId\");\n            String realName = httpServletRequest.getHeader(\"realName\");\n            UserInfoDTO userInfoDTO = new UserInfoDTO(userId, username, realName);\n            UserContext.setUser(userInfoDTO);\n        }\n        try {\n            filterChain.doFilter(servletRequest, servletResponse);\n        } finally {\n            UserContext.removeUser();\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\u56e0\u4e3a\u4e4b\u524d Redis \u64cd\u4f5c\u901a\u8fc7\u6784\u9020\u51fd\u6570\u521b\u5efa\uff0c\u6240\u4ee5\u540c\u65f6\u9700\u8981\u6539\u9020\u521b\u5efa\u65b9\u5f0f\u3002\n@Configuration\npublic class UserConfiguration {\n\n    \/**\n     * \u7528\u6237\u4fe1\u606f\u4f20\u9012\u8fc7\u6ee4\u5668\n     *\/\n    @Bean\n    public FilterRegistrationBean&lt;UserTransmitFilter&gt; globalUserTransmitFilter() {\n        FilterRegistrationBean&lt;UserTransmitFilter&gt; registration = new FilterRegistrationBean&lt;&gt;();\n        registration.setFilter(new UserTransmitFilter());\n        registration.addUrlPatterns(\"\/*\");\n        registration.setOrder(0);\n        return registration;\n    }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"EjtLs\">5.3. \u4fee\u6539\u524d\u7aef\u4ee3\u7801<\/h4>\n\n\n\n<p id=\"u8a3b4f3c\">\u8c03\u6574 vite.config.js \u6587\u4ef6\u8c03\u7528\u540e\u7aef\u7684\u7aef\u53e3\u9700\u8981\u4ece 8002 \u6539\u4e3a 8000 \u7f51\u5173\u7aef\u53e3<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { fileURLToPath, URL } from 'node:url'\n\nimport { defineConfig } from 'vite'\nimport vue from '@vitejs\/plugin-vue'\n\n\/\/ https:\/\/vitejs.dev\/config\/\nexport default defineConfig({\n  plugins: &#91;vue()],\n  resolve: {\n    alias: {\n      '@': fileURLToPath(new URL('.\/src', import.meta.url))\n    }\n  },\n  server: {\n    proxy: {\n      '\/api': {\n        target: 'http:\/\/127.0.0.1:8000',\n        changeOrigin: true,\n        ws: true,\n        rewrite: (path) =&gt; path.replace(\/^\\\/api\/, '') \/\/ \u4e0d\u53ef\u4ee5\u7701\u7565rewrit\n      }\n    }\n  }\n})<\/code><\/pre>\n\n\n\n<p>&nbsp;\u8c03\u6574 axios.js \u6587\u4ef6\u7684\u7528\u6237\u672a\u767b\u5f55\u8df3\u8f6c\u65b9\u5f0f\uff0c\u4e4b\u524d\u901a\u8fc7 <code>res.data.code === 'A000200'<\/code> \u5224\u65ad\uff0c\u73b0\u5728\u901a\u8fc7 <code>err.response.status === 401<\/code> \u5224\u65ad\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import axios from 'axios'\nimport { getToken, getUsername } from '@\/core\/auth.js'\n\/\/ import Router from '..\/router'\nimport { ElMessage } from 'element-plus'\nimport { isNotEmpty } from '@\/utils\/plugins.js'\nimport { useRouter } from 'vue-router'\nconst router = useRouter()\n\/\/ const baseURL = '\/resourcesharing\/organizational'\nconst baseURL = '\/api\/short-link\/admin\/v1'\n\/\/ \u521b\u5efa\u5b9e\u4f8b\nconst http = axios.create({\n  \/\/ api \u4ee3\u7406\u4e3a\u670d\u52a1\u5668\u8bf7\u6c42\u5730\u5740\n  baseURL: '\/api' + baseURL,\n  timeout: 15000\n})\n\/\/ \u8bf7\u6c42\u62e6\u622a --&gt;\u5728\u8bf7\u6c42\u53d1\u9001\u4e4b\u524d\u505a\u4e00\u4e9b\u4e8b\u60c5\nhttp.interceptors.request.use(\n  (config) =&gt; {\n    config.headers.Token = isNotEmpty(getToken()) ? getToken() : ''\n    config.headers.Username = isNotEmpty(getUsername()) ? getUsername() : ''\n    \/\/ console.log('\u83b7\u53d6\u5230\u7684token\u548cusername', getToken(), getUsername())\n    return config\n  },\n  (error) =&gt; {\n    return Promise.reject(error)\n  }\n)\n\/\/ \u54cd\u5e94\u62e6\u622a --&gt;\u5728\u8fd4\u56de\u7ed3\u679c\u4e4b\u524d\u505a\u4e00\u4e9b\u4e8b\u60c5\nhttp.interceptors.response.use(\n  (res) =&gt; {\n    if (res.status == 0 || res.status == 200) {\n      \/\/ \u8bf7\u6c42\u6210\u529f\u5bf9\u54cd\u5e94\u6570\u636e\u505a\u5904\u7406\uff0c\u6b64\u5904\u8fd4\u56de\u7684\u6570\u636e\u662faxios.then(res)\u4e2d\u63a5\u6536\u7684\u6570\u636e\n      \/\/ code\u503c\u4e3a 0 \u6216 200 \u65f6\u89c6\u4e3a\u6210\u529f\n      return Promise.resolve(res)\n    }\n    return Promise.reject(res)\n  },\n  (err) =&gt; {\n    \/\/ \u5728\u8bf7\u6c42\u9519\u8bef\u65f6\u8981\u505a\u7684\u4e8b\u513f\n    \/\/ \u6b64\u5904\u8fd4\u56de\u7684\u6570\u636e\u662faxios.catch(err)\u4e2d\u63a5\u6536\u7684\u6570\u636e\n    if (err.response.status === 401) {\n      localStorage.removeItem('token')\n      router.push('\/login')\n    }\n    return Promise.reject(err)\n  }\n)\nexport default http\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c05\u8282\uff1a\u5f15\u5165\u7f51\u5173\u67b6\u6784SpringCloud-Gateway\uff08\u4e0b\uff09<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"article-title\">\u5f15\u5165\u7f51\u5173\u67b6\u6784\u540e\u5982\u4f55\u8bbf\u95ee\u4e2d\u53f0\uff1f<\/h3>\n\n\n\n<p>\u540e\u7ba1\u4f5c\u4e3a\u53ef\u89c6\u5316\u754c\u9762\u65b9\u5f0f\u64cd\u4f5c\u77ed\u94fe\u63a5\u7cfb\u7edf\uff0c\u4e2d\u53f0\u4f5c\u4e3a\u63d0\u4f9b\u540e\u7ba1\u63a5\u53e3\u8c03\u7528\u4ee5\u53ca API \u7b49\u591a\u79cd\u8c03\u7528\u65b9\u5f0f\u3002\u6b64\u65f6\uff0c\u4e2d\u53f0\u5e94\u7528\u5c31\u9700\u8981\u8fdb\u884c\u72ec\u7acb\u7684\u7528\u6237\u767b\u5f55\u9a8c\u8bc1\u903b\u8f91\u3002<\/p>\n\n\n\n<p>\u5bc6\u94a5\u65b9\u5f0f\u5728\u7528\u6237\u8bb0\u5f55\u751f\u6210\u65f6\u521b\u5efa\u552f\u4e00\u7684\u5bc6\u94a5\u8fdb\u884c\u4fdd\u5b58\uff0c\u6bcf\u6b21\u8bbf\u95ee\u65f6\u90fd\u643a\u5e26\u8be5\u5bc6\u94a5\u8bbf\u95ee\u5373\u53ef\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u548c\u540e\u7ba1\u6cbf\u7528\u4e00\u5957\u65b9\u6848<\/h3>\n\n\n\n<p>\u548c\u5f53\u524d\u540e\u7ba1\u670d\u52a1\u6cbf\u7528\u4e00\u5957\u767b\u5f55\u673a\u5236\uff0c\u6bcf\u6b21\u90fd\u5e26\u4e0a\u7528\u6237\u7684\u767b\u5f55 Token \u8bbf\u95ee\u4e2d\u53f0\u63a5\u53e3\u5373\u53ef\u3002Q\uff1a\u5982\u679c\u7528\u6237\u5728\u540e\u7ba1\u4e2d\u64cd\u4f5c\u4e86\u9000\u51fa\u767b\u5f55\u5982\u4f55\u89e3\u51b3\uff1fA\uff1a\u5e94\u8be5\u5728\u5ba2\u6237\u7aef\u5e94\u7528\u8c03\u7528\u540e\uff0c\u53d1\u73b0\u8bf7\u6c42\u8fd4\u56de\u7684 401\uff0c\u91cd\u65b0\u8c03\u7528\u767b\u5f55\u63a5\u53e3\uff0c\u518d\u53d1\u8d77\u4e00\u6b21\u8c03\u7528\u5373\u53ef\u3002Q\uff1a\u5982\u679c\u7528\u6237\u767b\u5f55\u72b6\u6001\u5931\u6548\uff0c\u4f1a\u8bf7\u6c42 401 \u5982\u4f55\u89e3\u51b3\uff1fA\uff1a\u6539\u9020\u767b\u5f55\u63a5\u53e3\uff0c\u5982\u679c\u7528\u6237\u5df2\u767b\u5f55\u60c5\u51b5\uff0c\u90a3\u4e48\u91cd\u65b0\u5237\u65b0\u6709\u6548\u671f\u3002<\/p>\n\n\n\n<p>\u56e0\u4e3a\u6211\u4eec\u73b0\u5728\u7684\u65b9\u5f0f\u6211\u66f4\u503e\u5411\u4e8e\u662f\u4ec0\u4e48\uff1f\u548c\u540e\u53f0\u53bb\u7814\u7a76\u4e00\u5957\u65b9\u6848\uff0c\u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\u4e0a\u9762\u8fd9\u5957\u65b9\u6848\u5bf9\u76ee\u524d\u7684\u73b0\u6709\u4ee3\u7801\u6539\u52a8\u662f\u6bd4\u8f83\u5927\u7684\uff0c\u7136\u540e\u9488\u5bf9\u4e8e\u8fd9\u79cd\u65c1\u652f\u7684\u4e00\u4e9b\u903b\u8f91\uff0c\u6211\u4e0d\u662f\u5f88\u5e0c\u671b\u53bb\u505a\u4e00\u4e9b\u4e3b\u4f53\u4e0a\u7684\u6539\u53d8\uff0c\u90a3\u8fd9\u4e2a\u65f6\u5019\u5c31\u60f3\u5230\u4e00\u79cd\u8fd9\u79cd\u65b9\u6cd5\uff0c\u901a\u8fc7\u6211\u4eec\u7cfb\u7edf\u7684\u7528\u6237\u767b\u5f55\u7684\u903b\u8f91\u53bb\u6cbf\u7528\u540c\u4e00\u4efd\u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n\n\n\n<p>\u6bd4\u5982\u8bf4\u6211\u4eec\u73b0\u5728\u8c03\u7528\u901a\u8fc7\u524d\u7aef\u53bb\u8c03\u7528\u6237\u7ba1\u7406\u7cfb\u7edf\u5b83\u4f1a\u5e26\u4e0a\u6211\u4eec\u7684 token \u548c talking\uff0c\u90a3\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u5176\u5b9e\u53ea\u9700\u8981\u4f7f\u7528\u4e2d\u53f0\u5e94\u7528\u7684\u65f6\u5019\uff0c\u4e5f\u5e26\u4e0a\u6211\u4eec\u7684 token \u5c31\u53ef\u4ee5\u4e86\uff0c\u5bf9\u5427\uff1f<\/p>\n\n\n\n<p>\u8fd9\u4e2a\u65f6\u5019\u4f1a\u6709\u4e24\u4e2a\u95ee\u9898\uff0c\u5c31\u662f\u9996\u5148\u7b2c\u4e00\u4e2a\u95ee\u9898\u5982\u679c\u8bf4\uff0c\u7528\u6237\u5728\u540e\u53f0\u4e2d\u64cd\u4f5c\u4e86\u9000\u51fa\u767b\u5f55\uff0c\u600e\u4e48\u529e\uff1f\u56e0\u4e3a\u9000\u4e86\u5bf9\u4e0d\u5bf9\uff1f\u8fd9\u4e2a\u65f6\u5019\u6211\u4eec\u53ef\u4ee5\u5728\u5ba2\u6237\u7aef\u4e5f\u5c31\u662f\u522b\u4eba\u7684\u5e94\u7528\u6765\u8c03\u7528\u63a5\u53e3\u7cfb\u7edf\u7684\u65f6\u5019\uff0c\u53d1\u73b0\u8fd4\u56de\u7684\u8bf7\u6c42\u72b6\u6001\u7801\u662f 401\uff0c\u8fd9\u4e2a\u65f6\u5019\u4ed6\u53ea\u9700\u8981\u53bb\u91cd\u65b0\u8c03\u7528\u4ed6\u7684\u767b\u5f55\u63a5\u53e3\u628a\u503c\u4fdd\u5b58\u4e0b\u6765\u5c31\u53ef\u4ee5\u4e86\uff0c\u7136\u540e\u518d\u63a5\u7740\u53d1\u8d77\u8c03\u7528\u5bf9\u5427\uff1f<\/p>\n\n\n\n<p>\u8fd9\u79cd\u5f62\u5f0f\u6709\u70b9\u4e0d\u597d\u662f\u4ec0\u4e48\uff1f\u6bcf\u6b21\u5b83\u90fd\u6709\u53ef\u80fd\u6709\u4e00\u6bb5\u7684\u771f\u7a7a\u671f\uff0c\u771f\u7a7a\u671f\u6bd4\u8f83\u77ed\u53ef\u80fd\u5c31\u51e0\u767e\u6beb\u79d2\uff0c\u4f46\u662f\u5b83\u53ef\u80fd\u4f1a\u6709\u5927\u91cf\u7684\u8bf7\u6c42\u963b\u585e\u5728\u8fd9\u91cc\uff0c\u5bf9\u5427\uff1f\u56e0\u4e3a\u6bd4\u5982\u8bf4\u5b83\u5728\u5931\u6548\u7684\u90a3\u4e00\u523b\u6709\u5f88\u591a\u7684\u8bf7\u6c42\u6253\u8fc7\u6765\u662f\u5427\uff1f\u7c7b\u4f3c\u4e8e\u7f13\u5b58\u51fb\u7a7f\u7684\u8fd9\u79cd\u903b\u8f91\uff0c\u90a3\u5c31\u4e0d\u662f\u5f88\u4f18\u96c5\u3002<\/p>\n\n\n\n<p>\u90a3\u6240\u4ee5\u8bf4\u6211\u4eec\u8981\u6709\u4e00\u7cfb\u5217\u7684\u8f85\u52a9\u65b9\u6848\uff0c\u5927\u5bb6\u5e94\u8be5\u5bf9\u63a5\u8fc7\u5fae\u4fe1\u516c\u4f17\u53f7\u90fd\u77e5\u9053\u5b83\u4e5f\u662f\u6709\u4e00\u4e2a\u5728\u6548\u671f\u5185\u5bf9\u5427\uff1f\u901a\u8fc7\u8fd9\u79cd token \u7684\u673a\u5236\u6211\u4eec\u4e5f\u53ef\u4ee5\u8fd9\u6837\u505a\uff0c\u6bd4\u5982\u8bf4\u7ed9\u5b83\u8fdb\u884c\u4e00\u4e2a\u7eed\u671f\u5bf9\u5427\uff1f\u6bd4\u5982\u8bf4\u6211\u4eec\u6bcf\u6b21\u8c03\u4e00\u6b21 login\uff0c\u4ed6\u5c31\u8fdb\u884c\u4e00\u4e2a\u7eed\u671f\uff0c\u5fae\u4fe1\u516c\u4f17\u53f7\u7684\u903b\u8f91\u662f\u8fd4\u56de\u7ed9\u4f60\u4e00\u4e2a\uff0c\u4ed6\u6709\u8fd9\u79cd\u65b9\u6848\uff0c\u7b2c\u4e00\u79cd\u7684\u8bdd\u5c31\u662f\u4f60\u8fd4\u56de\u7ed9\u4f60\u539f\u6765\u7684\uff0c\u5230\u65f6\u5019\u4f60\u8fc7\u53bb\u65f6\u95f4\u7b2c\u4e8c\u79cd\u5f3a\u5236\u5237\u65b0\u6211\u4e2a\u4eba\u89c9\u5f97\u4e24\u79cd\u90fd\u4e0d\u662f\u5f88\u597d\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u53ef\u4ee5\u91c7\u7528\u4e00\u79cd\u8fd9\u79cd\u65b9\u6cd5\u5c31\u662f\u5f53\u6211\u4eec\u5728\u767b\u5f55\u7684\u72b6\u6001\u4e0b\u5c31\u8fd9\u4e2a\u7528\u6237\u5df2\u7ecf\u767b\u5f55\u7684\u72b6\u6001\u4e0b\uff0c\u4ed6\u53c8\u6389\u4e86\u63a5\u53e3\uff0c\u6211\u4eec\u53ef\u4ee5\u600e\u4e48\u529e\uff1f\u6211\u4eec\u662f\u4e0d\u662f\u53ef\u4ee5\u628a\u4ed6\u7684\u8fc7\u671f\u65f6\u95f4\u7ed9\u4ed6\u5237\u65b0\u5bf9\u5427\uff1f\u5c31\u5237\u65b0\u7684\u8fc7\u671f\u65f6\u95f4\uff0c\u8fd9\u6837\u7684\u8bdd\u4e0d\u6bd4\u5982\u5c31\u6bd4\u4e0d\u4e86\u3002\u5982\u679c\u7528\u6237\u767b\u5f55\u72b6\u6001\u5931\u6548\uff0c\u4f1a\u89e6\u53d1\u8bf7\u6c42\u6307\u4ee4\uff0c\u5982\u4f55\u89e3\u51b3\u6539\u9020\u767b\u5f55\u63a5\u53e3\u3002<\/p>\n\n\n\n<p>\u5982\u679c\u7528\u6237\u5df2\u767b\u5f55\u60c5\u51b5\uff0c\u90a3\u4e48\u91cd\u65b0\u5237\u65b0\u6709\u6548\u671f\uff0c\u8fd9\u79cd\u65b9\u5f0f\u5c31\u53ef\u4ee5\u4e86\uff0c\u6211\u4eec\u628a\u4ee3\u7801\u7a0d\u5fae\u6539\u4e00\u4e0b\uff0c\u7136\u540e\u5728\u8fd9\u91cc\u7684\u8bdd\u6211\u4eec\u91cd\u65b0\u7ed9\u5b83\u8c03\u4e00\u4e0b\u5b83\u7684\u903b\u8f91\uff0c\u5c31\u50cf\u4f60\u5728\u8fd9\u4e2a\u903b\u8f91\u91cc\u9762\u7ed9\u4ed6\u8c03\u4e00\u4e0b\u5c31\u53ef\u4ee5\u3002<\/p>\n\n\n\n<p>\u6240\u4ee5\u5982\u679c\u8bf4\u5df2\u7ecf\u5b58\u5728\u5bf9\u5427\uff1f\u8fd4\u56de\u8fd9\u4e2a\u6570\u636e\u7684\u65f6\u5019\uff0c\u6211\u4eec\u7ed9\u5b83\u8bbe\u7f6e\u4e00\u4e2a\u6709\u6548\u671f\uff0c\u7ed9\u5b83\u91cd\u65b0\u6539\u621030\u5206\u949f\uff0c\u8fd9\u6837\u7684\u8bdd\u5c31\u6bd4\u8f83 ok \u4e86\uff0c\u5982\u679c\u8bf4\u60f3\u8981\u505a\u5f97\u66f4\u7a33\u59a5\u4e00\u70b9\u5bf9\u5427\uff1f\u6211\u4eec\u53ef\u4ee5\u5982\u679c\u91c7\u7528\u8fd9\u79cd\u65b9\u6cd5\u90a3\u79cd\u6709\u76f8\u5f53\u4e8e\u6bcf\u6b21\u767b\u5f55\u5b8c\u4e4b\u540e\uff0c\u6bcf\u6b21\u6709\u4eba\u8c03\u7528\u6237\u63a5\u53e3\u90fd\u662f\u7ed9\u4ed6\u5237\u65b0 token \u7684\u6709\u6548\u671f\uff0c\u5bf9\u5427\uff1f\u80fd\u4fdd\u8bc1\u5b83\u7c7b\u4f3c\u4e8e\u6c38\u4e0d\u8d85\u65f6\u7684\u8fd9\u79cd\u611f\u89c9\u3002<\/p>\n\n\n\n<p>Ok \u8fd9\u6837\u7684\u8bdd\u6211\u4eec\u7684\u4e2d\u53f0\u5e94\u7528\u4e5f\u80fd\u591f\u5355\u72ec\u7684\u5bf9\u5916\u8fdb\u884c\u4e00\u7cfb\u5217\u7684\u8bbf\u95ee\uff0c\u4f18\u5316\u8fd9\u4e2a\u65b9\u6cd5\u3002\u8fd9\u6837\u80af\u5b9a\u662f\u5f00\u53d1\u6211\u4eec\u8bd5\u4e00\u4e0b\u597d\u5427\uff1f<\/p>\n\n\n\n<p>\u76f8\u5f53\u4e8e\u5047\u5982\u8bf4\u6709\u522b\u7684\u7cfb\u7edf\u60f3\u7ed9\u6211\u4eec\u5bfc\u8054\u7cfb\u7edf\uff0c\u4f60\u5e94\u7528\u91cc\u9762\u6709\u4e24\u4e2a\uff0c\u7b2c\u4e00\u4e2a\u5c31\u6765\u8c03\u7528\u7b2c\u4e8c\u4e2a\u63a5\u53e3\u8c03\u7528\u5176\u4ed6\u63a5\u53e3\u8c03\u7528\u8fde\u63a5\u7684\u4e00\u7cfb\u5217\u63a5\u53e3\uff0c\u7136\u540e\u76f8\u5f53\u4e8e\u4f60\u90a3\u8fb9\u6709\u4e2a\u5b9a\u65f6\u4efb\u52a1\u53bb\u652f\u6301\uff0c\u6bd4\u5982\u8bf4\u6bcf\u4e00\u4e2a\u5c0f\u65f6\u53bb\u5237\u4e00\u4e0b\u6211\u4eec\u7684 login \u7684\u63a5\u53e3\u5bf9\u5427\uff1f\u4fdd\u8bc1\u4f60\u7684\u6700\u65b0\u7684\uff0c\u8fd9\u6837\u7684\u8bdd\u662f\u6bd4\u8f83\u7a33\u59a5\u7684\u3002<\/p>\n\n\n\n<p>\u53ef\u4ee5\u4e86\uff0c\u8fd9\u6837\u7684\u8bdd\u5b83\u5c31\u80fd\u4fdd\u8bc1\u5b83\u7684\u4e00\u4e2a\u65f6\u6548\u65f6\u95f4\u662f\u6709\u5728\u7eed\u671f\u7684\u60c5\u51b5\u4e0b\u53ef\u80fd\u5c31\u662f\u6c38\u4e0d\u5931\u6548\u3002Ok \u90a3\u4ee3\u7801\u6211\u5199\u4e00\u4e0b\u3002<\/p>\n\n\n\n<p>\u8fd9\u6837\u7684\u8bdd\u5176\u5b9e\u6211\u4eec\u7684\u4e2d\u53f0\u76f8\u5173\u7684\u4e00\u7cfb\u5217\u7684\u4e1c\u897f\u90fd\u5df2\u7ecf\u6bd4\u8f83\u5b8c\u5584\u4e86\uff0c\u63a5\u4e0b\u6765\u4e0b\u8282\u8bfe\u6211\u4f1a\u628a\u805a\u5408\u670d\u52a1\u7ed9\u5927\u5bb6\u642d\u5efa\u51fa\u6765\uff0c\u90a3\u642d\u5efa\u51fa\u6765\u4e4b\u540e\uff0c\u5176\u5b9e\u5927\u5bb6\u5728\u90e8\u7f72\u7684\u65f6\u5019\u53ea\u9700\u8981\u90e8\u7f72\u4ec0\u4e48\u5730\u4f4d\u548c\u670d\u52a1\u5c31\u53ef\u4ee5\u4e86\uff0c\u5c31\u5ffd\u7565\u4e86\u5185\u6838\u548c\u903b\u8f91\u4e86\u597d\u5427\uff1f\u65b9\u4fbf\u5927\u5bb6\u90e8\u7f72\u7684\uff0c\u4f46\u662f\u771f\u5b9e\u573a\u666f\u4e0b\u80af\u5b9a\u8fd8\u662f admin \u548c project\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Mirac\uff1a\u597d\u50cf\u4e0d\u662f\u6211\u60f3\u7684\u5237\u65b0token\u7684\u529f\u80fd\uff0c\u7528\u6237\u53ef\u80fd\u4fee\u6539\u6570\u636e\u65f6\u7a81\u7136\u663e\u793atoken\u8fc7\u671f\u3002<\/p>\n\n\n\n<p>Ahci&nbsp;\u56de\u590d&nbsp;Mirac\uff1a\u53ef\u4e0d\u53ef\u4ee5\u5728\u7f51\u5173\u91cc\u5237\u65b0Token\uff0cusername\u548ctoken\u5747\u4e0d\u4e3a\u7a7a\u7684\u60c5\u51b5\u4e0b\u52a0\u4e00\u6761\u91cd\u7f6e\u8fc7\u671f\u65f6\u95f4\u5c31\u884c\u4e86<\/p>\n\n\n\n<p>\u9a6c\u4e01&nbsp;\u56de\u590d&nbsp;Ahci\uff1a\u53ef\u4ee5\u7684\uff0c\u5b9e\u73b0\u4e1a\u52a1\u7684\u65b9\u5f0f\u6709\u5f88\u591a\u79cd\uff0c\u53ea\u4e0d\u8fc7\u5c31\u770b\u90a3\u79cd\u4e1a\u52a1\u662f\u516c\u53f8\u5b9e\u9645\u573a\u666f\u9700\u8981\u7684<\/p>\n\n\n\n<p>\u4e0d\u60f3\u53d6\u540d&nbsp;\u56de\u590d&nbsp;Mirac\uff1a\u4e3a\u4ec0\u4e48\u7528\u6237\u4fee\u6539\u6570\u636e\u65f6\u4f1a\u7a81\u7136\u663e\u793atoken\u8fc7\u671f\u5462\uff0c\u80fd\u4fee\u6539\u6570\u636e\u4e0d\u662f\u5df2\u7ecf\u901a\u8fc7token\u9a8c\u8bc1\u4e86\u5417<\/p>\n\n\n\n<p>TheTurtle&nbsp;\u56de\u590d&nbsp;\u4e0d\u60f3\u53d6\u540d\uff1a\u586b\u5b8c\u8868\u5355\u540e\u70b9\u63d0\u4ea4\u4fee\u6539\u65f6\u5931\u6548\u4e86\u5462\uff1f<\/p>\n\n\n\n<p>\u76ae\u86cb\u7626\u8089\u7ca5\u3002&nbsp;\u56de\u590d&nbsp;Mirac\uff1a\u7528\u6237\u5c42\u641e\u4e2a\u62e6\u622a\u5668,\u6743\u91cd\u6700\u5927\u3002\u5224\u65ad\u662f\u5426\u6709token,\u65e0token\u5c31\u76f4\u63a5\u4e0d\u62e6\u622a,\u6709token\u5c31\u4e00\u76f4\u5237\u65b0redis\u7684ttl\u65f6\u95f4\u3002<\/p>\n\n\n\n<p>\u633d\u503e&nbsp;\u56de\u590d&nbsp;\u76ae\u86cb\u7626\u8089\u7ca5\u3002\uff1ahhh\u5bf9\u7684\uff0c\u4e4b\u524d\u505a\u7684\u5f88\u591a\u9879\u76ee\u5176\u5b9e\u90fd\u662f\u8fd9\u79cd\u601d\u60f3<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u60f3\u95ee\u4e00\u4e0b\u9a6c\u54e5\uff0c\u6211\u89c9\u5f97\u6b63\u5e38\u60c5\u51b5\u4e0b\u5206\u4eab\u51fa\u53bb\u7684\u77ed\u94fe\uff0c\u70b9\u51fb\u8df3\u8f6crestoreUrl\u5e94\u8be5\u662f\u76f4\u63a5\u7f51\u5173\u767d\u540d\u5355\u4e0d\u9700\u8981\u9274\u6743\u7684\u3002\u6309\u9a6c\u54e5\u7684\u8fd9\u4e2a\u60f3\u6cd5\u7684\u8bdd\uff0c\u767d\u540d\u5355\u91cc\u53ea\u6709hasName\u548clogin\u6ca1\u6709restoreUrl\u3002\u5982\u679c\u6211\u521b\u5efa\u4e00\u4e2a\u77ed\u94fe\u63a5\uff0c\u5206\u4eab\u51fa\u53bb\uff0c\u7136\u540e\u6211\u8fd9\u8d26\u53f7\u9000\u51fa\u53bb\u4e86\uff0c\u90a3\u4e48\u7f51\u5173\u9274\u6743\u5c31\u4f1a\u628arestoreUrl\u62e6\u4e0b\uff0c\u6240\u4ee5\u9a6c\u54e5\u8fd9\u91cc\u8981\u4e00\u76f4\u5b9a\u65f6\u4efb\u52a1\u7eed\u671ftoken\uff0c\u4fdd\u8bc1\u77ed\u94fe\u521b\u5efa\u7684\u8d26\u53f7\u4e0d\u767b\u51fa\uff0c\u611f\u89c9\u6709\u70b9\u53cd\u76f4\u89c9\uff1f<\/p>\n\n\n\n<p>\u4e00\u4e2a\u9ad8\u98ce\u4eae\u8282\u7684\u4eba&nbsp;\u56de\u590d&nbsp;\u5c0f\u5b59\u8981\u4e0a\u4e1c\u534e\uff1a\u6211\u4e2a\u4eba\u7406\u89e3\uff0c\u77ed\u8fde\u63a5\u7684\u8bbf\u95ee\u4f60\u770b\u4e0b\u8def\u5f84\uff0c\u662f\u76f4\u63a5\u8ddf\u5728ip\u5730\u5740\u52a0\u7aef\u53e3\u540e\u9762\u7684\uff0c\u6839\u672c\u5c31\u6ca1\u52a0\u5165gateway\uff0c\u4e5f\u5c31\u662f\u6ca1\u6709\u73b0\u5728\u7684\u4e00\u7cfb\u5217\u9274\u6743<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u6240\u4ee5\u53ef\u4ee5\u7406\u89e3\u4e3a\u901a\u8fc7API\u8c03\u4e2d\u53f0\u670d\u52a1\u7684\u65f6\u5019\u8fd8\u662f\u9700\u8981\u5f00\u4e00\u4e2a\u5b9a\u65f6\u4efb\u52a1\u53bb\u4e0d\u65ad\u5237\u540e\u7ba1\u7684login\u63a5\u53e3\u5417 \u90a3\u8fd9\u6837\u7684\u8bdd\u5176\u5b9e\u901a\u8fc7API\u8c03\u7528\u4e5f\u662f\u9700\u8981\u7ecf\u8fc7\u540e\u7ba1\u7684\u5417<\/p>\n\n\n\n<p>\u5e94\u8be5\u662f\u8bf4api\u8c03\u7528\u4e2d\u53f0\u670d\u52a1\u8fd8\u662f\u9700\u8981\u7ecf\u8fc7\u4e00\u4e2a\u7f51\u5173\u5427\uff0c\u5e94\u8be5\u662f\u7684\uff0c\u9664\u4e86\u77ed\u94fe\u63a5\u8df3\u8f6c\u4e0d\u7528<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u8fd9\u4e2a\u611f\u89c9\u600e\u4e48\u8bf4\u5462\u611f\u89c9\u6ca1\u4ec0\u4e48\u7528\u5427\uff0c\u9a6c\u4e01\u8bf4\u4e86\u597d\u591a\uff0c\u6bd4\u5982\u8bf4\u5916\u90e8\u6709\u4eba\u8c03\u7528\u8fd9\u4e2a\u4e2d\u53f0\u670d\u52a1\uff0c\u7136\u540e\u8bf4\u89e3\u51b3\u65b9\u6848\u5c31\u662f\u6dfb\u52a0token\u9a8c\u8bc1\uff0c\u4f46\u662f\u4f60\u4e5f\u6ca1\u7ed9\u5177\u4f53\u63aa\u65bd\u554a\uff0c\u8fd8\u6709\u5c31\u662f\u4f60\u8fd9\u8fb9\u8fd9\u4e2a\u5237\u65b0\u611f\u89c9\u6ca1\u6709\u4ec0\u4e48\u7528\uff0c\u8fd9\u4e0d\u5c31\u662f\u6211\u4e0d\u505c\u5730\u70b9\u51fb\u767b\u5f55\u5c31\u4e00\u76f4\u5237\u65b0\u8fd9\u4e2a\u7f13\u5b58\u65f6\u95f4\u5417\uff1f\u6211\u54ea\u6709\u8fd9\u4e48\u591a\u95f2\u5de5\u592b\u4e00\u76f4\u6401\u8fd9\u70b9\u767b\u5f55\uff1f\u4f60\u8fd8\u4e0d\u5982\u5728\u7f51\u5173\u76f4\u63a5\u6dfb\u52a0\u4e00\u4e2a\u8bed\u53e5\u53ea\u8981\u6709\u8bf7\u6c42\u8fc7\u6765\u5c31\u76f4\u63a5\u5237\u65b0\u7528\u6237\u767b\u5f55\u7f13\u5b58\u72b6\u6001\u5c31OK\u4e86\uff0c\u4e0d\u7136\u7684\u8bdd\u6309\u73b0\u5728\u7684\u903b\u8f91\u5c31\u662f\u6bcf30\u5206\u949f\u5c31\u4f1a\u8ba9\u7528\u6237\u5f3a\u5236\u9000\u51fa\u5e76\u91cd\u65b0\u767b\u9646\uff0c\u8fd9\u4e2a\u7b97\u662f\u4e2abug\u5427\uff0c\u8bd5\u95ee\u4f60\u5728\u67d0\u4e2a\u7f51\u7ad9\u770b\u7535\u5f71\uff0c\u7136\u540e\u521a\u4e09\u5341\u5206\u949f\u5c31\u628a\u4f60\u5f3a\u5236\u9000\u51fa\u4e86\uff0c\u4f60\u89c9\u5f97\u4f60\u4e0b\u6b21\u8fd8\u6765\u5417\uff1f\u73b0\u5728\u7f51\u4e0a\u7684\u5927\u90e8\u5206\u767b\u5f55\u903b\u8f91\u4e5f\u5dee\u4e0d\u591a\u662f\u8fd9\u4e2a\u903b\u8f91\u5427<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>&nbsp;\u4e3a\u5565\u8fd9\u91cc\u4f1a\u6c38\u4e0d\u5931\u6548\u4e86\u5462\uff1f\u6211\u7684\u7406\u89e3\u5c31\u662f\u53ea\u6709login\u65f6\u53d1\u73b0\u81ea\u5df130min\u5185\u767b\u9646\u8fc7\u624d\u4f1a\u5237\u65b0\u4e00\u6b21\u6709\u6548\u65f6\u95f4\u3002\u4f46\u662f\u4e0d\u8fd8\u8981\u662f\u6389login\u63a5\u53e3\u5417\uff1f\u5bf9\u554a\uff0c\u90fd\u5df2\u7ecf\u9000\u51fa\u767b\u5f55\u4e86\uff0c\u7f13\u5b58\u4e2d\u5df2\u7ecf\u6ca1\u6709token\u4e86\uff0c\u8fd8\u600e\u4e48\u7eed\u671f\u3002\u7528\u6237\u767b\u5f55\u72b6\u6001\u4e0b\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u4f1a\u8c03\u7528\u767b\u5f55\u63a5\u53e3\uff1f<\/p>\n\n\n\n<p>git\u91cc\u9762\u8fd9\u91cc\u6709\u4e00\u4e2a\u4f18\u5316\u7528\u6237\u767b\u5f55\u63a5\u53e3\u7eed\u671f\u903b\u8f91\uff1a&nbsp;userserviceimpl\u91cc\u9762\u52a0\u4e00\u53e5&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stringRedisTemplate.expire(USER_LOGIN_KEY + requestParam.getUsername(), 30L, TimeUnit.MINUTES);<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c06\u8282\uff1a\u5f00\u53d1\u77ed\u94fe\u63a5\u805a\u5408\u670d\u52a1\uff08\u4e0a\uff09<\/h2>\n\n\n\n<p>\u8fd9\u6837\u6211\u4eec\u628aadmin\u548cproject\u878d\u5408\u4e3a\u4e00\u4e2a\u4e1a\u52a1\uff1b\u8fd9\u6837\u7684\u8bdd\u5927\u5bb6\u6700\u8d77\u7801\u5c11100\u5146\u7684\u4e00\u4e2a\u5185\u5b58\u5bf9\u4e0d\u5bf9\uff1f\u4e3a\u6b64\u7684\u8bdd\u53c2\u800312306\u7684\u6982\u5ff5\uff0c\u6211\u4eec12306\u7684\u670d\u52a1\u6bd4\u8f83\u591a\uff0c\u6211\u662f\u628a\u5b83\u505a\u6210\u5f88\u591a\u4e1a\u52a1\u670d\u52a1\uff0c\u90fd\u6d53\u7f29\u6210\u4e00\u4e2a\u53eb\u505a\u805a\u5408\u670d\u52a1\u4e86\uff0c\u6211\u4eec\u5728\u77ed\u94fe\u63a5\u91cc\u9762\u5176\u5b9e\u4e5f\u53ef\u4ee5\u8fd9\u4e48\u53bb\u505a\uff0c\u4e3a\u6b64\u7684\u8bdd\u6211\u3001\u4e0a\u3001\u5c06\u5b83\u5bf9\u5e94\u7684\u4e00\u4e9b\u6d41\u7a0b\u7ed9\u64cd\u4f5c\u4e86\u4e00\u4e0b\uff0c\u7136\u540e\u8fd9\u8282\u8bfe\u7684\u8bdd\u6211\u5c31\u662f\u5e26\u7740\u5927\u5bb6\u4e00\u8d77\u8ddf\u7740\u6d41\u7a0b\u53bb\u64cd\u4f5c\uff0c\u8fd9\u4e2a\u6587\u6863\u91cc\u9762\u5f88\u6709\u9519\u8bef\uff0c\u4f46\u662f\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u5f53\u4e2d\u6211\u4f1a\u5bf9\u5b83\u8fdb\u884c\u4fee\u590d\uff0c\u6700\u7ec8\u5927\u5bb6\u770b\u5230\u7684\u80af\u5b9a\u662f\u80fd\u591f\u6b63\u5e38\u6d41\uff0c\u80fd\u591f\u6b63\u5e38\u7684\u6267\u884c\u4e0b\u6765\u7684\u3002\u9996\u5148\u6211\u4eec\u5148\u521b\u5efa\u4e00\u4e2a\u5c31\u662f\u805a\u5408\u670d\u52a1\u7684model\uff08\u9009\u62e9maven\uff0c\u56fe\u4e0a\u5fd8\u8bb0\u6807\u8bb0\u4e86\uff09<img loading=\"lazy\" decoding=\"async\" height=\"527\" width=\"592\" src=\"https:\/\/i-blog.csdnimg.cn\/direct\/6a2404f7f66b4780ab139d4d2a676489.png\" alt=\"\"><\/p>\n\n\n\n<p>test\u8fd9\u4e2a\u4e5f\u53ef\u4ee5\u5220\u6389\uff0c\u56e0\u4e3a\u6211\u4eec\u8fd9\u8fb9\u662f\u4e0d\u9700\u8981\u7528\u6d4b\u8bd5\u7684\u3002Ok\u805a\u5408\uff0c\u9996\u5148\u7684\u8bdd\u5b83\u7684\u540d\u5b57\u7ed9\u5b83\u6539\u4e00\u4e0b\uff0c\u7136\u540e\u6211\u4eec\u770b\u4e00\u4e0b\u5b83\u7684\u62a5\u540d\u662f\u5426\u6b63\u786e\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 https:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\n    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\n    &lt;parent&gt;\n        &lt;groupId&gt;com.nageoffer.shortlink&lt;\/groupId&gt;\n        &lt;artifactId&gt;shortlink-all&lt;\/artifactId&gt;\n        &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\n    &lt;\/parent&gt;\n    &lt;artifactId&gt;shortlink-aggregation&lt;\/artifactId&gt;\n\n    &lt;dependencies&gt;\n        &lt;dependency&gt;\n            &lt;groupId&gt;${project.groupId}&lt;\/groupId&gt;\n            &lt;artifactId&gt;shortlink-admin&lt;\/artifactId&gt;\n            &lt;version&gt;${project.version}&lt;\/version&gt;\n        &lt;\/dependency&gt;\n\n        &lt;dependency&gt;\n            &lt;groupId&gt;${project.groupId}&lt;\/groupId&gt;\n            &lt;artifactId&gt;shortlink-project&lt;\/artifactId&gt;\n            &lt;version&gt;${project.version}&lt;\/version&gt;\n        &lt;\/dependency&gt;\n    &lt;\/dependencies&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;build&gt; &lt;finalName&gt;${project.artifactId}&lt;\/finalName&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt; &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt; &lt;executions&gt; &lt;execution&gt; &lt;goals&gt; &lt;goal&gt;repackage&lt;\/goal&gt; &lt;\/goals&gt; &lt;\/execution&gt; &lt;\/executions&gt; &lt;\/plugin&gt; &lt;\/plugins&gt; &lt;\/build&gt;\n&lt;\/project&gt;<\/pre>\n\n\n\n<p>\u5728aggregation\u4e0b\u9762\u52a0\u4e00\u4e2a \u542f\u52a8\u9879&nbsp; AggregationServiceApplication<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.nageoffer.shortlink.aggregation;\nimport org.mybatis.spring.annotation.MapperScan;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.client.discovery.EnableDiscoveryClient;\n\n\/**\n * \u77ed\u94fe\u63a5\u805a\u5408\u5e94\u7528\n *\/\n@EnableDiscoveryClient\n@SpringBootApplication(scanBasePackages = {\n        \"com.nageoffer.shortlink.admin\",\n        \"com.nageoffer.shortlink.project\",\n        \"com.nageoffer.shortlink.aggregation\"\n})\n@MapperScan(value = {\n        \"com.nageoffer.shortlink.project.dao.mapper\",\n        \"com.nageoffer.shortlink.admin.dao.mapper\"\n})\npublic class AggregationServiceApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(AggregationServiceApplication.class, args);\n    }\n}<\/pre>\n\n\n\n<p>&nbsp;\u5bf9\u5e94\u7684application.yaml\u5982\u4e0b<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">server:\n  port: 8003\n\nspring:\n  application:\n    name: short-link-aggregation\n  datasource:\n    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver\n    url: jdbc:shardingsphere:classpath:shardingsphere-config-${database.env:dev}.yaml\n  data:\n    redis:\n      host: 192.168.111.130\n      port: 6379\n      password: 123321\n  mvc:\n    view:\n      prefix: \/templates\/\n      suffix: .html\n  cloud:\n    nacos:\n      discovery:\n        server-addr: 127.0.0.1:8848\n\naggregation:\n  remote-url: http:\/\/127.0.0.1:${server.port}\n\nshort-link:\n  group:\n    max-num: 20\n  flow-limit:\n    enable: true\n    time-window: 1\n    max-access-count: 20\n  domain:\n    default: nurl.ink:8003\n  stats:\n    locale:\n      amap-key: 824c511f0997586ea016f979fdb23087\n  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\n\nmybatis-plus:\n  configuration:\n    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl\n  mapper-locations: classpath:mapper\/*.xml<\/pre>\n\n\n\n<p>\u8fd8\u6709sharingsphere<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dataSources:\n  ds_0:\n    dataSourceClassName: com.zaxxer.hikari.HikariDataSource\n    driverClassName: com.mysql.cj.jdbc.Driver\n    jdbcUrl: jdbc:mysql:\/\/127.0.0.1:3306\/link?useUnicode=true&amp;characterEncoding=UTF-8&amp;rewriteBatchedStatements=true&amp;allowMultiQueries=true&amp;serverTimezone=Asia\/Shanghai\n    username: root\n    password: root\n\nrules:\n  - !SHARDING\n    tables:\n      t_user:\n        actualDataNodes: ds_0.t_user_${0..15}\n        tableStrategy:\n          standard:\n            shardingColumn: username\n            shardingAlgorithmName: user_table_hash_mod\n      t_group:\n        actualDataNodes: ds_0.t_group_${0..15}\n        tableStrategy:\n          standard:\n            shardingColumn: username\n            shardingAlgorithmName: group_table_hash_mod\n      t_link:\n        actualDataNodes: ds_0.t_link_${0..15}\n        tableStrategy:\n          standard:\n            shardingColumn: gid\n            shardingAlgorithmName: link_table_hash_mod\n      t_link_goto:\n        actualDataNodes: ds_0.t_link_goto_${0..15}\n        tableStrategy:\n          standard:\n            shardingColumn: full_short_url\n            shardingAlgorithmName: link_goto_table_hash_mod\n      t_link_stats_today:\n        actualDataNodes: ds_0.t_link_stats_today_${0..15}\n        tableStrategy:\n          standard:\n            shardingColumn: gid\n            shardingAlgorithmName: link_stats_today_hash_mod\n    bindingTables:\n      - t_link, t_link_stats_today\n    shardingAlgorithms:\n      user_table_hash_mod:\n        type: HASH_MOD\n        props:\n          sharding-count: 16\n      group_table_hash_mod:\n        type: HASH_MOD\n        props:\n          sharding-count: 16\n      link_table_hash_mod:\n        type: HASH_MOD\n        props:\n          sharding-count: 16\n      link_goto_table_hash_mod:\n        type: HASH_MOD\n        props:\n          sharding-count: 16\n      link_stats_today_hash_mod:\n        type: HASH_MOD\n        props:\n          sharding-count: 16\n  - !ENCRYPT\n    tables:\n      t_user:\n        columns:\n          phone:\n            cipherColumn: phone\n            encryptorName: common_encryptor\n          mail:\n            cipherColumn: mail\n            encryptorName: common_encryptor\n        queryWithCipherColumn: true\n    encryptors:\n      common_encryptor:\n        type: AES\n        props:\n          aes-key-value: d6oadClrrb9A3GWo\nprops:\n  sql-show: true\n<\/pre>\n\n\n\n<p>AggregationServiceApplication.java shortlink\\aggregation\\src\\main\\java\\com\\nageoffer\\shortlink\\aggregation&nbsp;<br>application.yaml shortlink\\aggregation\\src\\main\\resources&nbsp;<br>shardingsphere-config-dev.yaml shortlink\\aggregation\\src\\main\\resources&nbsp;<br>shardingsphere-config-prod.yaml shortlink\\aggregation\\src\\main\\resources&nbsp;&nbsp;<br>application-aggregation.yaml shortlinkigateway(src\\main\\resources&nbsp;<br>application-dev.yaml shortlink\\gateway\\src\\main\\resources&nbsp;&nbsp;<br>application.yaml shortlink\\gateway\\src\\main\\resources<br>pom.xml shortlink<br>DataBaseConfiguration.java shortlink\\project\\src\\main\\java\\com\\nageoffer\\shortlink\\project\\config<\/p>\n\n\n\n<p>\u7136\u540e\u521b\u5efa\u597d\u4e86\u4e4b\u540e\uff0c\u76f8\u5f53\u4e8e\u6211\u4eec\u8fd9\u4e2a\u914d\u4ef6\u5176\u5b9e\u662f\u5df2\u7ecf\u5305\u542b\u4e86\u6211\u7684\u547d\u548c\u5b83\u7684\u4e24\u4e2a\u914d\u7f6e\u7684\u4e00\u4e2a\u7ec4\u5408\uff0c\u5bf9\u5427\uff1f\u4f60\u6bd4\u5982\u8bf4\u50cf\u8fd9\u8fb9\u662fadmin\u7684\uff0c\u7136\u540e\u6709\u4e00\u4e9b\u662fproject\u7684\uff0c\u5b83\u4e24\u4e2a\u7ec4\u5408\u5728\u4e00\u8d77\u5c31\u53ef\u4ee5\u4e86\uff0c<\/p>\n\n\n\n<p>\u4f60\u770b\u8fd9\u628a\u5b83\u6539\u6389\u4ec0\u4e48\u610f\u601d\uff1f\u5c31\u662f\u5982\u679c\u8bf4\u805a\u5408\u670d\u52a1\u7684 L\u7b49\u4e8e\u4ec0\u4e48\u65f6\u5019\u52a8\uff1f\u5e45\u5ea6\u4e0d\u5bf9\uff0c\u7b49\u4e8e\u7a7a\uff0c\u90a3\u4ec0\u4e48\u65f6\u5019\u4e0d\u7b49\u4e8e\u7a7a\uff1f\u5f53\u6211\u4eec\u542f\u52a8\u805a\u5408\u670d\u52a1\u7684\u65f6\u5019\u4e0d\u7b49\u4e8e\u7a7a\u5bf9\u4e0d\u5bf9\uff1f\u4e0d\u4f1a\u518d\u4ece\u6ce8\u518c\u4e2d\u5fc3\u53bb\u8c03\u7528\u4ed6\u7684 IP\u548c\u7aef\u53e3\u4e86\uff0c\u6211\u4eec\u76f4\u63a5\u7528\u4ec0\u4e48\uff1f\u7528127.0.0.1\u7b49\u4e8e\u81ea\u5df1\u6559\u81ea\u5df1\u660e\u767d\uff0c\u76f8\u5f53\u4e8e\u8d70\u8def\u5faa\u73af\u3002\u6b63\u751f\u4ea7\u73af\u5883\u80af\u5b9a\u4f1a\u6709\u8fd9\u79cd\u4ee3\u7801\uff0c\u5c31\u76f8\u5f53\u4e8e\u76f4\u8fde\u5bf9\u5427\uff1f\u751f\u4ea7\u73af\u5883\u80af\u5b9a\u4e0d\u4f1a\u8fd9\u4e48\u5927\uff0c\u5c31\u662f\u4e3a\u4e86\u6211\u4eec\u81ea\u5df1\u53bb\u65b9\u4fbf\u5927\u5bb6\u90e8\u7f72\uff0c\u7136\u540e\u52a0\u4e86\u4e00\u5c0f\u5757\u7684\u903b\u8f91\uff0c\u5927\u5bb6\u660e\u767d\u5c31\u597d\uff0c12306\u4e5f\u662f\u8fd9\u4e48\u505a\u7684<\/p>\n\n\n\n<p>\u5f00\u59cb\u521b\u5efa\u6211\u4eec\u7684 DEV\u7684\u9875\u9762\uff0cDEV\u6307\u7684\u662f\u5206\u5e03\u5f0f\u7684\u6a21\u5f0f\uff1b\u7136\u540e\u6211\u4eec\u8fd8\u6709\u4e00\u4e2a\u6760\u3002\u4ec0\u4e48\u610f\u601d\uff1f\u8bc1\u660e\u5b83\u662f\u600e\u4e48\u6539\u9020\u7684\uff0c\u5c31\u5982\u679c\u8bf4\u5b83\u7684\u751f\u6548\u6a21\u5f0f\u662f\u805a\u5408\u7684\u8bdd\uff0cok\u5b83\u5c31\u4f1a\u6709\u805a\u5408\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5982\u679c\u8bf4\u5b83\u662fDEV\uff0c\u5b83\u5c31\u4f1a\u8d70\u914d\u7f6e\u6587\u4ef6\uff0c\u6b63\u5e38\u7684\u8bdd\u6211\u4eecDEV\u91cc\u9762\u6211\u4eec\u4ed6\u8fd9\u4e2a\u8001\u677f\u662f\u540e\u9762\u7684\u4ec0\u4e48\u5bf9\u4e0d\u5bf9\uff1f\u7136\u540e\u8fd8\u6709shortlink\u5bf9\u5e94\u5230\u5206\u5e03\u5f0f\u670d\u52a1\u4e0b\u9762\u4e24\u4e2a\u4e0d\u540c\u7684\u670d\u52a1\u805a\u5408\uff0c\u770b\u5230\u6ca1\u6709\uff1f\u7a0d\u5fae\u8ba4\u53ef\u805a\u5408\u5bf9\u4e0d\u5bf9\uff1f\u7a0d\u5fae\u805a\u5408\uff0c\u5b83\u76f8\u5f53\u4e8e\u628a\u8fd9\u4e2a\u4e1c\u897f\u90fd\u53eb\u4ed6\u81ea\u5df1\u5c31\u53ea\u6389\u4e00\u4e2a\u805a\u5408\u670d\u52a1\uff0c\u76f8\u5f53\u4e8e\u7c7b\u4f3c\u4e8e\u8fd9\u79cd\u3002<\/p>\n\n\n\n<p>\u62a5\u9519\u4e86<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c07\u8282\uff1a\u5f00\u53d1\u77ed\u94fe\u63a5\u805a\u5408\u670d\u52a1\uff08\u4e0b\uff09<\/h2>\n\n\n\n<p>\u4ed6\u670d\u52a1\u7684\u6ce8\u518c\u65b9\u5f0f\u4e0d\u592a\u5bf9\u3002\u77e5\u9053\u4e86\u3002\u4ec0\u4e48\u65f6\u5019\u56de\u53bb\uff1f\u4ed6\u7684\u65b9\u5f0f\u7684\u8bdd\u5e94\u8be5\u662f\u770b\u8d1d\u65af\u8fd9\u4e2a\u7684\u8bdd\uff0c\u6211\u4eec\u6539\u6210\u6539\u5c0f\u4e00\u70b9\u5c31\u597d\u4e86\u3002\u5982\u679c\u8bf4\u60f3\u8981\u66f4\u7ec6\u4e00\u70b9\u7684\u8bdd\uff0c\u6211\u4eec\u8fd9\u8fb9\u53ef\u4ee5\u7ed9\u4ed6\u641e\u6210\u4e00\u4e2a\uff1b\u4e3a\u542f\u52a8\u9879\u52a0\u4e0a\u90a3\u4e2a\u4e3a\u90a3\u4e9b\u91cd\u590d\u7684\u9879\u4e00\u8d77\u6dfb\u52a0@Configuration\uff08\u201c...\u201d\uff09<\/p>\n\n\n\n<p>\u7136\u540e\u8fd9\u8fb9\u90a3\u6539\u7684\u4ee3\u7801\u8fd8\u4e0d\u5c11\u5462\u3002\u6ca1\u4e8b\u6211\u4eec\u5148\u6539\uff0c\u56e0\u4e3a\u4f60\u6ca1\u62bd\u7ec4\u4ef6\u7684\u8bdd\u786e\u5b9e\u4f1a\u6709\u8fd9\u4e2a\u95ee\u9898\u3002\u6211\u7684\u547d\u3002\u5bf9\u5c3d\u5feb\u7ed9\u4f60\u3002\u4e24\u4e2a\u4e4b\u95f4\u597d\u50cf\u6709\u4e00\u6837\u7684\u4ee3\u7801\u3002\u4ec0\u4e48\u53e6\u5916\u3002\u5bf9\uff0c\u4e0d\u662f\u5f88\u660e\u663e\u3002\u7136\u540e\u6211\u628a\u4f60 by project ready stream? Just be more. User ok\uff0c\u6ca1\u95ee\u9898\u6ca1\u5173\u7cfb\uff0c\u8bb2\u4ed6\u6709\u65f6\u5019\u4f1a\u62a5\u9519\uff0c\u53ef\u80fd\u4f1a\u6bd4\u8f83\u9017\u6bd4\u3002\u7136\u540e\u8fd9\u4e2a\u7684\u8bdd\u9769\u547d\u91cc\u9762\u6211\u4eec\u518d\u52a0\u4e00\u4e2a\u8003\u8651\u4e00\u4e0b\uff0c\u7136\u540e\u770b\u5230\u4e86\u8fd9\u91cc\u8bf4\u7684\u7acb\u523b\u770b\u51fa\u6765\uff0c\u8fd9\u4e48\u4e00\u4e2a\u4ee3\u4ef7\u3002\u5982\u679c\u5927\u5bb6\u89c9\u5f97\u8fd9\u6bd4\u8f83\u590d\u6742\u7684\u8bdd\uff0c\u5bf9\u5427\uff1f\u4f60\u5982\u679c\u80fd\u63a5\u53d7\u76f4\u63a5\u90e8\u95e8\uff0c\u6211\u7684\u547d\u5176\u5b9e\u5c31\u4e0d\u7528\u8fd9\u4e00\u6b65\u6539\u9020\uff0c\u5982\u679c\u4e0d\u80fd\u63a5\u53d7\uff0c\u4f60\u5c31\u53ea\u80fd\u53bb\u505a\u4e00\u4e0b\u6539\u9020\u4e86\uff0c\u8ddf\u7740\u8fd9\u4e2a\u89c6\u9891\u91cc\u9762\u80af\u5b9a\u662f\u80fd\u591f\u8fc7\u7684\u3002\u6211\u7684 user\u8981\u6c42\u9065\u611f\uff0c\u7136\u540eU\u5b57\u523b\u51fa\u6765\u4e86\u3002&nbsp;<\/p>\n\n\n\n<p>&nbsp;GlobalExceptionHandler.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Component(\"globalExceptionHandlerByAdmin\")\n@Slf4j\n@RestControllerAdvice<\/pre>\n\n\n\n<p>DataBaseConfiguration.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Configuration(value = \"dataBaseConfigurationByAdmin\")\n<\/pre>\n\n\n\n<p>MyMetaObjectHandler.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Primary\n@Component(value = \"myMetaObjectHandlerByAdmin\")<\/pre>\n\n\n\n<p>RBloomFilterConfiguration.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Configuration(value = \"rBloomFilterConfigurationByAdmin\")\n<\/pre>\n\n\n\n<p>&nbsp;RecycleBinController.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@RestController(value = \"shortLinkControllerByAdmin\")\n@RequiredArgsConstructor<\/pre>\n\n\n\n<p>ShortLinkStatsController.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@RestController(value = \"shortLinkStatsControllerByAdmin\")\n@RequiredArgsConstructor<\/pre>\n\n\n\n<p>UrITitleController.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@RestController(value = \"urlTitleControllerByAdmin\")\n@RequiredArgsConstructor<\/pre>\n\n\n\n<p>ShortLinkActualRemoteService.java<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@FeignClient(value = \"short-link-project\", url = \"${aggregation.remote-url:}\")\n<\/pre>\n\n\n\n<p>RecycleBinServicelmpl.java&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Service(value = \"recycleBinServiceImplByAdmin\")<\/pre>\n\n\n\n<p>\u6761\u4ef6\u6ce8\u89e3\u662f\u6307\u5728\u751f\u6210bean\u7684\u65f6\u5019\u4f1a\u68c0\u67e5ioc\u91cc\u9762\u662f\u5426\u6709\u8fd9\u4e48\u4e2abean<\/p>\n\n\n\n<p>&nbsp;\u5982\u679c\u4f60\u4e0d\u7528\u90e8\u7f72\uff0c\u6216\u8005\u8bf4\u90e8\u7f72\u4e5f\u662f\u5206\u5e03\u5f0f\u67b6\u6784\uff0c\u53ef\u4ee5\u8df3\u8fc7\u3002\u805a\u5408\u670d\u52a1\u662f\u4e3a\u4e86\u5e2e\u52a9\u8fdc\u7a0b\u90e8\u7f72\u7684\u540c\u5b66\u8282\u7701\u5185\u5b58\u4f5c\u7528\uff0c\u5b9e\u9645\u5de5\u4f5c\u4e2d\u4e0d\u4f1a\u5b58\u5728<\/p>\n\n\n\n<p>\u4e4b\u524d\u5e03\u9686\u8fc7\u6ee4\u5668\u91cc\u52a0\u5165\u7684\u77ed\u94fe\u63a5\u7aef\u53e3\u53f7\u662f8001\u3002\u6539\u6210\u805a\u5408\u670d\u52a1\u4e4b\u540e\uff0c\u914d\u7f6e\u6587\u4ef6\u91cc\u7aef\u53e3\u53f7\u9700\u8981\u6539\u62108003<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c08\u8282\uff1a\u7ebf\u4e0a\u73af\u5883\u90e8\u7f72\u77ed\u94fe\u63a5\u670d\u52a1\uff08\u805a\u5408\u670d\u52a1\uff09<\/h2>\n\n\n\n<p>&nbsp;\u9996\u5148\u6709\u4e24\u4e2a\u95ee\u9898\u6bd4\u8f83\u4e25\u91cd\uff0c\u7b2c\u4e00\u4e2a\u95ee\u9898\u5c31\u662f\u5206\u9875\u95ee\u9898\uff0c\u5206\u9875\u5927\u5bb6\u53ef\u4ee5\u770b\u5230\u6211\u4eec\u8fd9\u8fb9\u662f\u4f46\u51e1\u662f\u6d89\u53ca\u5230\u5206\u9875\u7684\uff0c\u5176\u5b9e\u4ed6\u90fd\u5df2\u7ecf\u6ca1\u6709\u603b\u6761\u6570\u4e86\uff0c\u7136\u540e\u4ed6\u4e5f\u6ca1\u6709\u90a3\u79cd\u5177\u4f53\u7684\u8bbf\u95ee\u7684\u4e00\u4e2a\u5c31\u662f\u5206\u9875\u9650\u5236\uff0c\u8fd9\u662f\u4ec0\u4e48\u95ee\u9898\u3002\u9996\u5148\u6211\u4eec\u77e5\u9053\u4e4b\u524d\u6211\u4eec\u6539\u8fc7\u4e00\u4e2a\u5730\u65b9\uff0c\u662fproject\u7684config\u3002\u4e3a\u4ec0\u4e48\u53d8\uff1f\u80fd\u591f\u5237\u65b0\u3002\u521a\u624d\u56e0\u4e3a\u6211\u56de\u6eda\u4e86\uff0c\u8fd9\u4e2a\u80af\u5b9a\u662f\u8981\u53d8\u7684\uff0c\u5176\u5b9e\u5b83\u7684\u8bed\u4e49\u662f\u4ec0\u4e48\uff1f@ConditionalOnBean \u5f53\u5b58\u5728\u5b83\u8fd9\u91cc\u9762\u6307\u5b9a\u4e86\u8fd9\u4e2avalue\uff0c\u4e5f\u5c31\u662f\u6bd4\u5982\u8bf4\u6211\u6307\u5b9a\u4e00\u4e2a\u8fd9\u4e2a\u4e1c\u897f@ConditionalOnBean\uff08value= MybatisPlusInterceptor.class\uff09\uff0c\u5b83\u5982\u679c\u8bf4supreme IOC\u5bb9\u5668\u91cc\u9762\u6709\u8fd9\u4e2aBean\u5b83\u624d\u4f1a\u53bb\u52a0\u8f7d\uff0c\u5176\u5b9e\u56e0\u4e3a\u6211\u4eec\u4e0a\u9762\u4e0d\u662f\uff0c\u5176\u5b9e\u5982\u679c\u7528\u542f\u52a8\u7684\u8bdd\uff0c\u5176\u5b9e\u6709\u4e24\u4e2a\u7684\u5bf9\u4e0d\u5bf9\uff1f\u8fd9\u79cd\u60c5\u51b5\u4e0b\u6211\u4eec\u5c31\u4e0d\u80fd\u518d\u7528\u8fd9\u4e2aonbean\uff0c\u5176\u5b9e\u8fd9\u662f\u6211\u7528\u9519\u8bef\u7684\u4e00\u4e2a\u65b9\u6cd5\uff0c\u6211\u4eec\u6b63\u5e38\u5e94\u8be5\u7528\u4ec0\u4e48\uff1f\u4f60\u8fd9\u8fb9\u8fd9\u4e2a\u662f\u4ec0\u4e48\u610f\u601d\uff1f\u5c31\u662f\u5f53IOC\u5bb9\u5668\u91cc\u9762\u6ca1\u6709\u8fd9bean\u7684\u65f6\u5019\u518d\u56de\u53bb\u52a0\u8f7d\uff0c\u5982\u679c\u6709\u7684\u8bdd\u5c31\u52a0\u8f7d\uff0c\u8fd9\u6837\u7684\u8bdd\u662f\u7b26\u5408\u6211\u4eec\u7684\u8bed\u610f\u7684\uff0c\u6211\u4eec\u628a\u4e24\u4e2aDataBaseConfiguration.java\u60f3\u6539\u4e00\u4e0b\u5c31\u597d\u4e86\u3002<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Bean\n@ConditionalOnMissingBean\npublic MybatisPlusInterceptor mybatisPlusInterceptor() {\n    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();\n    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));\n    return interceptor;\n}<\/pre>\n\n\n\n<p>\u9996\u5148\u6211\u4eec\u5c31\u662f\u60f3\u901a\u8fc7\u8fd9\u4e2a\u884c\u4e3a\uff0c\u9996\u5148\u4e00\u70b9idea\u8fd9\u79cd\u65b9\u5f0f\u542f\u52a8\u5185\u6838\uff0c\u901a\u8fc7JDK\u65b9\u5f0f\u4e0d\u4e00\u6837\uff0c\u7684\uff0c\u901a\u8fc7idea\u5b83\u662f\u901a\u8fc7ideal\u81ea\u5e26\u7684\u88ab\u52a0\u8f7d\u7ee7\u7eed\u4e0b\u8f7d\u7684\uff0cJDK\u672c\u8d28\u7684\u533a\u522b\uff0c\u6240\u4ee5\u8bf4\u6709\u4e9b\u60c5\u51b5\u4e0b\u4f60\u5728idea\u91cc\u9762\u662f\u6210\u529f\u7684\uff0c\u4f46\u662fTOMCAT\u91cc\u9762\u4e0d\u4e00\u5b9a\u662f\u6210\u529f\u7684\u3002&nbsp;\u6211\u4eec\u6709\u8fd9\u4e2a\u547d\u4ee4\uff0c\u56e0\u4e3a\u6211\u73b0\u5728\u5176\u5b9e\u5927\u5bb6\u6ca1\u5fc5\u8981\u53bb\u6267\u884c\u8fd9\u4e2a\u64cd\u4f5c\uff0c\u6211\u53ea\u662f\u5927\u5bb6\u5728\u751f\u4ea7\u7ed9\u5927\u5bb6\u6f14\u793a\u4e00\u4e0b\uff0c\u5176\u5b9e\u751f\u4ea7\u4e0a\u7684\u8bdd\u5927\u5bb6\u76f4\u63a5\u7528GD17\uff0c\u6211\u90e8\u7f72\u6587\u6863\u91cc\u9762\u4e5f\u662f\u8fd9\u4e48\u5199\u7684\uff0c\u5927\u5bb6\u76f4\u63a5\u5c31\u672c\u5730\u7684\u7ed9\u5927\u5bb6\u6f14\u793a\u7684\u8bdd\uff0c\u9700\u8981\u53bb\u67e5\u4ed6\u7684\u73af\u5883\uff0c\u5b83\u7684\u73af\u5883\uff0c\u5c31\u662f\u6211\u901a\u8fc7\u6211\u7684\u5b9e\u9645\u7684\u73af\u5883\u76f4\u63a5\u653e\u5047\u53bb\u8fd0\u884c\u597d\u5427\uff0c\u5927\u5bb6\u77e5\u9053\u5c31\u597d\uff0c\u6211\u4eec\u91cd\u65b0\u6253\u5305\u4e00\u4e0b\u3002<\/p>\n\n\n\n<p>\u8bbf\u95ee\u90fd\u662f404\u3002\u521a\u624d\u53ef\u80fd\u662f\u56e0\u4e3a\u6211\u4e4b\u524d\u6211\u867d\u7136\u8bf4\u4ee3\u7801\u56de\u672c\u4e86\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u6ca1\u6709\u6253\u5305\uff0c\u6240\u4ee5\u8bf4\u4ed6\u7684\u6587\u4ef6\u53ef\u80fd\u6ca1\u6709\u53d8\u66f4\uff0c\u7136\u540e\u6211\u4eec\u5237\u4e00\u4e0b\uff0c\u7136\u540e\u91cd\u65b0\u6253\u5305\u4e4b\u540e\uff0c\u5176\u5b9e\u5c31\u662f\u6211\u4eec\u5f53\u524d\u73b0\u5728\u7684\u6700\u7ec8\u7136\u540e\u4ed6\u53d1\u73b0\u5168\u56fd404\u8fd9\u662f\u4e3a\u4ec0\u4e48\uff1f\u5f53\u65f6\u8bf4\u5b9e\u8bdd\u6211\u5f88\u56f0\u60d1\uff0c\u5c31\u662f\u5728\u751f\u4ea7\u4e0a\u4ed6\u4e00\u76f4\u5230404\u5bf9\u5427\uff1f\u4f60\u62a5\u4e2a500\u6216\u8005\u8bf4401\u6211\u90fd\u80fd\u7406\u89e3\uff0c500\u662f\u670d\u52a1\u5668\u65e0\u5f02\u5e38\u5bf9\u5427\uff1f\u7136\u540e401\u662f\u6ca1\u6709\u6743\u9650\u6211\u90fd\u80fd\u7406\u89e3\uff0c\u4f46\u662f\u4f60\u4e3a\u4ec0\u4e48\u62a5404\u5bf9\u4e0d\u5bf9\uff1f\u7136\u540e\u6211\u4e00\u70b9\u70b9\u53bb\u6392\u67e5\uff0c\u5305\u62ec\u5728\u7f51\u7edc\u91cc\u52a0\u65e5\u5fd7\uff0c\u5bf9\u5427\uff1f\u5728\u6211\u4eec\u7684\u4e1a\u52a1\u7cfb\u7edf\u4e5f\u5c31\u662f\u805a\u5408\u670d\u52a1\u91cc\u9762\u52a0\u65e5\u5fd7\u7b49\u7b49\u90fd\u6ca1\u6709\u53d1\u73b0\u95ee\u9898\uff0c\u7136\u540e\u6700\u7ec8\u6211\u60f3\u4e86\u4e00\u4e2a\u70b9\uff0c\u90a3\u5c31\u662f\u770b\u770b\u4ed6\u5230\u5e95\u6709\u6ca1\u6709\u8fdb\u5165\u5230\u6211\u4eec\u7684\u805a\u5408\u670d\u52a1\uff0c\u53d1\u73b0\u4ed6\u8fc7\u7f51\u5173\u4e86\uff0c\u4f46\u662f\u4ed6\u662f\u56f4\u7ed5\u6211\u4eec\u670d\u52a1\u7684\uff0c\u8fd9\u662f\u4ec0\u4e48\u60c5\u51b5\u5462\uff1f&nbsp;\u6765\u627e\u5230\u4e86\u3002\u56e0\u4e3a\u6211\u4eec\u7ec4\u4ef6\u6807\u7684\u5927\u5bb6\u90fd\u77e5\u9053\u5427\u5bf9\u4e0d\u5bf9\uff1f\u4e0d\u662f\u4e0d\u80fd\u4e70\u6211\u6253\u7ed9\u4f60\uff0c\u7136\u540e\u4ed6\u5176\u5b9e\u5c31\u662f\u5c06\u4f60\u4ec0\u4e48\u90e8\u7684\u9879\u76ee\u53d8\u6210\u4e00\u4e2a\u53ef\u6267\u884c\u7684\u5927\u5305\uff0c\u4f46\u662f\u6211\u4eec\u8fd9\u8fb9 project\u5bf9\u5427\uff1f\u5b83\u5176\u5b9e\u6309\u7167\u6211\u4eec\u805a\u5408\u6a21\u5f0f\u7684\u90e8\u7f72\u7684\u8bdd\uff0c\u5b83\u5176\u5b9e\u8fd9\u91cc\u9762\u5b83\u662f\u4e0d\u9700\u8981\u52a0\u4e0a\u652f\u4ed8\u6cd5\u5f8b\u95ee\u9898\u4e86\uff0c\u5c31\u4e86\u89e3\u4e00\u4e0b\u5927\u5bb6\u5982\u679c\u8bf4\uff0c\u4f60\u7528\u805a\u5408\u6a21\u5f0f\uff0c\u4f60\u5c31\u53ea\u80fd\u628a\u4e24\u4e2a\u6587\u4ef6\u5220\u6389\uff0c\u7136\u540e\u4e0d\u65ad\u7684\u7ed9\u5220\u6389<\/p>\n\n\n\n<p>\u90a3\u4e48\u628aadmin\u548cproject \u7684 pom.xml\u7684repackage\u5220\u9664\u4e86\uff0c\u5982\u679c\u4f60\u8981\u7528\u5206\u5e03\u5f0f\u7684\u90e8\u7f72\uff0c\u90a3\u4e48\u4f60\u9700\u8981\u91cd\u65b0\u628a\u90a3\u4e24\u4e2a\u5199\u5165<\/p>\n\n\n\n<p>\u805a\u5408\u6a21\u5f0f\u91cc\u9762AggregationService\u542f\u52a8\u9879\u662f\u53ef\u4ee5\u4e0d\u8981&nbsp;scanBasePackages &nbsp; &nbsp; &nbsp;\u7684&nbsp; \"com.nageoffer.shortlink.aggregation\"<\/p>\n\n\n\n<p>&nbsp;fix:\u4fee\u590d\u805a\u5408\u670d\u52a1\u8fdc\u7a0b\u90e8\u7f72\u670d\u52a1\u5668\u5931\u8d25...(5files)<\/p>\n\n\n\n<p>&nbsp;\u9a6c\u4e01\u90a3\u4e2a\u4e3a\u4e86\u63a8\u9500\u52a0\u4e86\u5173\u6ce8\u516c\u4f17\u53f7\u4e8c\u7ef4\u7801\u7684\u4eba\u673a\u9a8c\u8bc1\u529f\u80fd<\/p>\n\n\n\n<p>\u4ed6\u5199\u4e86\u90e8\u7f72\u6587\u6863\uff0c&nbsp;\u90e8\u7f72\u7684\u65f6\u5019\uff0c\u6211\u4e5f\u9047\u5230\u8fd9\u4e2a\u95ee\u9898\u4e86 404 \uff0c\u6392\u67e5\u4e86\u5f88\u4e45\u5f88\u4e45\u3002 \u6392\u67e5\u4e86\u5f88\u4e45\uff0c\u6392\u67e5\u5230\u8bf7\u6c42\u5230\u7f51\u5173\u4e86\uff0c\u4f46\u662f\u6ca1\u6709\u6253\u5230\u805a\u5408\u670d\u52a1\u4e0a\u9762\u3002 \u6211\u5c31\u50cf\u662f\u4e0d\u662f jar \u5305\u6709\u95ee\u9898\u554a\u3002 \u679c\u7136\u662f\u805a\u5408\u670d\u52a1 \u7684jar \u5305\u6ca1\u6253\u597d\uff0c\u641e\u4e86\u4e0b maven \u6253\u5305\u63d2\u4ef6\uff0c\u7ec8\u4e8e\u90e8\u7f72\u597d\u4e86<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">- \u7b2c09\u8282\uff1a\u5982\u4f55\u901a\u8fc7\u57df\u540d\u8bbf\u95ee\u7ebf\u4e0a\u670d\u52a1<\/h2>\n\n\n\n<p>\u5c31\u662f\u90a3\u6837\u7684 \u200b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8211; \u7b2c01\u8282\uff1a\u5982\u4f55\u6539\u9020\u4e3a\u5fae\u670d\u52a1\u67b6\u6784\uff1f 1. \u6a21\u5757\u5316\u548c\u72ec\u7acb\u6027 2. \u6280\u672f\u5f02\u6784\u6027 3. \u72ec\u7acb\u90e8\u7f72\u548c\u6269\u5c55 4. \u56e2\u961f\u81ea\u6cbb 5. \u5f39\u6027\u548c\u5bb9 &#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-1220","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\/1220","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=1220"}],"version-history":[{"count":1,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1220\/revisions"}],"predecessor-version":[{"id":1221,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1220\/revisions\/1221"}],"wp:attachment":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}