{"@attributes":{"version":"2.0"},"channel":{"title":"SSpirits\u306e\u79d8\u5bc6\u57fa\u5730","link":"https:\/\/blog.lv5.moe\/","description":"Recent content on SSpirits\u306e\u79d8\u5bc6\u57fa\u5730","generator":"Hugo -- gohugo.io","language":"en-us","lastBuildDate":"Thu, 01 May 2025 11:02:00 +0800","item":[{"title":"\u7f51\u7edc\u6293\u5305\u5206\u6790\u6848\u4f8b\uff1aSNI \u963b\u65ad","link":"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis","pubDate":"Thu, 01 May 2025 11:02:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis\/cover.jpg\" alt=\"Featured image of post \u7f51\u7edc\u6293\u5305\u5206\u6790\u6848\u4f8b\uff1aSNI \u963b\u65ad\" \/><h2 id=\"\u80cc\u666f\">\u80cc\u666f<\/h2>\n<p>\u67d0\u5ba2\u6237\u53cd\u9988\u5176\u90e8\u5206\u7ec8\u7aef\u8bbe\u5907\u65e0\u6cd5\u8bbf\u95ee\u6211\u65b9\u670d\u52a1\uff0c\u6545\u969c\u73b0\u8c61\u5448\u73b0\u8bbe\u5907\u9009\u62e9\u6027\u65ad\u8fde\u7684\u7279\u5f81\uff0c\u9700\u8981\u6211\u4eec\u534f\u52a9\u6392\u67e5\u3002\u597d\u5728\u8be5\u95ee\u9898\u53ef\u4ee5\u7a33\u5b9a\u590d\u73b0\uff0c\u6240\u4ee5\u6211\u4eec\u8bf7\u5ba2\u6237\u5728\u6d4b\u8bd5\u73af\u5883\u4e2d\u590d\u73b0\u95ee\u9898\u5e76\u8fdb\u884c\u6293\u5305\uff0c\u4e8e\u662f\u4fbf\u5f00\u59cb\u4e86\u672c\u6b21\u6392\u67e5\u4e4b\u65c5<\/p>\n<h2 id=\"mtls-\u8ba4\u8bc1\u6392\u67e5\">mTLS \u8ba4\u8bc1\u6392\u67e5<\/h2>\n<p>\u56e0\u4e3a\u5ba2\u6237\u4f7f\u7528 mTLS \u8fdb\u884c\u8ba4\u8bc1\u548c\u52a0\u5bc6\u8fde\u63a5\uff0c\u5e76\u4e14\u53ea\u6709\u90e8\u5206\u8bbe\u5907\u51fa\u73b0\u95ee\u9898\u3002\u6240\u4ee5\u4f18\u5148\u6000\u7591\u8bbe\u5907\u5ba2\u6237\u7aef\u8bc1\u4e66\u975e\u6cd5\u6216\u8005\u8fc7\u671f\u3002\u6211\u4eec\u7684\u670d\u52a1\u7aef\u5b9e\u73b0\u4e86\u5bf9\u5ba2\u6237\u7aef\u8bc1\u4e66\u94fe\u7684\u6821\u9a8c\u903b\u8f91\uff0c\u5728\u8bc1\u4e66\u6821\u9a8c\u4e0d\u901a\u8fc7\u65f6\u4f1a\u8bb0\u5f55\u5ba1\u8ba1\u65e5\u5fd7\u3002\u6240\u4ee5\u6211\u4eec\u8bf7\u5ba2\u6237\u5728\u6d4b\u8bd5\u73af\u5883\u4e2d\u590d\u73b0\u95ee\u9898\u5e76\u8fdb\u884c\u6293\u5305\uff0c\u5e0c\u671b\u80fd\u591f\u62ff\u5230\u7528\u6237\u8bbe\u5907\u4f7f\u7528\u7684\u8bc1\u4e66\u4ee5\u4fbf\u4e8e\u6211\u4eec\u8fdb\u884c\u6392\u67e5\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 196;\nflex-basis: 472px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis\/client-packet-capture.jpg\" data-size=\"3128x1590\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis\/client-packet-capture.jpg\"\nwidth=\"3128\"\nheight=\"1590\"\nloading=\"lazy\"\nalt=\"\u8bbe\u5907\u4fa7\u7f51\u7edc\u6293\u5305\">\n<\/a>\n<figcaption>\u8bbe\u5907\u4fa7\u7f51\u7edc\u6293\u5305<\/figcaption>\n<\/figure><\/p>\n<p>\u770b\u5230\u8fd9\u4e2a\u6293\u5305\u6587\u4ef6\u5c31\u53d1\u73b0\u4e8b\u60c5\u5e76\u4e0d\u8fd9\u4e48\u7b80\u5355\uff1a\u62a5\u6587\u4e2d\u5e76\u6ca1\u6709\u8bc1\u4e66\u4ea4\u6362\u7684\u8fc7\u7a0b\uff0c\u53ea\u6709\u4e00\u4e2a <code>Client Hello<\/code> \u62a5\u6587\uff0c\u7136\u540e\u6536\u5230\u4e86 RST \u62a5\u6587\u5bfc\u81f4\u8fde\u63a5\u91cd\u7f6e\u3002\u8fd9\u8bf4\u660e\u670d\u52a1\u7aef\u5728\u6ca1\u6709\u63a5\u6536\u5230\u5ba2\u6237\u7aef\u8bc1\u4e66\u7684\u60c5\u51b5\u4e0b\u65ad\u5f00\u4e86\u8fde\u63a5\uff0c\u6211\u4eec\u5728\u670d\u52a1\u7aef\u7684\u5ba1\u8ba1\u65e5\u5fd7\u4e2d\u6ca1\u6709\u5728\u7528\u6237\u6293\u5305\u65f6\u6bb5\u770b\u5230\u4efb\u4f55\u8bc1\u4e66\u6821\u9a8c\u5931\u8d25\u7684\u8bb0\u5f55\u4e5f\u4f50\u8bc1\u4e86\u8fd9\u70b9<\/p>\n<p>\u7531\u4e8e\u5e94\u7528\u5c42\u65e0\u6709\u6548\u4fe1\u606f\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5728\u670d\u52a1\u7aef\u6267\u884c\u7f51\u7edc\u6293\u5305\u4ee5\u5b9a\u4f4d\u95ee\u9898<\/p>\n<h2 id=\"\u7f51\u7edc\u94fe\u8def\u5206\u6790\">\u7f51\u7edc\u94fe\u8def\u5206\u6790<\/h2>\n<p>\u5728\u5f00\u59cb\u670d\u52a1\u7aef\u6293\u5305\u4e4b\u524d\u9996\u5148\u9700\u8981\u68b3\u7406\u4e00\u4e0b\u7f51\u7edc\u94fe\u8def\uff1a\u5ba2\u6237\u7684\u8bbe\u5907\u901a\u8fc7\u516c\u7f51\u8bbf\u95ee\u6211\u4eec\u7684\u670d\u52a1\uff0c\u7528\u6237\u4fa7\u6ca1\u6709\u7f51\u5173\u8bbe\u5907\u3002\u4f46\u662f\u5728\u670d\u52a1\u4fa7\u6709\u63a5\u5165\u7f51\u5173\u548c\u8d1f\u8f7d\u5747\u8861\u5668\uff0c\u7528\u6237\u7684\u8bbe\u5907\u901a\u8fc7\u81ea\u5b9a\u4e49\u7684\u57df\u540d CNAME \u89e3\u6790\u5230\u6211\u4eec\u7684\u63a5\u5165\u7f51\u5173\uff0c\u63a5\u5165\u7f51\u5173\u4f1a\u5c06\u8bf7\u6c42\u8f6c\u53d1\u5230\u5e94\u7528\u670d\u52a1\u5668\u3002\u6574\u4e2a\u94fe\u8def\u5927\u81f4\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">\u7528\u6237\u7ec8\u7aef\u8bbe\u5907\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> | \u516c\u7f51\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u516c\u7f51\u63a5\u5165\u7f51\u5173\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> | \u5185\u7f51\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">L4 \u8d1f\u8f7d\u5747\u8861\u5668\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> | \u5185\u7f51\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u5e94\u7528\u670d\u52a1\u5668\n<\/span><\/span><\/code><\/pre><\/div><p>\u76f4\u89c9\u4e0a\u6000\u7591\u7528\u6237\u7f51\u7edc\u73af\u5883\u4e0a\u7684 DNS \u914d\u7f6e\u6709\u95ee\u9898\uff0c\u5bfc\u81f4\u6d41\u91cf\u6ca1\u6709\u6253\u5230\u6211\u4eec\u670d\u52a1\u7684\u63a5\u5165\u7f51\u5173\u4e0a\uff0c\u800c\u662f\u88ab\u52ab\u6301\u5230\u5176\u4ed6\u5730\u65b9\u3002\u4f46\u662f\u901a\u8fc7\u5bf9\u6bd4\u7528\u6237\u4fa7\u6b63\u5e38\u7684\u8bbe\u5907\u548c\u5f02\u5e38\u7684\u8bbe\u5907\u7684\u6293\u5305\uff0c\u53d1\u73b0 DNS \u89e3\u6790\u7684\u7ed3\u679c\u662f\u4e00\u6837\u7684\uff0c\u8bf4\u660e DNS \u89e3\u6790\u6ca1\u6709\u95ee\u9898<\/p>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u5728\u5e94\u7528\u670d\u52a1\u5668\u4e0a\u8fdb\u884c\u6293\u5305\uff0c\u9a8c\u8bc1\u5ba2\u6237\u8bbe\u5907\u7684\u8bf7\u6c42\u662f\u5426\u6b63\u5e38\u62b5\u8fbe\uff0c\u4ee5\u6392\u9664\u7f51\u7edc\u8def\u7531\u7684\u95ee\u9898<\/p>\n<h2 id=\"\u6293\u5305\u5206\u6790\">\u6293\u5305\u5206\u6790<\/h2>\n<p>\u901a\u8fc7\u548c\u7528\u6237\u7ea6\u5b9a\u65f6\u95f4\u540c\u65f6\u6293\u5305\u53d1\u73b0\uff0c\u786e\u5b9e\u6709\u8bf7\u6c42\u5230\u8fbe\u4e86\u6211\u4eec\u7684\u5e94\u7528\u670d\u52a1\u5668\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 318;\nflex-basis: 764px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis\/server-packet-capture.jpg\" data-size=\"3448x1082\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/decoding-sni-blocking-through-packet-capture-analysis\/server-packet-capture.jpg\"\nwidth=\"3448\"\nheight=\"1082\"\nloading=\"lazy\"\nalt=\"\u670d\u52a1\u7aef\u7f51\u7edc\u6293\u5305\">\n<\/a>\n<figcaption>\u670d\u52a1\u7aef\u7f51\u7edc\u6293\u5305<\/figcaption>\n<\/figure><\/p>\n<p>\u4f46\u662f\u5bf9\u6bd4\u5ba2\u6237\u7aef\u6293\u5305\uff0c\u5e76\u6ca1\u6709\u51fa\u73b0 <code>Client Hello<\/code> \u62a5\u6587\uff0c\u5e76\u4e14\u66f4\u5947\u602a\u7684\u662f\u670d\u52a1\u7aef\u6293\u5305\u663e\u793a RST \u62a5\u6587\u6765\u81ea\u5bf9\u7aef\uff01\u4e5f\u5c31\u662f\u8bf4\u5ba2\u6237\u7aef\u548c\u670d\u52a1\u7aef\u5747\u8ba4\u4e3a\u5bf9\u65b9\u53d1\u4e86 RST \u62a5\u6587\uff0c\u90a3\u4e48\u5927\u6982\u7387\u5c31\u662f\u201c\u4e2d\u95f4\u4eba\u201d\u540c\u65f6\u5411\u4e24\u4fa7\u53d1\u7684 RST \u62a5\u6587<\/p>\n<p>\u90a3\u4e48\u600e\u4e48\u5feb\u901f\u5224\u65ad\u6240\u8c13\u7684\u201c\u4e2d\u95f4\u4eba\u201d\u662f\u54ea\u4e00\u4fa7\u7684\u7f51\u7edc\u8bbe\u5907\u5462\uff1f\u8fd9\u91cc\u6709\u4e2a\u5c0f\u6280\u5de7\uff0c\u53ef\u4ee5\u901a\u8fc7 TTL \u6765\u5224\u65ad\uff1a<\/p>\n<p>\u670d\u52a1\u7aef\u7684\u6d41\u91cf\u8bb0\u5f55\uff1a\u6536\u5230\u4e86\u4e09\u4e2a\u6765\u81ea\u5ba2\u6237\u7aef\u7684\u62a5\u6587<\/p>\n<ul>\n<li>SYN\uff1aTTL=52<\/li>\n<li>ACK\uff1aTTL=52<\/li>\n<li>RST\uff1aTTL=52<\/li>\n<\/ul>\n<p>\u5ba2\u6237\u7aef\u7684\u6d41\u91cf\u8bb0\u5f55\uff1a\u8fd9\u91cc\u5ba2\u6237\u7aef\u6536\u5230\u4e86\u4e09\u4e2a\u6765\u81ea\u670d\u52a1\u7aef\u7684\u62a5\u6587<\/p>\n<ul>\n<li>SYN, ACK\uff1aTTL=50<\/li>\n<li>RST\uff1aTTL=64<\/li>\n<\/ul>\n<p>\u53ef\u4ee5\u770b\u5230\u5ba2\u6237\u7aef\u6536\u5230\u7684\u62a5\u6587\u7684 TTL \u503c\u6539\u53d8\u4e86\uff0c\u8fd9\u8bf4\u660e\u5ba2\u6237\u7aef\u6536\u5230\u7684 RST \u62a5\u6587\u4e0d\u662f\u670d\u52a1\u7aef\u53d1\u7684\uff0c\u800c\u4e14\u76f8\u6bd4\u4e8e\u670d\u52a1\u7aef\u7684 TTL \u503c\u66f4\u5927\u3002\u53ef\u4ee5\u63a8\u6d4b\u51fa\u8fd9\u4e2a RST \u62a5\u6587\u53ef\u80fd\u662f\u6765\u81ea\u4e8e\u9760\u8fd1\u7528\u6237\u4fa7\u7684\u7f51\u7edc\u8bbe\u5907\u53d1\u51fa<\/p>\n<h2 id=\"\u7ed3\u8bba\">\u7ed3\u8bba<\/h2>\n<p>\u8003\u8651\u5230\u7528\u6237\u4f7f\u7528\u516c\u7f51\u81ea\u5b9a\u4e49\u57df\u540d\u8bbf\u95ee\uff0c\u5e76\u4e14\u5728\u53d1\u51fa <code>Client Hello<\/code> \u62a5\u6587\u540e\u5c31\u88ab\u91cd\u7f6e\u8fde\u63a5\uff0c\u6000\u7591\u662f\u906d\u9047\u4e86 SNI \u963b\u65ad\u3002\u5411\u7528\u6237\u53cd\u9988\u4e86\u8fd9\u4e2a\u60c5\u51b5\u540e\uff0c\u7528\u6237\u548c\u4ed6\u4eec\u7684\u8fd0\u8425\u5546\u8fdb\u884c\u4e86\u8054\u7cfb\u53d1\u73b0\u662f\u8fd0\u8425\u5546\u4e00\u4fa7\u7684\u7f51\u7edc\u914d\u7f6e\u95ee\u9898\u5bfc\u81f4\uff0c\u672c\u6b21\u4e8b\u4ef6\u4e5f\u7b97\u662f\u5706\u6ee1\u89e3\u51b3\u4e86<\/p>"},{"title":"MCP with GraphQL \u2014\u2014 LLM \u5927\u6a21\u578b\u9ad8\u6548\u8bbf\u95ee\u5f02\u6784\u6570\u636e\u6e90","link":"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources","pubDate":"Sat, 29 Mar 2025 23:25:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/cover.jpg\" alt=\"Featured image of post MCP with GraphQL \u2014\u2014 LLM \u5927\u6a21\u578b\u9ad8\u6548\u8bbf\u95ee\u5f02\u6784\u6570\u636e\u6e90\" \/><p>\u5728 RocketMQ \u7684\u65e5\u5e38\u8fd0\u7ef4\u4e2d\uff0c\u6211\u4eec\u7ecf\u5e38\u9700\u8981\u8bbf\u95ee\u4e0d\u540c\u7684\u6570\u636e\u6e90\u6765\u83b7\u53d6\u8bca\u65ad\u4fe1\u606f\u3002\u4f20\u7edf\u7684\u65b9\u5f0f\u5f80\u5f80\u9700\u8981\u7f16\u5199\u590d\u6742\u7684\u67e5\u8be2\u8bed\u53e5\uff0c\u6216\u8005\u5728\u591a\u4e2a\u7cfb\u7edf\u4e4b\u95f4\u5207\u6362\uff0c\u6548\u7387\u4f4e\u4e0b<\/p>\n<p>\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u4f7f\u7528 LLM \u7ed3\u5408 MCP \u6765\u5b9e\u73b0\u9ad8\u6548\u7684\u6570\u636e\u8bbf\u95ee\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\uff0c\u53ef\u4ee5\u7528<strong>\u81ea\u7136\u8bed\u8a00\u4e00\u7ad9\u5f0f\u67e5\u8be2<\/strong>\u6240\u9700\u7684\u4fe1\u606f\uff0c\u63d0\u9ad8\u8fd0\u7ef4\u6548\u7387<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/operation-system-vs-llm.jpg\" width=\"651\" height=\"533\"\/><figcaption>\n<h4>\u4f20\u7edf\u65b9\u6cd5\u5bf9\u6bd4\u5927\u6a21\u578b<\/h4>\n<\/figcaption>\n<\/figure>\n<h2 id=\"\u524d\u8a00\">\u524d\u8a00<\/h2>\n<p>\u5728 RocketMQ \u7684\u65e5\u5e38\u8fd0\u7ef4\u4e2d\uff0c\u6211\u4eec\u7ecf\u5e38\u9700\u8981\u8bbf\u95ee\u4e0d\u540c\u7684\u6570\u636e\u6e90\u6765\u83b7\u53d6\u8bca\u65ad\u4fe1\u606f\u3002\u4e0b\u56fe\u662f\u6211\u4eec\u8bca\u65ad\u95ee\u9898\u65f6\u9700\u8981\u8bbf\u95ee\u7684\u5e38\u89c1\u6570\u636e\u6e90\u548c\u4ed6\u4eec\u63d0\u4f9b\u7684\u67e5\u8be2\u63a5\u53e3\uff1a<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">flowchart TD\nsubgraph Observability\ndirection LR\nMetrics[&#34;Metrics &lt;br&gt;(WebUI\/PromQL)&#34;]\nLogs[&#34;Logs &lt;br&gt;(WebUI\/SQL)&#34;]\nTrace[&#34;Trace &lt;br&gt;(WebUI\/gRPC)&#34;]\nend\nsubgraph External Storage\ndirection LR\nObjectStorage[&#34;Object Storage &lt;br&gt;(WebUI\/S3 API)&#34;]\nDB[&#34;Database &lt;br&gt;(WebUI\/SQL)&#34;]\nConfigCenter[&#34;Config Center &lt;br&gt;(WebUI\/REST API)&#34;]\nend\nsubgraph Runtime Data\ndirection LR\nNameServer[&#34;RocketMQ NameServer &lt;br&gt;(CLI\/Binary Protocol)&#34;]\nBroker[&#34;RocketMQ Broker &lt;br&gt;(CLI\/Binary Protocol)&#34;]\nend\nsubgraph IaaS Data\ndirection LR\nKubnetes[&#34;Kubernetes &lt;br&gt;(WebUI\/K8S API)&#34;]\nend\n<\/div>\n<p>\u4e00\u822c\u6765\u8bf4\u8fd0\u7ef4\u4eba\u5458\u5982\u679c\u60f3\u8981\u83b7\u53d6\u67d0\u4e2a\u6570\u636e\u6e90\u7684\u4fe1\u606f\uff0c\u901a\u5e38\u9700\u8981\u5148\u767b\u5f55\u5230\u5bf9\u5e94\u7684\u7cfb\u7edf\uff0c\u7136\u540e\u7f16\u5199\u67e5\u8be2\u8bed\u53e5\uff0c\u6700\u540e\u518d\u89e3\u6790\u8fd4\u56de\u7684\u7ed3\u679c\u3002\u8fd9\u4e0d\u4f46\u9700\u8981\u8fd0\u7ef4\u4eba\u5458\u719f\u6089\u6bcf\u4e2a\u6570\u636e\u6e90\u7684\u67e5\u8be2\u8bed\u6cd5\uff0c\u8fd8\u9700\u8981\u5728\u4e0d\u540c\u7684\u7cfb\u7edf\u4e4b\u95f4\u5207\u6362\uff0c\u6548\u7387\u4f4e\u4e0b<\/p>\n<p>\u806a\u660e\u7684\u56e2\u961f\u4f1a\u5f00\u53d1\u4e00\u4e2a\u201c\u8fd0\u8425\u7cfb\u7edf\u201d\uff0c\u63d0\u4f9b\u7edf\u4e00\u7684\u67e5\u8be2\u754c\u9762\u3002\u4f46\u662f\u4ecd\u7136\u6ca1\u6709\u89e3\u51b3\u53cd\u590d\u5207\u6362\u5de5\u5177\uff0c\u67e5\u8be2\u788e\u7247\u5316\u7684\u95ee\u9898\uff1b\u66f4\u8fdb\u4e00\u6b65\u53ef\u4ee5\u5c06\u5e38\u89c1\u7684\u6392\u67e5\u8fc7\u7a0b\u4e2d\u7528\u5230\u7684\u5de5\u5177\u4e32\u8054\u5230\u4e00\u8d77\uff0c\u5f62\u6210\u4e00\u4e2a\u201c\u67e5\u8be2\u6d41\u6c34\u7ebf\u201d\u3002\u4f46\u662f\u8fd9\u6837\u7684\u7cfb\u7edf\u5f80\u5f80\u9700\u8981\u6392\u67e5\u95ee\u9898\u7684\u4e13\u5bb6\u7ecf\u9a8c\u6c89\u6dc0\u3001\u5927\u91cf\u7684\u5f00\u53d1\u548c\u7ef4\u62a4\u5de5\u4f5c\uff0c\u4e14\u96be\u4ee5\u9002\u5e94\u5feb\u901f\u53d8\u5316\u7684\u9700\u6c42<\/p>\n<p>\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 LLM \u7ed3\u5408 MCP \u6765\u5b9e\u73b0\u9ad8\u6548\u7684\u6570\u636e\u8bbf\u95ee\u3002\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\uff0c\u7528<strong>\u81ea\u7136\u8bed\u8a00\u4e00\u7ad9\u5f0f\u67e5\u8be2<\/strong>\u6240\u9700\u7684\u4fe1\u606f\uff0c\u63d0\u9ad8\u95ee\u9898\u8bca\u65ad\u7684\u6548\u7387<\/p>\n<h2 id=\"talk-is-cheap-show-me-the-demo\">Talk is cheap, show me the demo!<\/h2>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/llm-workflow.jpg\" width=\"770\" height=\"305\"\/><figcaption>\n<h4>LLM Workflow<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u501f\u52a9 LLM + Chatbox + MCP + GraphQL \u7684\u7ec4\u5408\uff0c\u7528\u81ea\u7136\u8bed\u8a00\u67e5\u8be2 RocketMQ \u96c6\u7fa4\u7684\u72b6\u6001\u3001Topic \u7684\u4fe1\u606f\u3001\u6d88\u606f\u7684\u5185\u5bb9\u7b49<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 44;\nflex-basis: 107px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-cluster.jpg\" data-size=\"1923x4302\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-cluster.jpg\"\nwidth=\"1923\"\nheight=\"4302\"\nloading=\"lazy\"\nalt=\"\u67e5\u8be2\u96c6\u7fa4\u548c\u8282\u70b9\">\n<\/a>\n<figcaption>\u67e5\u8be2\u96c6\u7fa4\u548c\u8282\u70b9<\/figcaption>\n<\/figure><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 79;\nflex-basis: 191px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-topic.jpg\" data-size=\"1632x2048\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-topic.jpg\"\nwidth=\"1632\"\nheight=\"2048\"\nloading=\"lazy\"\nalt=\"\u67e5\u8be2 Topic\">\n<\/a>\n<figcaption>\u67e5\u8be2 Topic<\/figcaption>\n<\/figure><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 74;\nflex-basis: 178px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-message.jpg\" data-size=\"1524x2048\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/rocketmq-mcp-message.jpg\"\nwidth=\"1524\"\nheight=\"2048\"\nloading=\"lazy\"\nalt=\"\u67e5\u8be2\u6d88\u606f\">\n<\/a>\n<figcaption>\u67e5\u8be2\u6d88\u606f<\/figcaption>\n<\/figure><\/p>\n<p>Awesome\uff01\u7406\u8bba\u4e0a\u53ea\u8981\u662f\u5728\u6211\u4eec\u7cfb\u7edf\u5185\u7684\u4fe1\u606f\uff0c\u90fd\u53ef\u4ee5\u901a\u8fc7<strong>\u4e00\u6b21\u81ea\u7136\u8bed\u8a00\u4ea4\u4e92<\/strong>\u67e5\u51fa\u6765\uff0c\u5e76\u4e14\u53ef\u4ee5\u8fde\u7eed\u8ffd\u95ee\u76f4\u5230\u627e\u5230\u95ee\u9898\u6839\u56e0\u3002\u518d\u4e5f\u4e0d\u9700\u8981\u8bbf\u95ee\u4e00\u5927\u5806\u670d\u52a1\uff0c\u7f16\u8f91\u547d\u4ee4\u884c\u53c2\u6570\/SQL \u6216\u8005\u5728\u524d\u7aef\u754c\u9762\u4e4b\u95f4\u8df3\u6765\u8df3\u53bb\u4e86<\/p>\n<h2 id=\"\u5b9e\u73b0\u539f\u7406\">\u5b9e\u73b0\u539f\u7406<\/h2>\n<h3 id=\"llm-\u5927\u8bed\u8a00\u6a21\u578b\">LLM \u5927\u8bed\u8a00\u6a21\u578b<\/h3>\n<p>\u5728\u8fd9\u4e2a\u7ec4\u5408\uff08LLM + Chatbox + MCP + GraphQL\uff09\u4e2d\uff0cLLM \u5145\u5f53\u4e86\u81ea\u7136\u8bed\u8a00\u5904\u7406\u7684\u6838\u5fc3\u7ec4\u4ef6\u3002\u7528\u6237\u901a\u8fc7 Chatbox \u8f93\u5165\u81ea\u7136\u8bed\u8a00\u67e5\u8be2\uff0cLLM \u5c06\u5176\u8f6c\u6362\u4e3a GraphQL \u67e5\u8be2\u8bed\u53e5\uff0c\u5e76\u901a\u8fc7 MCP \uff08\u5927\u6a21\u578b\u8c03\u7528\u5de5\u5177\u7684\u534f\u8bae\uff0c\u8fd9\u91cc\u53ef\u4ee5\u8ba4\u4e3a\u662f GraphQL \u5ba2\u6237\u7aef\uff09\u63d0\u4ea4\u5230\u540e\u7aef\u670d\u52a1\u3002\u540e\u7aef\u670d\u52a1\u8fd4\u56de\u7684 JSON \u683c\u5f0f\u67e5\u8be2\u7ed3\u679c\u53c8\u4f1a\u88ab LLM \u8f6c\u6362\u4e3a\u4eba\u7c7b\u66f4\u6613\u61c2\u7684\u683c\u5f0f\uff0c\u4ece\u800c\u5b9e\u73b0\u4e86\u81ea\u7136\u8bed\u8a00\u4e0e\u6570\u636e\u6e90\u4e4b\u95f4\u7684\u9ad8\u6548\u4ea4\u4e92<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 176;\nflex-basis: 423px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/llm-example.jpg\" data-size=\"1610x912\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/llm-example.jpg\"\nwidth=\"1610\"\nheight=\"912\"\nloading=\"lazy\"\nalt=\"Chatbox \u4e2d\u7684\u5bf9\u8bdd\">\n<\/a>\n<figcaption>Chatbox \u4e2d\u7684\u5bf9\u8bdd<\/figcaption>\n<\/figure><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 178;\nflex-basis: 427px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/graphql-example.jpg\" data-size=\"1798x1010\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mcp-with-graphql-llm-access-heterogeneous-data-sources\/graphql-example.jpg\"\nwidth=\"1798\"\nheight=\"1010\"\nloading=\"lazy\"\nalt=\"\u5bf9\u5e94\u7684 GraphQL \u67e5\u8be2\u548c\u7ed3\u679c\">\n<\/a>\n<figcaption>\u5bf9\u5e94\u7684 GraphQL \u67e5\u8be2\u548c\u7ed3\u679c<\/figcaption>\n<\/figure><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock \">\n<p>\u56fe\u4e2d\u7684 introspect-schema \u7528\u6765\u83b7\u53d6 GraphQL \u7684 schema \u4fe1\u606f\uff0c\u5e2e\u52a9 LLM \u7406\u89e3\u6570\u636e\u7ed3\u6784\u548c\u5b57\u6bb5<\/p>\n<p>\u5b9e\u9645\u4e0a\u53ea\u9700\u8981\u5728\u5f00\u59cb\u5bf9\u8bdd\u7684\u65f6\u5019\u8c03\u7528\u4e00\u6b21\u5373\u53ef\uff0c\u8fd9\u91cc\u6bcf\u6b21\u4ea4\u4e92\u90fd\u8c03\u7528\u662f\u56e0\u4e3a\u535a\u4e3b\u4f7f\u7528\u7684 Chatbox \u6ca1\u6709\u6b63\u786e\u4f7f\u7528 MCP \u534f\u8bae\uff0c\u6362\u6210\u652f\u6301 <a class=\"link\" href=\"https:\/\/modelcontextprotocol.io\/docs\/concepts\/resources\" target=\"_blank\" rel=\"noopener\"\n>MCP Resources<\/a> \u7684\u5de5\u5177\u4f8b\u5982 Claude Desktop \u5c31\u53ef\u4ee5\u907f\u514d\u591a\u6b21\u8bf7\u6c42 schema<\/p>\n<\/div>\n<p><\/p>\n<p>\u901a\u8fc7 LLM \u6765\u7ec4\u7ec7\u67e5\u8be2\u76f8\u6bd4\u4e8e\u4f20\u7edf\u7684\u8fd0\u8425\u7cfb\u7edf\uff0c\u53ef\u4ee5\u8282\u7ea6\u5f00\u53d1\u5927\u91cf\u9875\u9762\u7684\u6210\u672c\uff0c\u80fd\u591f\u6309\u9700\u83b7\u53d6\u60f3\u8981\u67e5\u8be2\u7684\u5b57\u6bb5\uff0c\u5e76\u4e14\u81ea\u9002\u5e94\u6570\u636e\u7ed3\u6784\u7684\u6f14\u8fdb\u3002\u4e3a\u4e86\u6700\u5927\u5316\u5229\u7528 LLM \u7684\u67e5\u8be2\u7075\u6d3b\u6027\uff0c\u6211\u4eec\u5f15\u5165\u4e86 GraphQL \u4f5c\u4e3a\u6570\u636e\u67e5\u8be2\u7684\u4e2d\u95f4\u5c42<\/p>\n<h3 id=\"\u9053\u7406\u6211\u90fd\u61c2\u4e3a\u4ec0\u4e48\u662f-graphql\">\u9053\u7406\u6211\u90fd\u61c2\uff0c\u4e3a\u4ec0\u4e48\u662f GraphQL\uff1f<\/h3>\n<p>GraphQL \u662f\u4e00\u79cd\u7528\u4e8e\u63d0\u4f9b API \u7684\u67e5\u8be2\u8bed\u8a00\uff0c\u5b83\u5141\u8bb8<strong>\u5ba2\u6237\u7aef\u6307\u5b9a<\/strong>\u6240\u9700\u7684\u6570\u636e\u7ed3\u6784\u548c\u5b57\u6bb5\u3002\u6211\u4eec\u4f7f\u7528 GraphQL \u4f5c\u4e3a\u8fde\u63a5 LLM \u548c\u6240\u6709\u6570\u636e\u6e90\u7684\u6865\u6881\uff1a LLM \u4f7f\u7528 GraphQL \u63cf\u8ff0\u8981\u67e5\u8be2\u7684\u6570\u636e\uff0c\u5728\u4e00\u6b21\u67e5\u8be2\u4e2d\u8bbf\u95ee\u591a\u79cd\u6570\u636e\u6e90<\/p>\n<p>\u56de\u5fc6\u4e00\u4e0b\u672c\u6587\u5f00\u5934\u5217\u51fa\u7684\u591a\u79cd\u6570\u636e\u6e90\uff0c\u6211\u4eec\u53d6\u5176\u4e2d Runtime Data \u4e2d\u7684 RocketMQ Broker \u6570\u636e\u6e90\u4e3a\u4f8b\uff0c\u5b83\u7684\u6570\u636e\u6a21\u578b\u5927\u81f4\u5982\u4e0b\u6240\u793a\uff1a<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">flowchart TD\nsubgraph Cluster\ndirection LR\nBroker_One --&gt;|\u5305\u542b| Topic_A\nBroker_One --&gt;|\u5305\u542b| Topic_B\nBroker_One --&gt;|\u5305\u542b| Group_X\nsubgraph Topic\ndirection LR\nTopic_A --&gt;|\u5305\u542b| Queue_A1\nTopic_A --&gt;|\u5305\u542b| Queue_A2\nTopic_B --&gt;|\u5305\u542b| Queue_B1\nQueue_A1 --&gt;|\u5305\u542b| Message_A1\nQueue_A2 --&gt;|\u5305\u542b| Message_A2\nQueue_B1 --&gt;|\u5305\u542b| Message_B1\nend\nsubgraph Group\ndirection LR\nGroup_X --&gt;|\u5305\u542b| Consumer_A\nGroup_X --&gt;|\u5305\u542b| Consumer_B\nConsumer_A --&gt;|\u6d88\u8d39| Message_A1\nConsumer_B --&gt;|\u6d88\u8d39| Message_B1\nConsumer_B --&gt;|\u6d88\u8d39| Message_A2\nend\nend\n<\/div>\n<p>\u6211\u4eec\u5c06\u8fd9\u4e2a\u6570\u636e\u6a21\u578b\u7ec4\u7ec7\u6210\u4e00\u4e2a\u6811\u72b6\u7684\u7ed3\u6784\uff0cGraphQL \u7684\u67e5\u8be2\u8bed\u6cd5\u975e\u5e38\u9002\u5408\u8fd9\u79cd\u6811\u72b6\u7ed3\u6784\u7684\u67e5\u8be2\uff1a\u53ef\u4ee5\u901a\u8fc7 GraphQL \u7684\u5d4c\u5957\u67e5\u8be2\u6765\u83b7\u53d6 Broker\u3001Topic\u3001Queue \u548c Message \u4e4b\u95f4\u7684\u5173\u7cfb<\/p>\n<p>\u4f8b\u5982\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u7684 GraphQL \u67e5\u8be2\u8bed\u53e5\u6765\u83b7\u53d6 Broker_One \u4e2d Topic_A \u7684\u961f\u5217 0 \u7684\u76f8\u5173\u4fe1\u606f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-graphql\" data-lang=\"graphql\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">query<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2 Broker\u8282\u70b9 Broker_One<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nc\">brokers<\/span><span class=\"p\">(<\/span><span class=\"py\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&#34;Broker_One&#34;<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2\u8be5 Broker \u8282\u70b9\u7684\u63a5\u5165\u70b9<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nc\">addr<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2 Broker \u8282\u70b9\u7684\u914d\u7f6e\u9879 messageIndexEnable<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">config<\/span><span class=\"p\">(<\/span><span class=\"py\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&#34;messageIndexEnable&#34;<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nc\">name<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">value<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2\u8be5 Broker \u8282\u70b9\u7684 Topic \u4fe1\u606f\uff1aTopic_A<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">topics<\/span><span class=\"p\">(<\/span><span class=\"py\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s\">&#34;Topic_A&#34;<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2\u8be5 Topic \u7684\u961f\u5217 0<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nc\">queues<\/span><span class=\"p\">(<\/span><span class=\"py\">id<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"nc\">0<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2\u8be5\u961f\u5217\u7684\u6d88\u606f\u6570\uff08maxOffset - minOffset\uff09<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">minOffset<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">maxOffset<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u67e5\u8be2\u8be5\u961f\u5217\u7684\u7b2c 100 \u6761\u6d88\u606f<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">messages<\/span><span class=\"p\">(<\/span><span class=\"py\">offset<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"nc\">100<\/span><span class=\"p\">)<\/span><span class=\"w\"> <\/span><span class=\"p\">{<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">id<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"py\">payload<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"p\">}<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u4e2a\u67e5\u8be2\u4f1a\u88ab\u7ffb\u8bd1\u6210\u5bf9 RocketMQ Broker \u6570\u636e\u6e90\u4ee5\u4e0b\u63a5\u53e3\u7684\u8c03\u7528\uff1a<\/p>\n<ol>\n<li>Broker \u4fe1\u606f\uff08\u63a5\u5165\u70b9\uff09<\/li>\n<li>Broker \u914d\u7f6e\u9879\uff08messageIndexEnable\uff09<\/li>\n<li>Topic \u4fe1\u606f\uff08\u961f\u5217\u6570\uff09<\/li>\n<li>Topic \u961f\u5217\u7684\u4fe1\u606f\uff08minOffset\u3001maxOffset\uff09<\/li>\n<li>Topic \u7684\u6d88\u606f\uff08\u8be5\u961f\u5217\u7b2c 100 \u6761\u6d88\u606f\uff09<\/li>\n<\/ol>\n<p>\u4e5f\u5c31\u662f\u8bf4\uff0c\u6211\u4eec\u901a\u8fc7 GraphQL \u7684\u5d4c\u5957\u67e5\u8be2\u8bed\u6cd5\u5c06 5 \u4e2a\u67e5\u8be2\u7ec4\u5408\u5728\u4e00\u8d77\u3002\u4e0a\u9762\u53ea\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u5b9e\u9645\u4e0a\u53ef\u4ee5\u7ec4\u5408\u9762\u5411\u4e0d\u540c\u6570\u636e\u6e90\u7684\u67e5\u8be2\u3002\u4e0d\u7ba1\u4ed6\u4eec\u63d0\u4f9b\u7684\u662f REST API \u8fd8\u662f Binary Protocol \u90fd\u53ef\u4ee5\u5408\u5e76\u5230\u4e00\u4e2a GraphQL \u67e5\u8be2\u4e2d\u3002\u5bf9\u4e8e LLM \u6765\u8bf4\u8fd9\u6837\u505a\u5c24\u5176\u6709\u610f\u4e49\uff1a<\/p>\n<ul>\n<li><strong>\u7b80\u5316\u5f00\u53d1<\/strong>\uff1a\u4e0d\u9700\u8981\u4e3a\u6bcf\u79cd\u6570\u636e\u6e90\u7f16\u5199\u5355\u72ec\u7684 MCP Server\uff0c\u7edf\u4e00\u4f7f\u7528 GraphQL \u4f5c\u4e3a\u6570\u636e\u67e5\u8be2\u7684\u4e2d\u95f4\u5c42\uff0c\u7528 GraphQL \u7684 schema \u6765\u5e2e\u52a9 LLM \u7406\u89e3\u6570\u636e\u7ed3\u6784<\/li>\n<li><strong>\u7b80\u5316\u67e5\u8be2<\/strong>\uff1aLLM \u53ea\u9700\u8981\u7406\u89e3 GraphQL \u7684\u67e5\u8be2\u8bed\u6cd5\uff0c\u800c\u4e0d\u9700\u8981\u4e86\u89e3\u6bcf\u4e2a\u6570\u636e\u6e90\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u3002\u5bf9\u4e8e\u590d\u6742\u7684\u67e5\u8be2\u53ef\u4ee5\u6709\u6548\u964d\u4f4e LLM \u7684\u7406\u89e3\u96be\u5ea6\uff0c\u51cf\u5c11\u51fa\u9519\u7684\u6982\u7387<\/li>\n<li><strong>\u51cf\u5c11\u67e5\u8be2\u6b21\u6570<\/strong>\uff1a\u901a\u8fc7\u4e00\u6b21 GraphQL \u67e5\u8be2\uff0c\u53ef\u4ee5\u83b7\u53d6\u591a\u4e2a\u6570\u636e\u6e90\u7684\u4fe1\u606f\uff0c\u51cf\u5c11\u4e86\u591a\u6b21 LLM \u8c03\u7528\u7684 Token \u5f00\u9500<\/li>\n<li><strong>\u964d\u4f4e\u4e0a\u4e0b\u6587\u5f00\u9500<\/strong>\uff1a\u4e0d\u9700\u8981\u7ec4\u7ec7\u591a\u6b21\u67e5\u8be2\uff0c\u4e5f\u4e0d\u9700\u8981\u8f93\u5165\u591a\u79cd MCP tools \u7684\u53c2\u6570\u548c\u7528\u6cd5\u3002\u53ef\u4ee5\u5c06 LLM \u6709\u9650\u7684\u4e0a\u4e0b\u6587\u7528\u4e8e\u63cf\u8ff0\u95ee\u9898\u7684\u672c\u8d28<\/li>\n<li><strong>\u7075\u6d3b\u53d8\u66f4\u6570\u636e\u7ed3\u6784<\/strong>\uff1aGraphQL \u81ea\u5e26 schema\uff0c\u5bf9\u4e8e LLM \u6765\u8bf4\u53ef\u4ee5\u901a\u8fc7 schema \u6765\u83b7\u53d6\u6570\u636e\u7684\u5b57\u6bb5\u548c\u4e0d\u540c\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u7684\u5173\u7cfb\u3002\u7b80\u800c\u8a00\u4e4b\u6211\u4eec\u63d0\u4f9b\u7684\u67e5\u8be2\u63a5\u53e3\u662f\u81ea\u63cf\u8ff0\u7684\uff0c\u53ef\u4ee5\u968f\u65f6\u589e\u52a0\u65b0\u7684\u6570\u636e\u7ed3\u6784\uff0cLLM \u4e5f\u80fd\u81ea\u52a8\u9002\u5e94<\/li>\n<\/ul>\n<h2 id=\"\u603b\u7ed3\u4e0e\u540e\u7eed\u5c55\u671b\">\u603b\u7ed3\u4e0e\u540e\u7eed\u5c55\u671b<\/h2>\n<p>\u901a\u8fc7 LLM + Chatbox + MCP + GraphQL \u7684\u7ec4\u5408\uff0c\u6211\u4eec\u5b9e\u73b0\u4e86\u5bf9\u591a\u4e2a\u5f02\u6784\u6570\u636e\u6e90\u7684\u9ad8\u6548\u67e5\u8be2\u3002\u7528\u6237\u4e0d\u9700\u8981\u5177\u5907\u5927\u91cf\u7684\u6392\u67e5\u7ecf\u9a8c\u548c\u5bf9\u7cfb\u7edf\u7684\u6df1\u5165\u7406\u89e3\uff0c\u53ea\u9700\u8981\u7528\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u6240\u9700\u7684\u4fe1\u606f\uff0c\u7cfb\u7edf\u5c31\u80fd\u81ea\u52a8\u751f\u6210\u67e5\u8be2\u8bed\u53e5\u5e76\u8fd4\u56de\u7ed3\u679c\u3002\u8fd9\u79cd\u65b9\u5f0f\u4e0d\u4ec5\u63d0\u9ad8\u4e86\u6392\u67e5\u95ee\u9898\u6548\u7387\uff0c\u8fd8\u964d\u4f4e\u4e86\u5bf9\u8fd0\u7ef4\u4eba\u5458\u7684\u6280\u672f\u8981\u6c42<\/p>\n<p>\u76ee\u524d\u6211\u4eec\u5b9e\u73b0\u4e86 LLM \u9ad8\u6548\u8bbf\u95ee\u6570\u636e\uff0c\u5e76\u4e14\u901a\u8fc7 GraphQL \u7684 schema \u80fd\u591f\u7406\u89e3\u591a\u79cd\u6570\u636e\u7ed3\u6784\u4e4b\u95f4\u7684\u5173\u8054\u3002\u4e0b\u4e00\u6b65\u6211\u4eec\u5c06\u7ee7\u7eed\u8fed\u4ee3\u8fd9\u4e2a\u7cfb\u7edf\uff0c\u5c06\u6211\u4eec\u95ee\u9898\u6392\u67e5\u7684\u4e13\u5bb6\u7ecf\u9a8c\u4ee5\u77e5\u8bc6\u5e93\u7684\u5f62\u5f0f\u8f93\u5165\u5230 LLM \u4e2d\uff0c\u5e2e\u52a9 LLM \u4e0d\u4ec5\u80fd\u7406\u89e3\u6570\u636e\uff0c\u66f4\u80fd\u7406\u89e3\u95ee\u9898\u7684\u672c\u8d28\u3002\u6700\u7ec8\u5b9e\u73b0\u4e00\u4e2a\u4e00\u7ad9\u5f0f\u95ee\u9898\u6392\u67e5\u7cfb\u7edf\uff0c\u8ba9 LLM \u80fd\u591f\u81ea\u52a8\u5316\u5730\u5b8c\u6210\u95ee\u9898\u6392\u67e5\u7684\u5de5\u4f5c<\/p>"},{"title":"Java \u5e94\u7528\u5185\u5b58\u5360\u7528\u5f02\u5e38\u6392\u67e5\u601d\u8def","link":"https:\/\/blog.lv5.moe\/p\/java-application-memory-allocation-troubleshooting","pubDate":"Thu, 23 Nov 2023 16:00:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/java-application-memory-allocation-troubleshooting","description":"<img src=\"https:\/\/blog.lv5.moe\/img\/67003464_p0.jpg\" alt=\"Featured image of post Java \u5e94\u7528\u5185\u5b58\u5360\u7528\u5f02\u5e38\u6392\u67e5\u601d\u8def\" \/><p>\u672c\u6587\u7528\u4e00\u4e2a\u7ebf\u4e0a\u95ee\u9898\u7684\u6392\u67e5\u8fc7\u7a0b\u6765\u4ecb\u7ecd Java \u5e94\u7528\u7684\u5185\u5b58\u7ba1\u7406\uff0c\u4ee5\u53ca Linux \u5185\u5b58\u5206\u6790\u5de5\u5177\u7684\u4f7f\u7528\uff0c\u4f9b\u8bfb\u8005\u6392\u67e5 Java \u5e94\u7528\u7684\u5185\u5b58\u6cc4\u9732\u548c OOM \u95ee\u9898\u65f6\u53c2\u8003<\/p>\n<h2 id=\"\u524d\u60c5\u63d0\u8981\">\u524d\u60c5\u63d0\u8981<\/h2>\n<p>\u535a\u4e3b\u81ea\u4fe1\u6ee1\u6ee1\u538b\u6d4b\u4e00\u665a\uff0c\u7ed3\u679c\u9694\u5929\u65e9\u4e0a\u67e5\u770b\u76d1\u63a7\u53d1\u73b0 Java \u8fdb\u7a0b\u5360\u7528\u5185\u5b58\u8fdc\u8d85\u9884\u671f\uff0c\u4e8e\u662f\u4fbf\u5f00\u59cb\u4e86\u672c\u6587\u8270\u8f9b\u7684\u6392\u67e5\u4e4b\u65c5<\/p>\n<p>\u8fd9\u4e2a\u573a\u666f\u7684\u6280\u672f\u6808\u662f Java 17 + ZGC\uff0c\u4f46\u662f\u672c\u6587\u4ecb\u7ecd\u7684\u65b9\u6cd5\u4e5f\u9002\u7528\u4e8e\u6392\u67e5\u5176\u4ed6\u7248\u672c Java \u5e94\u7528\u7684\u5185\u5b58\u6cc4\u9732\u548c OOM \u95ee\u9898<\/p>\n<p>\u6211\u4eec\u77e5\u9053 Java \u5e94\u7528\u7684\u5185\u5b58\u53ef\u4ee5\u5206\u4e3a\u4e09\u79cd\uff1a<\/p>\n<ol>\n<li>\u5806\u5185\u5b58\uff1aJava \u5bf9\u8c61\u5206\u914d\u7684\u7a7a\u95f4<\/li>\n<li>\u5806\u5916\u5185\u5b58\uff1a\u65b9\u6cd5\u533a\u3001\u7ebf\u7a0b\u6808\u3001Direct Buffer \u7b49<\/li>\n<li>\u975e JVM \u5185\u5b58\uff1anative library \u5206\u914d\u7684\u5185\u5b58<\/li>\n<\/ol>\n<p>\u535a\u4e3b\u7684\u5e94\u7528\u4f7f\u7528\u4e86 NIO ByteBuffer + Netty + RocksDB \u53ef\u8c13\u662f\u4e94\u6bd2\u4ff1\u5168\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u5148\u786e\u8ba4\u5185\u5b58\u6cc4\u9732\u53d1\u751f\u5728\u54ea\u4e2a\u5185\u5b58\u533a\u57df<\/p>\n<h2 id=\"\u5206\u6790\u5806\u5185\u5b58\u6ea2\u51fa\">\u5206\u6790\u5806\u5185\u5b58\u6ea2\u51fa<\/h2>\n<p>\u5806\u5185\u5b58\u6cc4\u9732\u95ee\u9898\u6700\u5bb9\u6613\u5206\u6790\uff1a\u8bbe\u7f6e VM \u53c2\u6570 <code>-XX:+HeapDumpOnOutOfMemoryError<\/code> \u5728\u5e94\u7528\u5d29\u6e83\u65f6 dump \u5806\u5185\u5b58\uff0c\u6216\u8005\u4f7f\u7528 <code>jmap -dump:format=b,file=heap.bin &lt;pid&gt;<\/code> \u624b\u52a8 dump \u5806\u5185\u5b58\u3002\u7136\u540e\u901a\u8fc7 MAT\/JProfiler \u7b49\u5de5\u5177\u5bf9\u5927\u5bf9\u8c61\u8fdb\u884c\u5f15\u7528\u5206\u6790\u5373\u53ef\u5f97\u77e5\u5185\u5b58\u6cc4\u9732\u7684\u539f\u56e0<\/p>\n<p>\u4e0d\u5e78\u7684\u662f\u535a\u4e3b\u7684\u5e94\u7528\u6ca1\u6709\u751f\u6210\u5806\u8f6c\u50a8\u6587\u4ef6\uff0c\u901a\u8fc7 JVM \u76d1\u63a7\u4e5f\u53ef\u4ee5\u5f97\u77e5\u5728\u8fd0\u884c\u671f\u95f4\uff0c\u5806\u5185\u5b58\u4f7f\u7528\u7387\u51e0\u4e4e\u6ca1\u6709\u589e\u957f\uff0c\u90a3\u4e48\u6cc4\u6f0f\u5fc5\u7136\u662f\u5728\u5806\u5916\u53d1\u751f<\/p>\n<h2 id=\"\u5206\u6790\u5806\u5916\u5185\u5b58\u6ea2\u51fa\">\u5206\u6790\u5806\u5916\u5185\u5b58\u6ea2\u51fa<\/h2>\n<p>\u65b9\u6cd5\u533a\u3001\u7ebf\u7a0b\u6808\u5bfc\u81f4\u7684\u5806\u5916\u5185\u5b58\u6ea2\u51fa\u4f1a\u5bfc\u81f4 JVM \u5d29\u6e83\u5e76\u5728\u8fd0\u884c\u76ee\u5f55\u4e0b\u4ea7\u751f <code>hs_err_pid&lt;pid&gt;.log<\/code> \u6587\u4ef6\uff0c\u67e5\u770b\u62a5\u9519\u7684\u7ebf\u7a0b\u6808\u53ef\u4ee5\u5206\u6790\u51fa VM \u53c2\u6570\u8bbe\u7f6e\u4e0d\u5408\u7406\u6216\u5f00\u542f\u7ebf\u7a0b\u8fc7\u591a\u7b49\u539f\u56e0<\/p>\n<p>\u53e6\u5916\u4e00\u79cd\u5806\u5916\u5185\u5b58\u662f DirectByteBuffer \/ FileChannel.map \u7b49\u5206\u914d\u7684\u5185\u5b58\uff0c\u8fd9\u90e8\u5206\u5185\u5b58\u53ef\u4ee5\u4f7f\u7528 <code>-XX:MaxDirectMemorySize=size<\/code> \u9650\u5236\uff0c\u4f46\u662f\u8fd9\u4e2a\u9009\u9879\u53ea\u4f1a\u5f71\u54cd\u5230 java.nio \u5305\u4e0b\u7684\u5185\u5b58\u5206\u914d\uff0c\u8be6\u89c1 JDK \u7684\u6587\u6863\uff1a<\/p>\n<blockquote>\n<p>-XX:MaxDirectMemorySize=size<\/p>\n<p>Sets the maximum total size (in bytes) of the java.nio package, direct-buffer allocations. Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, or g or G to indicate gigabytes. By default, the size is set to 0, meaning that the JVM chooses the size for NIO direct-buffer allocations automatically.<\/p>\n<\/blockquote>\n<p>\u535a\u4e3b\u5e94\u7528\u7684\u7f13\u5b58\u6c60\u4f7f\u7528\u4e86 Netty \u63d0\u4f9b\u7684 ByteBuf\uff0c\u5e95\u5c42\u6b63\u662f\u4f7f\u7528 java.nio.DirectByteBuffer<\/p>\n<p>\u5806\u5916\u5185\u5b58\u4e5f\u53d7 JVM \u7ba1\u63a7\uff0c\u53ef\u4ee5\u4f7f\u7528 JVM \u63d0\u4f9b\u7684 Native Memory Tracking \u6765\u5206\u6790\u3002\u6dfb\u52a0 VM \u53c2\u6570 <code>-XX:NativeMemoryTracking=[off | summary | detail]<\/code> \u6765\u5f00\u542f NMT\uff0c\u91cd\u542f JVM \u540e\u5373\u53ef\u4f7f\u7528 <code>jcmd<\/code> \u5de5\u5177\u6765\u67e5\u770b NMT \u6570\u636e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">jcmd &lt;pid&gt; VM.native_memory <span class=\"o\">[<\/span>summary <span class=\"p\">|<\/span> detail <span class=\"p\">|<\/span> baseline <span class=\"p\">|<\/span> summary.diff <span class=\"p\">|<\/span> detail.diff <span class=\"p\">|<\/span> shutdown<span class=\"o\">]<\/span> <span class=\"o\">[<\/span><span class=\"nv\">scale<\/span><span class=\"o\">=<\/span> KB <span class=\"p\">|<\/span> MB <span class=\"p\">|<\/span> GB<span class=\"o\">]<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>NMT \u4f1a\u8f93\u51fa\u7c7b\u4f3c\u4e0b\u9762\u7684\u62a5\u544a\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">jcmd <span class=\"m\">1713702<\/span> VM.native_memory summary <span class=\"nv\">scale<\/span><span class=\"o\">=<\/span>MB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">1713702:\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Native Memory Tracking:\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">(<\/span>Omitting categories weighting less than 1MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Total: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>207768MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>6213MB\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> malloc: 1823MB <span class=\"c1\">#670978<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>205945MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>4390MB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Java Heap <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>196608MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>4096MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>196608MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>4096MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Class <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>260MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>14MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>classes <span class=\"c1\">#17028)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> instance classes <span class=\"c1\">#16123, array classes #905)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>4MB <span class=\"c1\">#74947) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>256MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>11MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> Metadata: <span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>128MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>82MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">used<\/span><span class=\"o\">=<\/span>82MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">waste<\/span><span class=\"o\">=<\/span><span class=\"nv\">0MB<\/span> <span class=\"o\">=<\/span>0.43%<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> Class space:<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>256MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>11MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">used<\/span><span class=\"o\">=<\/span>10MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span> <span class=\"nv\">waste<\/span><span class=\"o\">=<\/span><span class=\"nv\">0MB<\/span> <span class=\"o\">=<\/span>4.21%<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Thread <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>472MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>50MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>thread <span class=\"c1\">#472)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>stack: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>471MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>49MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>1MB <span class=\"c1\">#2839) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">arena<\/span><span class=\"o\">=<\/span>1MB <span class=\"c1\">#941)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Code <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>248MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>83MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>6MB <span class=\"c1\">#23199) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>242MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>77MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- GC <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>8336MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>176MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>112MB <span class=\"c1\">#48322) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>8224MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>64MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Compiler <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>4MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>4MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>4MB <span class=\"c1\">#2150) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Internal <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>6MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>6MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>6MB <span class=\"c1\">#57737) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Other <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>1658MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>1658MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>1658MB <span class=\"c1\">#613) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Symbol <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>18MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>18MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>16MB <span class=\"c1\">#432773) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">arena<\/span><span class=\"o\">=<\/span>2MB <span class=\"c1\">#1)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Native Memory Tracking <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>11MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>11MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>1MB <span class=\"c1\">#7935) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>tracking <span class=\"nv\">overhead<\/span><span class=\"o\">=<\/span>10MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Shared class space <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>16MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>12MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>16MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>12MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Serviceability <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>1MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>1MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span><span class=\"nv\">malloc<\/span><span class=\"o\">=<\/span>1MB <span class=\"c1\">#14544) <\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">- Metaspace <span class=\"o\">(<\/span><span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>128MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>83MB<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">(<\/span>mmap: <span class=\"nv\">reserved<\/span><span class=\"o\">=<\/span>128MB, <span class=\"nv\">committed<\/span><span class=\"o\">=<\/span>82MB<span class=\"o\">)<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>Java 11 \u4e4b\u540e DirectByteBuffer \u4f7f\u7528\u7684\u5185\u5b58\u88ab\u5f52\u5165 Other \u4e2d\uff08\u4e4b\u524d\u662f Internal\uff09\uff0c\u6211\u4eec\u9700\u8981\u5173\u6ce8\u7684\u662f\u5176\u4e2d\u7684 committed \u90e8\u5206\uff0c\u4ee3\u8868\u4e86\u771f\u5b9e\u4f7f\u7528\u7684\u7269\u7406\u5185\u5b58\u3002\u8fd9\u91cc\u53ef\u4ee5\u53d1\u73b0 DirectByteBuffer \u53ea\u5360\u7528\u4e86 1658MB \u5185\u5b58\uff0c\u5e76\u4e0d\u662f\u53d1\u751f\u5185\u5b58\u6cc4\u9732\u7684\u539f\u56e0<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u6839\u636e JDK \u548c\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c\u7684\u4e0d\u540c\uff0ccommitted \u7684\u6570\u503c\u53ef\u80fd\u4f1a\u5927\u4e8e\u7b49\u4e8e\u64cd\u4f5c\u7cfb\u7edf\u8ba1\u7b97\u7684 RSS\u3002\u5177\u4f53\u539f\u56e0\u548c\u4fee\u590d\u65b9\u6848\u53ef\u4ee5\u53c2\u8003 <a class=\"link\" href=\"https:\/\/bugs.openjdk.org\/browse\/JDK-8191369\" target=\"_blank\" rel=\"noopener\"\n>JDK-8191369<\/a> \u548c <a class=\"link\" href=\"https:\/\/bugs.openjdk.org\/browse\/JDK-8249666\" target=\"_blank\" rel=\"noopener\"\n>JDK-8249666<\/a>\n<\/div>\n<p><\/p>\n<h2 id=\"\u5206\u6790\u975e-jvm-\u5185\u5b58\u6ea2\u51fa\">\u5206\u6790\u975e JVM \u5185\u5b58\u6ea2\u51fa<\/h2>\n<p>\u901a\u8fc7\u4e0a\u8ff0\u6392\u67e5\u6d41\u7a0b\uff0c\u6211\u4eec\u5df2\u7ecf\u786e\u8ba4\u4e86\u6cc4\u9732\u7684\u5185\u5b58\u5e76\u4e0d\u53d7 JVM \u7684\u7ba1\u63a7\uff0c\u8fd9\u5c31\u9700\u8981\u6df1\u5165\u5230\u5bf9\u64cd\u4f5c\u7cfb\u7edf\u5185\u5b58\u5206\u914d\u60c5\u51b5\u7684\u5206\u6790<\/p>\n<h3 id=\"\u6362\u7528-jemalloc\">\u6362\u7528 jemalloc<\/h3>\n<p>Java \u9ed8\u8ba4\u4f7f\u7528 glibc \u7684 malloc\uff0c\u6709\u65f6\u4f1a\u51fa\u73b0\u788e\u7247\u95ee\u9898\uff0c\u53ef\u4ee5\u4f7f\u7528 jemalloc \u66ff\u4ee3\u5e76\u5f00\u542f\u5206\u6790\u529f\u80fd\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">apt install libjemalloc-dev\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">export<\/span> <span class=\"nv\">LD_PRELOAD<\/span><span class=\"o\">=<\/span>\/usr\/lib\/x86_64-linux-gnu\/libjemalloc.so.2\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u6bcf\u5206\u914d 128K \u5185\u5b58\u8bb0\u5f55\u5806\u6808\u4fe1\u606f\uff0c\u6bcf\u5206\u914d 1GB \u5185\u5b58\u8f93\u51fa\u5230\u6587\u4ef6<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">export<\/span> <span class=\"nv\">MALLOC_CONF<\/span><span class=\"o\">=<\/span>prof:true,lg_prof_interval:30,lg_prof_sample:17\n<\/span><\/span><\/code><\/pre><\/div><p>\u91cd\u542f\u5e94\u7528\u540e\u5728\u8fd0\u884c\u76ee\u5f55\u4e0b\u4f1a\u751f\u6210\u7c7b\u4f3c <code>jeprof.&lt;pid&gt;.0.i0.heap<\/code> \u7684\u6587\u4ef6\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 <code>jeprof<\/code> \u6765\u8f93\u51fa\u5185\u5b58\u5206\u914d\u60c5\u51b5<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">jeprof --svg <span class=\"sb\">`<\/span>which java<span class=\"sb\">`<\/span> jeprof*.heap &gt; jeprof.svg\n<\/span><\/span><\/code><\/pre><\/div><figure><img src=\"https:\/\/blog.lv5.moe\/p\/java-application-memory-allocation-troubleshooting\/jemalloc-prof.webp\" width=\"669px\" height=\"645px\"\/><figcaption>\n<h4>Jemalloc Prof<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u8fd9\u91cc\u770b\u5230\u5206\u914d\u5185\u5b58\u5360\u6bd4 89% \u7684\u51fd\u6570\u662f <code>Unsafe_AllocateMemory0<\/code>\u3002\u4f46\u662f jemalloc \u4e0d\u80fd\u8fdb\u4e00\u6b65\u5206\u6790 java \u865a\u62df\u673a\u7684\u5806\u6808\uff0c\u6211\u4eec\u9700\u8981\u8fdb\u4e00\u6b65\u914d\u5408 <a class=\"link\" href=\"https:\/\/github.com\/async-profiler\/async-profiler\" target=\"_blank\" rel=\"noopener\"\n>async-profler<\/a> \u751f\u6210\u706b\u7130\u56fe\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u53ef\u4ee5\u5c06 Unsafe_AllocateMemory0 \u6362\u6210\u5176\u4ed6\u4efb\u4f55\u60f3\u89c2\u6d4b\u7684\u51fd\u6570\u540d<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">.\/profiler.sh -d &lt;duration&gt; -e Unsafe_AllocateMemory0 -f unsafe_allocate.html &lt;pid&gt;\n<\/span><\/span><\/code><\/pre><\/div><p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 173;\nflex-basis: 417px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/java-application-memory-allocation-troubleshooting\/async-profiler.webp\" data-size=\"720x414\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/java-application-memory-allocation-troubleshooting\/async-profiler.webp\"\nwidth=\"720\"\nheight=\"414\"\nloading=\"lazy\"\nalt=\"Flame Graph\">\n<\/a>\n<figcaption>Flame Graph<\/figcaption>\n<\/figure><\/p>\n<p>\u751f\u6210\u7684\u706b\u7130\u56fe\u4e2d\u53ef\u4ee5\u770b\u5230 Unsafe_AllocateMemory0 \u5206\u914d\u7684\u5185\u5b58\u5b9e\u9645\u4e0a\u662f DirectByteBuffer \u4f7f\u7528\u7684\uff0c\u8fd9\u548c NMT \u7684\u62a5\u544a\u4e2d\u663e\u793a\u7684\u5360\u7528\u91cf\u57fa\u672c\u4e00\u81f4\uff0c\u5e76\u4e0d\u662f\u5bfc\u81f4\u5185\u5b58\u5360\u7528\u5f02\u5e38\u7684\u5143\u51f6<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-text\" data-lang=\"text\"><span class=\"line\"><span class=\"cl\">Other (reserved=1658MB, committed=1658MB)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> (malloc=1658MB #613)\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5206\u6790\u5185\u5b58\u5206\u5e03\">\u5206\u6790\u5185\u5b58\u5206\u5e03<\/h3>\n<p>\u65e2\u7136\u5e94\u7528\u8fd0\u884c\u4e2d\u6ca1\u6709\u660e\u663e\u7684\u5185\u5b58\u6cc4\u9732\uff0c\u90a3\u4e48\u5c31\u9700\u8981\u770b\u4e0b\u6d88\u8017\u7684\u5185\u5b58\u7528\u5728\u4e86\u54ea\u91cc\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">cat \/proc\/2031108\/status\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Name: java\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssAnon: <span class=\"m\">805844<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssFile: <span class=\"m\">38036<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssShmem: <span class=\"m\">12582912<\/span> kB\n<\/span><\/span><\/code><\/pre><\/div><p>\u5360\u7528\u5185\u5b58\u6700\u591a\u7684 RssShmem \u6709 12G\uff0c\u8fd9\u662f\u4e2a\u5f88\u4e0d\u540c\u5bfb\u5e38\u7684\u60c5\u51b5\uff0c\u4e00\u822c\u6765\u8bf4 page cache \u4ee5\u53ca mmap \u8fdb\u884c\u6587\u4ef6\u6620\u5c04\u90fd\u4f1a\u7b97\u5230 RssFile \u4e0a\u3002\u63a5\u4e0b\u6765\u9700\u8981\u8fdb\u4e00\u6b65\u627e\u5230\u8fd9 12G \u7684\u5185\u5b58\u7528\u5728\u4e86\u54ea\u91cc\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 <code>pmap<\/code> \u6765\u67e5\u770b\u5185\u5b58\u5206\u5e03\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">pmap -x <span class=\"m\">2031108<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Address Kbytes RSS Dirty Mode Mapping\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000040000000000<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> rw-s- memfd:java_heap <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000040100000000<\/span> <span class=\"m\">62914560<\/span> <span class=\"m\">0<\/span> <span class=\"m\">0<\/span> ----- <span class=\"o\">[<\/span> anon <span class=\"o\">]<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000080000000000<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> rw-s- memfd:java_heap <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000080100000000<\/span> <span class=\"m\">62914560<\/span> <span class=\"m\">0<\/span> <span class=\"m\">0<\/span> ----- <span class=\"o\">[<\/span> anon <span class=\"o\">]<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000100000000000<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> <span class=\"m\">4194304<\/span> rw-s- memfd:java_heap <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000100100000000<\/span> <span class=\"m\">62914560<\/span> <span class=\"m\">0<\/span> <span class=\"m\">0<\/span> ----- <span class=\"o\">[<\/span> anon <span class=\"o\">]<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5f88\u5bb9\u6613\u53d1\u73b0\u7591\u4f3c\u7684\u5185\u5b58\u533a\u57df\uff0cjava \u5806\u88ab\u6620\u5c04\u5230\u4e86\u4e09\u4e2a\u865a\u62df\u5185\u5b58\u5730\u5740\u4e0a\uff1a40000000000\u300180000000000\u3001100000000000\u3002\u535a\u4e3b\u5e94\u7528\u7684\u5806\u5927\u5c0f\u8bbe\u7f6e\u4e3a 4G\uff0c\u7406\u8bba\u4e0a\u6620\u5c04\u4e86\u4e09\u6b21\u5c31\u4ea7\u751f\u4e86 12G \u7684 RssShmem \u5360\u7528\u3002\u4e3a\u4e86\u9a8c\u8bc1\u8fd9\u4e2a\u731c\u60f3\u63a5\u4e0b\u6765 dump \u8fd9\u4e09\u6bb5\u5185\u5b58\u6bd4\u8f83\u5176\u4e2d\u7684\u5185\u5bb9\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">dd <span class=\"k\">if<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/proc\/2031108\/mem&#34;<\/span> <span class=\"nv\">of<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/dev\/stdout&#34;<\/span> <span class=\"nv\">bs<\/span><span class=\"o\">=<\/span><span class=\"m\">1<\/span> <span class=\"nv\">skip<\/span><span class=\"o\">=<\/span><span class=\"k\">$((<\/span><span class=\"m\">0<\/span>x40000000000<span class=\"k\">))<\/span> <span class=\"nv\">count<\/span><span class=\"o\">=<\/span><span class=\"m\">128<\/span> <span class=\"p\">|<\/span> hexdump\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records in\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records out\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">128<\/span> bytes copied, 0.000292939 s, <span class=\"m\">437<\/span> kB\/s\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0003<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000010<\/span> e938 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span> e970 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000020<\/span> e9c0 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000030<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0007<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000040<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">*\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000070<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0020<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000080<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">dd <span class=\"k\">if<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/proc\/2031108\/mem&#34;<\/span> <span class=\"nv\">of<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/dev\/stdout&#34;<\/span> <span class=\"nv\">bs<\/span><span class=\"o\">=<\/span><span class=\"m\">1<\/span> <span class=\"nv\">skip<\/span><span class=\"o\">=<\/span><span class=\"k\">$((<\/span><span class=\"m\">0<\/span>x80000000000<span class=\"k\">))<\/span> <span class=\"nv\">count<\/span><span class=\"o\">=<\/span><span class=\"m\">128<\/span> <span class=\"p\">|<\/span> hexdump\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records in\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records out\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">128<\/span> bytes copied, 0.000298448 s, <span class=\"m\">429<\/span> kB\/s\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0003<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000010<\/span> e938 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span> e970 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000020<\/span> e9c0 <span class=\"m\">0005<\/span> <span class=\"m\">0400<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000030<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0007<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000040<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">*\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000070<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0020<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000080<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">dd <span class=\"k\">if<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/proc\/2031108\/mem&#34;<\/span> <span class=\"nv\">of<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/dev\/stdout&#34;<\/span> <span class=\"nv\">bs<\/span><span class=\"o\">=<\/span><span class=\"m\">1<\/span> <span class=\"nv\">skip<\/span><span class=\"o\">=<\/span><span class=\"k\">$((<\/span><span class=\"m\">0<\/span>x100000000000<span class=\"k\">))<\/span> <span class=\"nv\">count<\/span><span class=\"o\">=<\/span><span class=\"m\">128<\/span> <span class=\"p\">|<\/span> hexdump\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records in\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records out\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">128<\/span> bytes copied, 0.000330489 s, <span class=\"m\">387<\/span> kB\/s\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0003<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000010<\/span> e938 <span class=\"m\">0005<\/span> <span class=\"m\">0800<\/span> <span class=\"m\">0000<\/span> e970 <span class=\"m\">0005<\/span> <span class=\"m\">0800<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000020<\/span> e9c0 <span class=\"m\">0005<\/span> <span class=\"m\">0800<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000030<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0007<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000040<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">*\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000070<\/span> <span class=\"m\">0001<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">1550<\/span> <span class=\"m\">0000<\/span> <span class=\"m\">0020<\/span> <span class=\"m\">0000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">0000080<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0\u8fd9\u4e9b\u5185\u5bb9\u662f\u5b8c\u5168\u4e00\u81f4\u7684\uff0c\u90a3\u4e48\u5c31\u627e\u5230\u4e86\u7f6a\u9b41\u7978\u9996\uff1a\u6b63\u662f\u8fd9\u4e09\u4e2a\u5806\u5185\u5b58\u6620\u5c04\u9020\u6210\u4e86\u5185\u5b58\u5360\u7528\u98d9\u9ad8\u7684\u95ee\u9898<\/p>\n<h2 id=\"\u77e5\u5176\u6240\u4ee5\u7136\">\u77e5\u5176\u6240\u4ee5\u7136<\/h2>\n<p>\u6211\u4eec\u53d1\u73b0\u4e86\u5143\u51f6\u9996\u6076\uff0c\u4f46\u662f\u8fd8\u9700\u8981\u8fdb\u4e00\u6b65\u5206\u6790\u4e3a\u4ec0\u4e48\u6620\u5c04\u7684\u5185\u5b58\u4f1a\u88ab\u7b97\u4e3a RssShmem \u4ee5\u53ca\u4e3a\u4ec0\u4e48\u4f1a\u51fa\u73b0\u4e09\u6b21\u6620\u5185\u5b58\u6620\u5c04<\/p>\n<h3 id=\"\u533f\u540d\u6587\u4ef6\u6620\u5c04\">\u533f\u540d\u6587\u4ef6\u6620\u5c04<\/h3>\n<p>\u9996\u5148\u6765\u770b\u4e00\u4e0b\u6620\u5c04\u7684\u6587\u4ef6 <code>memfd:java_heap (deleted)<\/code>\uff0c\u5176\u4e2d <code>memfd<\/code> \u662f Linux \u7684\u4e00\u4e2a\u7279\u6027\uff0c\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u533f\u540d\u6587\u4ef6\u9a7b\u7559\u5728\u5185\u5b58\u4e2d\u3002\u8fd9\u4e2a\u6587\u4ef6\u4e0d\u4f1a\u51fa\u73b0\u5728\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u53ea\u80fd\u901a\u8fc7 <code>\/proc\/&lt;pid&gt;\/fd<\/code> \u67e5\u770b\uff0c\u6620\u5c04\u7684\u5185\u5bb9\u4f1a\u5728\u8fdb\u7a0b\u9000\u51fa\u65f6\u88ab\u91ca\u653e<\/p>\n<p>\u8fd9\u4e2a\u6587\u4ef6\u7684 fd \u548c\u666e\u901a\u7684 fd \u5e76\u65e0\u4e8c\u81f4\uff0c\u81ea\u7136\u4e5f\u80fd\u4f7f\u7528 <code>mmap<\/code> \u6765\u521b\u5efa\u6587\u4ef6\u6620\u5c04\uff0c\u591a\u6b21\u6620\u5c04\u540c\u4e00\u4e2a\u6587\u4ef6\u4f1a\u5171\u4eab\u540c\u4e00\u5757\u7269\u7406\u5185\u5b58\uff0c\u53ef\u4ee5\u901a\u8fc7\u7c7b\u4f3c\u4e0b\u9762\u7684\u4ee3\u7801\u6765\u5b9e\u73b0\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-c\" data-lang=\"c\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ 1G\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">SIZE<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1024<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1024<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1024<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kt\">int<\/span> <span class=\"n\">fd<\/span> <span class=\"o\">=<\/span> <span class=\"n\">syscall<\/span><span class=\"p\">(<\/span><span class=\"n\">SYS_memfd_create<\/span><span class=\"p\">,<\/span> <span class=\"s\">&#34;shma&#34;<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">ftruncate<\/span><span class=\"p\">(<\/span><span class=\"n\">fd<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kt\">void<\/span> <span class=\"o\">*<\/span><span class=\"n\">ptr0<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mmap<\/span><span class=\"p\">(<\/span><span class=\"nb\">NULL<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">,<\/span> <span class=\"n\">PROT_READ<\/span><span class=\"o\">|<\/span><span class=\"n\">PROT_WRITE<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAP_SHARED<\/span><span class=\"p\">,<\/span> <span class=\"n\">fd<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">memset<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr0<\/span><span class=\"p\">,<\/span> <span class=\"sc\">&#39;A&#39;<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kt\">void<\/span> <span class=\"o\">*<\/span><span class=\"n\">ptr1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mmap<\/span><span class=\"p\">(<\/span><span class=\"nb\">NULL<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">,<\/span> <span class=\"n\">PROT_READ<\/span><span class=\"o\">|<\/span><span class=\"n\">PROT_WRITE<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAP_SHARED<\/span><span class=\"p\">,<\/span> <span class=\"n\">fd<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">memset<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr1<\/span><span class=\"p\">,<\/span> <span class=\"sc\">&#39;B&#39;<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kt\">void<\/span> <span class=\"o\">*<\/span><span class=\"n\">ptr2<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mmap<\/span><span class=\"p\">(<\/span><span class=\"nb\">NULL<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">,<\/span> <span class=\"n\">PROT_READ<\/span><span class=\"o\">|<\/span><span class=\"n\">PROT_WRITE<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAP_SHARED<\/span><span class=\"p\">,<\/span> <span class=\"n\">fd<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">memset<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr2<\/span><span class=\"p\">,<\/span> <span class=\"sc\">&#39;C&#39;<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIZE<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u6bb5\u4ee3\u7801\u4f1a\u521b\u5efa\u4e00\u4e2a\u533f\u540d\u6587\u4ef6\uff0c\u7136\u540e\u6620\u5c04\u4e09\u6b21\u5e76\u5206\u522b\u5199\u5165 A\u3001B\u3001C \u4e09\u79cd\u5b57\u7b26\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">cat \/proc\/2306924\/status\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Name: memfd_create\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssAnon: <span class=\"m\">96<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssFile: <span class=\"m\">1320<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">RssShmem: <span class=\"m\">3145540<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">pmap -x <span class=\"m\">2306924<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">2306924: .\/memfd_create\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Address Kbytes RSS Dirty Mode Mapping\n<\/span><\/span><span class=\"line\"><span class=\"cl\">00007f1b16ee7000 <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> rw-s- memfd:shma <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">00007f1b56ee7000 <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> rw-s- memfd:shma <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">00007f1b96ee7000 <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> <span class=\"m\">1048576<\/span> rw-s- memfd:shma <span class=\"o\">(<\/span>deleted<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">dd <span class=\"k\">if<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/proc\/2306924\/mem&#34;<\/span> <span class=\"nv\">of<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;\/dev\/stdout&#34;<\/span> <span class=\"nv\">bs<\/span><span class=\"o\">=<\/span><span class=\"m\">1<\/span> <span class=\"nv\">skip<\/span><span class=\"o\">=<\/span><span class=\"k\">$((<\/span><span class=\"m\">0<\/span>x00007f1b16ee7000<span class=\"k\">))<\/span> <span class=\"nv\">count<\/span><span class=\"o\">=<\/span><span class=\"m\">128<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC128+0 records in\n<\/span><\/span><span class=\"line\"><span class=\"cl\">128+0 records out\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"m\">128<\/span> bytes copied, 0.000432721 s, <span class=\"m\">296<\/span> kB\/s\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u770b\u5230\u521b\u5efa\u7684\u533f\u540d\u6587\u4ef6\u88ab\u6620\u5c04\u4e86\u4e09\u6b21\uff0c\u5e76\u4e14\u5bf9\u5e94\u8fdb\u7a0b\u7684 RssShmem \u4e5f\u662f 3G<\/p>\n<h3 id=\"zgc-\u4e2d\u5806\u5185\u5b58\u6620\u5c04\">ZGC \u4e2d\u5806\u5185\u5b58\u6620\u5c04<\/h3>\n<p>\u9700\u8981\u56de\u7b54\u7684\u4e0b\u4e00\u4e2a\u95ee\u9898\u662f\uff1a\u4e3a\u4ec0\u4e48 Java \u5c06\u5806\u5185\u5b58\u6620\u5c04\u4e09\u6b21\uff1f\u8fd9\u6e90\u4e8e ZGC \u5f15\u5165\u7684\u6307\u9488\u67d3\u8272\u6280\u672f\uff0c\u5373\u7528\u5bf9\u8c61\u6307\u9488\u4e2d\u7684\u67d0\u51e0\u4f4d\u6765\u4f5c\u4e3a GC \u6807\u8bb0\uff0c\u8fd9\u6837\u5c31\u4e0d\u9700\u8981\u989d\u5916\u7684\u5bf9\u8c61\u5934\u7a7a\u95f4\u6765\u8bb0\u5f55 GC \u6807\u8bb0\u4e86\u3002\u6bd4\u5982\u6211\u4eec\u7528 16 \u8fdb\u5236\u4e0b\u7684\u5bf9\u8c61\u6307\u9488\u6700\u9ad8\u4f4d\u6765\u4f5c\u4e3a GC \u6807\u8bb0\uff0c\u90a3\u4e48\u6307\u5411 0x13210 \u7684\u5bf9\u8c61 GC \u6807\u8bb0\u662f 0x1\uff0c\u5730\u5740\u662f 0x3210<\/p>\n<p>\u5bf9\u4e8e\u8ba1\u7b97\u673a\u6765\u8bf4\uff0c\u53ef\u4ee5\u7528\u63a9\u7801\u5b9e\u73b0\u4ece\u5bf9\u8c61\u6307\u9488\u4e2d\u63d0\u53d6 GC \u6807\u8bb0\u548c\u5bf9\u8c61\u5730\u5740\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-text\" data-lang=\"text\"><span class=\"line\"><span class=\"cl\">Pointer value: 0x13210 : 0001 0011 0010 0001 0000\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Metadata mask: &amp; 0xf0000 : 1111 0000 0000 0000 0000\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Metadata bits: 0x1 : 0001\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Pointer value: 0x13210 : 0001 0011 0010 0001 0000\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Address mask: &amp; 0x0ffff : 0000 1111 1111 1111 1111\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Address bits: 0x3210 : 0011 0010 0001 0000\n<\/span><\/span><\/code><\/pre><\/div><p>\u6bcf\u6b21\u8bbf\u95ee\u5bf9\u8c61\u65f6\uff0c\u90fd\u9700\u8981\u5c06 GC \u6807\u8bb0\u4f4d\u6e05\u96f6\u4ee5\u5f97\u5230\u771f\u5b9e\u7684\u5730\u5740\uff0c\u8fd9\u662f\u4e0d\u53ef\u5ffd\u7565\u7684\u5f00\u9500\u3002ZGC \u4f7f\u7528\u591a\u91cd\u6620\u5c04\u6280\u672f\u5de7\u5999\u7684\u907f\u514d\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002\u8003\u8651\u5230 0x13210\u30010x23210 \u90fd\u6307\u5411\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u5c06\u8fd9\u4e24\u4e2a\u5730\u5740\u6620\u5c04\u5230\u540c\u4e00\u5757\u7269\u7406\u5185\u5b58\u4e0a\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u907f\u514d\u6bcf\u6b21\u8bbf\u95ee\u5bf9\u8c61\u65f6\u7684\u63a9\u7801\u64cd\u4f5c\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-text\" data-lang=\"text\"><span class=\"line\"><span class=\"cl\">+-----------+ 0x10000\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| X | 0x13210 -----+ +----------------------+\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| | \\ | |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">+-----------+ 0x20000 +---&gt; | X @ offset 0x3210 |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| | \/ | |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| X | 0x23210 -----+ +----------------------+\n<\/span><\/span><span class=\"line\"><span class=\"cl\">| |\n<\/span><\/span><span class=\"line\"><span class=\"cl\">+-----------+ 0x30000\n<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u5c06\u5806\u6620\u5c04\u5230 0x10000~0x20000 \u548c 0x20000~0x30000 \u8fd9\u4e24\u4e2a\u865a\u62df\u5185\u5b58\u7a7a\u95f4\u4e0a\u3002\u53ea\u8981\u76f8\u5bf9\u4e8e 0x10000 \u548c 0x20000 \u7684\u504f\u79fb\u91cf\u76f8\u540c\uff0c\u5c31\u80fd\u8bbf\u95ee\u5230\u540c\u4e00\u5757\u7269\u7406\u5185\u5b58<\/p>\n<p>\u8fd9\u662f\u4e00\u79cd\u7a7a\u95f4\u6362\u65f6\u95f4\u7684\u505a\u6cd5\u3002\u5b9e\u9645\u4e0a\u6d6a\u8d39\u7684\u7a7a\u95f4\u662f\u865a\u62df\u5185\u5b58\u7684\u7a7a\u95f4\uff0c\u7528\u9875\u8868\u7684\u5f00\u9500\u6362\u53d6\u4e86\u6bcf\u6b21\u5bf9\u8c61\u8bbf\u95ee\u65f6\u7684\u63a9\u7801\u64cd\u4f5c\uff0c\u662f\u4e00\u4e2a\u975e\u5e38\u503c\u5f97\u7684 trade off<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u66f4\u8be6\u7ec6\u7684\u8bbe\u8ba1\u53ef\u4ee5\u53c2\u8003 <a class=\"link\" href=\"https:\/\/wiki.openjdk.org\/display\/zgc\/Pointer&#43;Metadata&#43;using&#43;Multi-Mapped&#43;memory\" target=\"_blank\" rel=\"noopener\"\n>OpenJDK Wiki<\/a>\n<\/div>\n<p><\/p>\n<h3 id=\"\u89c2\u6d4b\u771f\u5b9e\u5185\u5b58\u5360\u7528\">\u89c2\u6d4b\u771f\u5b9e\u5185\u5b58\u5360\u7528<\/h3>\n<p>Linux \u4e2d\u4e00\u4e2a\u8fdb\u7a0b\u5360\u7528\u7684\u5185\u5b58\u6709\u591a\u79cd\u7edf\u8ba1\u65b9\u5f0f\uff0c\u53ef\u4ee5\u5206\u4e3a VSS\u3001RSS\u3001PSS\u3001USS\uff1a<\/p>\n<ul>\n<li>VSS\uff1aVirtual Set Size\uff0c\u8fdb\u7a0b\u7533\u8bf7\u7684\u865a\u62df\u5185\u5b58\u5927\u5c0f<\/li>\n<li>RSS\uff1aResident Set Size\uff0c\u8fdb\u7a0b\u7684\u5e38\u9a7b\u5185\u5b58\u5927\u5c0f\uff0c\u5305\u62ec\u4ee3\u7801\u6bb5\u3001\u5806\u3001\u6808\u3001\u5171\u4eab\u5e93\u3001\u6620\u5c04\u6587\u4ef6\u7b49<\/li>\n<li>PSS\uff1aProportional Set Size\uff0c\u8fdb\u7a0b\u7684\u6bd4\u4f8b\u5185\u5b58\u5927\u5c0f\uff0cRSS \u4e2d\u7684\u5171\u4eab\u5185\u5b58\u6309\u7167\u6bd4\u4f8b\u5206\u644a\u5230\u5404\u4e2a\u8fdb\u7a0b<\/li>\n<li>USS\uff1aUnique Set Size\uff0c\u8fdb\u7a0b\u72ec\u5360\u7684\u5185\u5b58\u5927\u5c0f\uff0cRSS \u4e2d\u7684\u5171\u4eab\u5185\u5b58\u4e0d\u8ba1\u5165 USS<\/li>\n<\/ul>\n<p>\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 PSS \u6765\u89c2\u6d4b\u771f\u5b9e\u7684\u5185\u5b58\u5360\u7528\u60c5\u51b5\uff0c\u8fd9\u91cc\u4f7f\u7528\u4e86 <code>\/proc\/[pid]\/smaps_rollup<\/code> \u6765\u67e5\u770b PSS\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">cat \/proc\/2306924\/smaps_rollup\n<\/span><\/span><span class=\"line\"><span class=\"cl\">5626d2e58000-7ffca670f000 ---p <span class=\"m\">00000000<\/span> 00:00 <span class=\"m\">0<\/span> <span class=\"o\">[<\/span>rollup<span class=\"o\">]<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Rss: <span class=\"m\">3147164<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Pss: <span class=\"m\">1048716<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Pss_Anon: <span class=\"m\">100<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Pss_File: <span class=\"m\">40<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Pss_Shmem: <span class=\"m\">1048575<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Shared_Clean: <span class=\"m\">1324<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Shared_Dirty: <span class=\"m\">3145728<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Private_Clean: <span class=\"m\">12<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Private_Dirty: <span class=\"m\">100<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Referenced: <span class=\"m\">3147164<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Anonymous: <span class=\"m\">100<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">LazyFree: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">AnonHugePages: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ShmemPmdMapped: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">FilePmdMapped: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Shared_Hugetlb: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Private_Hugetlb: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Swap: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">SwapPss: <span class=\"m\">0<\/span> kB\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Locked: <span class=\"m\">0<\/span> kB\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0 Pss_Shmem \u662f RssShmem \u7684\u4e09\u5206\u4e4b\u4e00\uff0c\u66f4\u80fd\u53cd\u5e94\u771f\u5b9e\u5185\u5b58\u5360\u7528<\/p>"},{"title":"RocketMQ \u591a\u7ea7\u5b58\u50a8\u8bbe\u8ba1\u4e0e\u5b9e\u73b0","link":"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq","pubDate":"Sun, 26 Feb 2023 10:45:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq\/tiered_storage.png\" alt=\"Featured image of post RocketMQ \u591a\u7ea7\u5b58\u50a8\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\" \/><p>\u968f\u7740 RocketMQ 5.1.0 \u7684\u6b63\u5f0f\u53d1\u5e03\uff0c\u591a\u7ea7\u5b58\u50a8\u4f5c\u4e3a RocketMQ \u4e00\u4e2a\u65b0\u7684\u72ec\u7acb\u6a21\u5757\u5230\u8fbe\u4e86 Technical Preview \u91cc\u7a0b\u7891\uff1a\u5141\u8bb8\u7528\u6237\u5c06\u6d88\u606f\u4ece\u672c\u5730\u78c1\u76d8\u5378\u8f7d\u5230\u5176\u4ed6\u66f4\u4fbf\u5b9c\u7684\u5b58\u50a8\u4ecb\u8d28\uff0c\u53ef\u4ee5\u7528\u8f83\u4f4e\u7684\u6210\u672c\u5ef6\u957f\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd RocketMQ \u591a\u7ea7\u5b58\u50a8\u8bbe\u8ba1\u4e0e\u5b9e\u73b0<\/p>\n<h2 id=\"\u8bbe\u8ba1\u603b\u89c8\">\u8bbe\u8ba1\u603b\u89c8<\/h2>\n<p>RocketMQ \u591a\u7ea7\u5b58\u50a8\u65e8\u5728<strong>\u4e0d\u5f71\u54cd\u70ed\u6570\u636e\u8bfb\u5199<\/strong>\u7684\u524d\u63d0\u4e0b\u5c06\u6570\u636e\u5378\u8f7d\u5230\u5176\u4ed6\u5b58\u50a8\u4ecb\u8d28\u4e2d\uff0c\u9002\u7528\u4e8e\u4e24\u79cd\u573a\u666f\uff1a<\/p>\n<ol>\n<li>\n<p>\u51b7\u70ed\u6570\u636e\u5206\u79bb\uff1aRocketMQ \u65b0\u8fd1\u4ea7\u751f\u7684\u6d88\u606f\u4f1a\u7f13\u5b58\u5728 page cache \u4e2d\uff0c\u6211\u4eec\u79f0\u4e4b\u4e3a<strong>\u70ed\u6570\u636e<\/strong>\uff1b\u5f53\u7f13\u5b58\u8d85\u8fc7\u4e86\u5185\u5b58\u7684\u5bb9\u91cf\u5c31\u4f1a\u6709\u70ed\u6570\u636e\u88ab\u6362\u51fa\u6210\u4e3a<strong>\u51b7\u6570\u636e<\/strong>\u3002\u5982\u679c\u6709\u5c11\u8bb8\u6d88\u8d39\u8005\u5c1d\u8bd5\u6d88\u8d39\u51b7\u6570\u636e\u5c31\u4f1a\u4ece\u786c\u76d8\u4e2d\u91cd\u65b0\u52a0\u8f7d\u51b7\u6570\u636e\u5230 page cache\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u8bfb\u5199 IO \u7ade\u4e89\u5e76\u6324\u538b page cache \u7684\u7a7a\u95f4\u3002\u800c\u5c06\u51b7\u6570\u636e\u7684\u8bfb\u53d6\u94fe\u8def\u5207\u6362\u4e3a\u591a\u7ea7\u5b58\u50a8\u5c31\u53ef\u4ee5\u907f\u514d\u8fd9\u4e2a\u95ee\u9898<\/p>\n<\/li>\n<li>\n<p>\u5ef6\u957f\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\uff1a\u5c06\u6d88\u606f\u5378\u8f7d\u5230\u66f4\u5927\u66f4\u4fbf\u5b9c\u7684\u5b58\u50a8\u4ecb\u8d28\u4e2d\uff0c\u53ef\u4ee5\u7528\u8f83\u4f4e\u7684\u6210\u672c\u5b9e\u73b0\u66f4\u957f\u7684\u6d88\u606f\u4fdd\u5b58\u65f6\u95f4\u3002\u540c\u65f6\u591a\u7ea7\u5b58\u50a8\u652f\u6301\u4e3a topic \u6307\u5b9a\u4e0d\u540c\u7684\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\uff0c\u53ef\u4ee5\u6839\u636e\u4e1a\u52a1\u9700\u8981\u7075\u6d3b\u914d\u7f6e\u6d88\u606f TTL<\/p>\n<\/li>\n<\/ol>\n<p>RocketMQ \u591a\u7ea7\u5b58\u50a8\u5bf9\u6bd4 Kafka \u548c Pulsar \u7684\u5b9e\u73b0\u6700\u5927\u7684\u4e0d\u540c\u662f\u6211\u4eec\u4f7f\u7528\u51c6\u5b9e\u65f6\u7684\u65b9\u5f0f\u4e0a\u4f20\u6d88\u606f\uff0c\u800c\u4e0d\u662f\u7b49\u4e00\u4e2a CommitLog \u5199\u6ee1\u540e\u518d\u4e0a\u4f20\uff0c\u4e3b\u8981\u57fa\u4e8e\u4ee5\u4e0b\u51e0\u70b9\u8003\u8651\uff1a<\/p>\n<ol>\n<li>\n<p>\u5747\u644a\u6210\u672c\uff1aRocketMQ \u591a\u7ea7\u5b58\u50a8\u9700\u8981\u5c06\u5168\u5c40 CommitLog \u8f6c\u6362\u4e3a topic \u7ef4\u5ea6\u5e76\u91cd\u65b0\u6784\u5efa\u6d88\u606f\u7d22\u5f15\uff0c\u4e00\u6b21\u6027\u5904\u7406\u6574\u4e2a CommitLog \u6587\u4ef6\u4f1a\u5e26\u6765\u6027\u80fd\u6bdb\u523a<\/p>\n<\/li>\n<li>\n<p>\u5bf9\u5c0f\u89c4\u683c\u5b9e\u4f8b\u66f4\u53cb\u597d\uff1a\u5c0f\u89c4\u683c\u5b9e\u4f8b\u5f80\u5f80\u914d\u7f6e\u8f83\u5c0f\u7684\u5185\u5b58\uff0c\u8fd9\u610f\u5473\u7740\u70ed\u6570\u636e\u4f1a\u66f4\u5feb\u6362\u51fa\u6210\u4e3a\u51b7\u6570\u636e\uff0c\u7b49\u5f85 CommitLog \u5199\u6ee1\u518d\u4e0a\u4f20\u672c\u8eab\u5c31\u6709\u51b7\u8bfb\u98ce\u9669\u3002\u91c7\u53d6\u51c6\u5b9e\u65f6\u4e0a\u4f20\u7684\u65b9\u5f0f\u65e2\u80fd\u89c4\u907f\u6d88\u606f\u4e0a\u4f20\u65f6\u7684\u51b7\u8bfb\u98ce\u9669\uff0c\u53c8\u80fd\u5c3d\u5feb\u4f7f\u5f97\u51b7\u6570\u636e\u53ef\u4ee5\u4ece\u591a\u7ea7\u5b58\u50a8\u8bfb\u53d6<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"quick-start\">Quick Start<\/h2>\n<p>\u591a\u7ea7\u5b58\u50a8\u5728\u8bbe\u8ba1\u4e0a\u5e0c\u671b\u964d\u4f4e\u7528\u6237\u5fc3\u667a\u8d1f\u62c5\uff1a\u7528\u6237\u65e0\u9700\u53d8\u66f4\u5ba2\u6237\u7aef\u5c31\u80fd\u5b9e\u73b0\u65e0\u611f\u5207\u6362\u51b7\u70ed\u6570\u636e\u8bfb\u5199\u94fe\u8def\uff0c\u901a\u8fc7\u7b80\u5355\u7684\u4fee\u6539\u670d\u52a1\u7aef\u914d\u7f6e\u5373\u53ef\u5177\u5907\u591a\u7ea7\u5b58\u50a8\u7684\u80fd\u529b\uff0c\u53ea\u9700\u4ee5\u4e0b\u4e24\u6b65\uff1a<\/p>\n<ol>\n<li>\u4fee\u6539 Broker \u914d\u7f6e\uff0c\u6307\u5b9a\u4f7f\u7528 <code>org.apache.rocketmq.tieredstore.TieredMessageStore<\/code> \u4f5c\u4e3a <code>messageStorePlugIn<\/code><\/li>\n<li>\u914d\u7f6e\u4f60\u60f3\u4f7f\u7528\u7684\u50a8\u5b58\u4ecb\u8d28\uff0c\u4ee5\u5378\u8f7d\u6d88\u606f\u5230\u5176\u4ed6\u786c\u76d8\u4e3a\u4f8b\uff1a\u914d\u7f6e <code>tieredBackendServiceProvider<\/code> \u4e3a <code>org.apache.rocketmq.tieredstore.provider.posix.PosixFileSegment<\/code>\uff0c\u540c\u65f6\u6307\u5b9a\u65b0\u50a8\u5b58\u7684\u6587\u4ef6\u8def\u5f84\uff1a<code>tieredStoreFilepath<\/code><\/li>\n<\/ol>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u53ef\u9009\u9879\uff1a\u652f\u6301\u4fee\u6539 <code>tieredMetadataServiceProvider<\/code> \u5207\u6362\u5143\u6570\u636e\u5b58\u50a8\u7684\u5b9e\u73b0\uff0c\u9ed8\u8ba4\u662f\u57fa\u4e8e json \u7684\u6587\u4ef6\u5b58\u50a8\n<\/div>\n<p><\/p>\n<p>\u66f4\u591a\u4f7f\u7528\u8bf4\u660e\u548c\u914d\u7f6e\u9879\u53ef\u4ee5\u5728 GitHub \u4e0a\u67e5\u770b\u591a\u7ea7\u5b58\u50a8\u7684 <a class=\"link\" href=\"https:\/\/github.com\/apache\/rocketmq\/blob\/develop\/tieredstore\/README.md\" target=\"_blank\" rel=\"noopener\"\n>README<\/a><\/p>\n<h2 id=\"\u6280\u672f\u67b6\u6784\">\u6280\u672f\u67b6\u6784<\/h2>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq\/tiered_storage_arch.jpg\" width=\"708\" height=\"800\"\/><figcaption>\n<h4>architecture<\/h4>\n<\/figcaption>\n<\/figure>\n<ul>\n<li>\n<p>\u63a5\u5165\u5c42\uff1aTieredMessageStore\/TieredDispatcher\/TieredMessageFetcher<br \/>\n\u63a5\u5165\u5c42\u5b9e\u73b0 MessageStore \u4e2d\u7684\u90e8\u5206\u8bfb\u5199\u63a5\u53e3\uff0c\u5e76\u4e3a\u4ed6\u4eec\u589e\u52a0\u4e86\u5f02\u6b65\u8bed\u610f\u3002TieredDispatcher \u548c TieredMessageFetcher \u5206\u522b\u5b9e\u73b0\u4e86\u591a\u7ea7\u5b58\u50a8\u7684\u4e0a\u4f20\/\u4e0b\u8f7d\u903b\u8f91\uff0c\u76f8\u6bd4\u4e8e\u5e95\u5c42\u63a5\u53e3\u8fd9\u91cc\u505a\u4e86\u8f83\u591a\u7684\u6027\u80fd\u4f18\u5316\uff1a\u5305\u62ec\u4f7f\u7528\u72ec\u7acb\u7684\u7ebf\u7a0b\u6c60\uff0c\u907f\u514d\u6162 IO \u963b\u585e\u8bbf\u95ee\u70ed\u6570\u636e\uff1b\u4f7f\u7528\u9884\u8bfb\u7f13\u5b58\u4f18\u5316\u6027\u80fd\u7b49<\/p>\n<\/li>\n<li>\n<p>\u5bb9\u5668\u5c42\uff1aTieredCommitLog\/TieredConsumeQueue\/TieredIndexFile\/TieredFileQueue<br \/>\n\u5bb9\u5668\u5c42\u5b9e\u73b0\u4e86\u548c DefaultMessageStore \u7c7b\u4f3c\u7684\u903b\u8f91\u6587\u4ef6\u62bd\u8c61\uff0c\u540c\u6837\u5c06\u6587\u4ef6\u5212\u5206\u4e3a CommitLog\u3001ConsumeQueue\u3001IndexFile\uff0c\u5e76\u4e14\u6bcf\u79cd\u903b\u8f91\u6587\u4ef6\u7c7b\u578b\u90fd\u901a\u8fc7 FileQueue \u6301\u6709\u5e95\u5c42\u7269\u7406\u6587\u4ef6\u7684\u5f15\u7528\u3002\u6709\u6240\u4e0d\u540c\u7684\u662f\u591a\u7ea7\u5b58\u50a8\u7684 CommitLog \u6539\u4e3a queue \u7ef4\u5ea6<\/p>\n<\/li>\n<li>\n<p>\u9a71\u52a8\u5c42\uff1aTieredFileSegment<br \/>\n\u9a71\u52a8\u5c42\u8d1f\u8d23\u7ef4\u62a4\u903b\u8f91\u6587\u4ef6\u5230\u7269\u7406\u6587\u4ef6\u7684\u6620\u5c04\uff0c\u901a\u8fc7\u5b9e\u73b0 TieredStoreProvider \u5bf9\u63a5\u5e95\u5c42\u6587\u4ef6\u7cfb\u7edf\u8bfb\u5199\u63a5\u53e3(Posix\u3001S3\u3001OSS\u3001MinIO \u7b49)\u3002\u76ee\u524d\u63d0\u4f9b\u4e86 PosixFileSegment \u7684\u5b9e\u73b0\uff0c\u53ef\u4ee5\u5c06\u6570\u636e\u8f6c\u79fb\u5230\u5176\u4ed6\u786c\u76d8\u6216\u901a\u8fc7 fuse \u6302\u8f7d\u7684\u5bf9\u8c61\u5b58\u50a8\u4e0a<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"\u6d88\u606f\u4e0a\u4f20\">\u6d88\u606f\u4e0a\u4f20<\/h3>\n<p>RocketMQ \u591a\u7ea7\u5b58\u50a8\u7684\u6d88\u606f\u4e0a\u4f20\u662f\u7531 dispatch \u673a\u5236\u89e6\u53d1\u7684\uff1a\u521d\u59cb\u5316\u591a\u7ea7\u5b58\u50a8\u65f6\u4f1a\u5c06 TieredDispatcher \u6ce8\u518c\u4e3a CommitLog \u7684 dispacher\u3002\u8fd9\u6837\u6bcf\u5f53\u6709\u6d88\u606f\u53d1\u9001\u5230 Broker \u4f1a\u8c03\u7528 TieredDispatcher \u8fdb\u884c\u6d88\u606f\u5206\u53d1\uff0cTieredDispatcher \u5c06\u8be5\u6d88\u606f\u5199\u5165\u5230 upload buffer \u540e\u7acb\u5373\u8fd4\u56de\u6210\u529f\u3002\u6574\u4e2a dispatch \u6d41\u7a0b\u4e2d\u4e0d\u4f1a\u6709\u4efb\u4f55\u963b\u585e\u903b\u8f91\uff0c\u786e\u4fdd\u4e0d\u4f1a\u5f71\u54cd\u672c\u5730 ConsumeQueue \u7684\u6784\u5efa<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq\/dispatch.jpg\" width=\"420\" height=\"295\"\/><figcaption>\n<h4>TieredDispatcher<\/h4>\n<\/figcaption>\n<\/figure>\n<p>TieredDispatcher \u5199\u5165 upload buffer \u7684\u5185\u5bb9\u4ec5\u4e3a\u6d88\u606f\u7684\u5f15\u7528\uff0c\u4e0d\u4f1a\u5c06\u6d88\u606f\u7684 body \u8bfb\u5165\u5185\u5b58\u3002\u56e0\u4e3a\u591a\u7ea7\u50a8\u5b58\u4ee5 queue \u7ef4\u5ea6\u6784\u5efa CommitLog\uff0c\u6b64\u65f6\u9700\u8981\u91cd\u65b0\u751f\u6210 commitLog offset \u5b57\u6bb5<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq\/upload_buffer.jpg\" width=\"318\" height=\"145\"\/><figcaption>\n<h4>upload buffer<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u89e6\u53d1 upload buffer \u4e0a\u4f20\u65f6\u8bfb\u53d6\u5230\u6bcf\u6761\u6d88\u606f\u7684 commitLog offset \u5b57\u6bb5\u65f6\u91c7\u7528\u62fc\u63a5\u7684\u65b9\u5f0f\u5c06\u65b0\u7684 offset \u5d4c\u5165\u5230\u539f\u6d88\u606f\u4e2d<\/p>\n<h4 id=\"\u4e0a\u4f20\u8fdb\u5ea6\u63a7\u5236\">\u4e0a\u4f20\u8fdb\u5ea6\u63a7\u5236<\/h4>\n<p>\u6bcf\u4e2a\u961f\u5217\u90fd\u4f1a\u6709\u4e24\u4e2a\u5173\u952e\u4f4d\u70b9\u63a7\u5236\u4e0a\u4f20\u8fdb\u5ea6\uff1a<\/p>\n<ol>\n<li>dispatch offset\uff1a\u5df2\u7ecf\u5199\u5165\u7f13\u5b58\u4f46\u662f\u672a\u4e0a\u4f20\u7684\u6d88\u606f\u4f4d\u70b9<\/li>\n<li>commit offset\uff1a\u5df2\u4e0a\u4f20\u7684\u6d88\u606f\u4f4d\u70b9<\/li>\n<\/ol>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/introduce-tiered-storage-for-rocketmq\/upload_progress.jpg\" width=\"471\" height=\"206\"\/><figcaption>\n<h4>upload progress<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u7c7b\u6bd4\u6d88\u8d39\u8005\uff0cdispatch offset \u76f8\u5f53\u4e8e\u62c9\u53d6\u6d88\u606f\u7684\u4f4d\u70b9\uff0ccommit offset \u76f8\u5f53\u4e8e\u786e\u8ba4\u6d88\u8d39\u7684\u4f4d\u70b9\u3002commit offset \u5230 dispatch offset \u4e4b\u95f4\u7684\u90e8\u5206\u76f8\u5f53\u4e8e\u5df2\u62c9\u53d6\u672a\u6d88\u8d39\u7684\u6d88\u606f<\/p>\n<h3 id=\"\u6d88\u606f\u8bfb\u53d6\">\u6d88\u606f\u8bfb\u53d6<\/h3>\n<p>TieredMessageStore \u5b9e\u73b0\u4e86 MessageStore \u4e2d\u7684\u6d88\u606f\u8bfb\u53d6\u76f8\u5173\u63a5\u53e3\uff0c\u901a\u8fc7\u8bf7\u6c42\u4e2d\u7684\u903b\u8f91\u4f4d\u70b9\uff08queue offset\uff09\u5224\u65ad\u662f\u5426\u4ece\u591a\u7ea7\u5b58\u50a8\u4e2d\u8bfb\u53d6\u6d88\u606f\uff0c\u6839\u636e\u914d\u7f6e\uff08tieredStorageLevel\uff09\u6709\u56db\u79cd\u7b56\u7565\uff1a<\/p>\n<ul>\n<li>DISABLE\uff1a\u7981\u6b62\u4ece\u591a\u7ea7\u5b58\u50a8\u4e2d\u8bfb\u53d6\u6d88\u606f<\/li>\n<li>NOT_IN_DISK\uff1a\u4e0d\u5728 DefaultMessageStore \u4e2d\u7684\u6d88\u606f\u4ece\u591a\u7ea7\u5b58\u50a8\u4e2d\u8bfb\u53d6<\/li>\n<li>NOT_IN_MEM\uff1a\u4e0d\u5728 page cache \u4e2d\u7684\u6d88\u606f\u5373\u51b7\u6570\u636e\u4ece\u591a\u7ea7\u5b58\u50a8\u8bfb\u53d6<\/li>\n<li>FORCE\uff1a\u5f3a\u5236\u6240\u6709\u6d88\u606f\u4ece\u591a\u7ea7\u5b58\u50a8\u4e2d\u8bfb\u53d6\uff0c\u76ee\u524d\u4ec5\u4f9b\u6d4b\u8bd5\u4f7f\u7528<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"cm\">\/**\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * Asynchronous get message\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @see #getMessage(String, String, int, long, int, MessageFilter) getMessage\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param group Consumer group that launches this query.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param topic Topic to query.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param queueId Queue ID to query.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param offset Logical offset to start from.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param maxMsgNums Maximum count of messages to query.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param messageFilter Message filter used to screen desired messages.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @return Matched messages.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\/<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">CompletableFuture<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">GetMessageResult<\/span><span class=\"o\">&gt;<\/span> <span class=\"nf\">getMessageAsync<\/span><span class=\"o\">(<\/span><span class=\"kd\">final<\/span> <span class=\"n\">String<\/span> <span class=\"n\">group<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">String<\/span> <span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">queueId<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kd\">final<\/span> <span class=\"kt\">long<\/span> <span class=\"n\">offset<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">maxMsgNums<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">MessageFilter<\/span> <span class=\"n\">messageFilter<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u9700\u8981\u4ece\u591a\u7ea7\u5b58\u50a8\u4e2d\u8bfb\u53d6\u7684\u6d88\u606f\u4f1a\u4ea4\u7531 TieredMessageFetcher \u5904\u7406\uff1a\u9996\u5148\u6821\u9a8c\u53c2\u6570\u662f\u5426\u5408\u6cd5\uff0c\u7136\u540e\u6309\u7167\u903b\u8f91\u4f4d\u70b9\uff08queue offset\uff09\u53d1\u8d77\u62c9\u53d6\u8bf7\u6c42\u3002TieredConsumeQueue\/TieredCommitLog \u5c06\u903b\u8f91\u4f4d\u70b9\u6362\u7b97\u4e3a\u5bf9\u5e94\u6587\u4ef6\u7684\u7269\u7406\u4f4d\u70b9\u4ece TieredFileSegment \u8bfb\u53d6\u6d88\u606f<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ TieredMessageFetcher#getMessageAsync similar with TieredMessageStore#getMessageAsync\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"kd\">public<\/span> <span class=\"n\">CompletableFuture<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">GetMessageResult<\/span><span class=\"o\">&gt;<\/span> <span class=\"nf\">getMessageAsync<\/span><span class=\"o\">(<\/span><span class=\"n\">String<\/span> <span class=\"n\">group<\/span><span class=\"o\">,<\/span> <span class=\"n\">String<\/span> <span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">queueId<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kt\">long<\/span> <span class=\"n\">queueOffset<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">maxMsgNums<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">MessageFilter<\/span> <span class=\"n\">messageFilter<\/span><span class=\"o\">)<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>TieredFileSegment \u7ef4\u62a4\u6bcf\u4e2a\u50a8\u5b58\u5728\u6587\u4ef6\u7cfb\u7edf\u4e2d\u7684\u7269\u7406\u6587\u4ef6\u4f4d\u70b9\uff0c\u5e76\u901a\u8fc7\u4e3a\u4e0d\u540c\u5b58\u50a8\u4ecb\u8d28\u5b9e\u73b0\u7684\u63a5\u53e3\u4ece\u4e2d\u8bfb\u53d6\u6240\u9700\u7684\u6570\u636e<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"cm\">\/**\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * Get data from backend file system\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param position the index from where the file will be read\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param length the data size will be read\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @return data to be read\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\/<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">CompletableFuture<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">ByteBuffer<\/span><span class=\"o\">&gt;<\/span> <span class=\"nf\">read0<\/span><span class=\"o\">(<\/span><span class=\"kt\">long<\/span> <span class=\"n\">position<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">length<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"\u9884\u8bfb\u7f13\u5b58\">\u9884\u8bfb\u7f13\u5b58<\/h4>\n<p>TieredMessageFetcher \u8bfb\u53d6\u6d88\u606f\u65f6\u4f1a\u9884\u8bfb\u4e00\u90e8\u5206\u6d88\u606f\u4f9b\u4e0b\u6b21\u4f7f\u7528\uff0c\u8fd9\u4e9b\u6d88\u606f\u6682\u5b58\u5728\u9884\u8bfb\u7f13\u5b58\u4e2d<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">protected<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">Cache<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageCacheKey<\/span> <span class=\"cm\">\/* topic, queue id and queue offset *\/<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">SelectMappedBufferResultWrapper<\/span> <span class=\"cm\">\/* message data *\/<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">readAheadCache<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u9884\u8bfb\u7f13\u5b58\u7684\u8bbe\u8ba1\u53c2\u8003\u4e86 TCP Tahoe \u62e5\u585e\u63a7\u5236\u7b97\u6cd5\uff0c\u6bcf\u6b21\u9884\u8bfb\u7684\u6d88\u606f\u91cf\u7c7b\u4f3c\u62e5\u585e\u7a97\u53e3\u91c7\u7528\u52a0\u6cd5\u589e\u3001\u4e58\u6cd5\u51cf\u7684\u673a\u5236\u63a7\u5236\uff1a<\/p>\n<ul>\n<li>\u52a0\u6cd5\u589e\uff1a\u4ece\u6700\u5c0f\u7a97\u53e3\u5f00\u59cb\uff0c\u6bcf\u6b21\u589e\u52a0\u7b49\u540c\u4e8e\u5ba2\u6237\u7aef batchSize \u7684\u6d88\u606f\u91cf<\/li>\n<li>\u4e58\u6cd5\u51cf\uff1a\u5f53\u7f13\u5b58\u7684\u6d88\u606f\u8d85\u8fc7\u4e86\u7f13\u5b58\u8fc7\u671f\u65f6\u95f4\u4ecd\u672a\u88ab\u5168\u90e8\u62c9\u53d6\uff0c\u5728\u6e05\u7406\u7f13\u5b58\u7684\u540c\u65f6\u4f1a\u5c06\u4e0b\u6b21\u9884\u8bfb\u6d88\u606f\u91cf\u51cf\u534a<\/li>\n<\/ul>\n<p>\u9884\u8bfb\u7f13\u5b58\u652f\u6301\u5728\u8bfb\u53d6\u6d88\u606f\u91cf\u8f83\u5927\u65f6\u5206\u7247\u5e76\u53d1\u8bf7\u6c42\uff0c\u4ee5\u53d6\u5f97\u66f4\u5927\u5e26\u5bbd\u548c\u66f4\u5c0f\u7684\u5ef6\u8fdf<\/p>\n<p>\u67d0\u4e2a topic \u6d88\u606f\u7684\u9884\u8bfb\u7f13\u5b58\u7531\u6d88\u8d39\u8fd9\u4e2a topic \u7684\u6240\u6709 group \u5171\u4eab\uff0c\u7f13\u5b58\u5931\u6548\u7b56\u7565\u4e3a\uff1a<\/p>\n<ol>\n<li>\u6240\u6709\u8ba2\u9605\u8fd9\u4e2a topic \u7684 group \u90fd\u8bbf\u95ee\u4e86\u7f13\u5b58<\/li>\n<li>\u5230\u8fbe\u7f13\u5b58\u8fc7\u671f\u65f6\u95f4<\/li>\n<\/ol>\n<h3 id=\"\u6545\u969c\u6062\u590d\">\u6545\u969c\u6062\u590d<\/h3>\n<p>\u4e0a\u6587\u4e2d\u6211\u4eec\u4ecb\u7ecd\u4e0a\u4f20\u8fdb\u5ea6\u7531 commit offset \u548c dispatch offset \u63a7\u5236\u3002\u591a\u7ea7\u5b58\u50a8\u4f1a\u4e3a\u6bcf\u4e2a topic\u3001queue\u3001fileSegment \u521b\u5efa\u5143\u6570\u636e\u5e76\u6301\u4e45\u5316\u8fd9\u4e24\u79cd\u4f4d\u70b9\u3002\u5f53 Broker \u91cd\u542f\u540e\u4f1a\u4ece\u5143\u6570\u636e\u4e2d\u6062\u590d\uff0c\u7ee7\u7eed\u4ece commit offset \u5f00\u59cb\u4e0a\u4f20\u6d88\u606f\uff0c\u4e4b\u524d\u7f13\u5b58\u7684\u6d88\u606f\u4f1a\u91cd\u65b0\u4e0a\u4f20\u5e76\u4e0d\u4f1a\u4e22\u5931<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">classDiagram\nclass TopicMetadata\nTopicMetadata: &#43;int topicId\nTopicMetadata: &#43;String topic\nTopicMetadata: &#43;long reserveTime\nTopicMetadata: &#43;int status\nTopicMetadata: &#43;long updateTimeStamp\nclass QueueMetadata\nQueueMetadata: &#43;MessageQueue queue\nQueueMetadata: &#43;long minOffset\nQueueMetadata: &#43;long maxOffset\nQueueMetadata: &#43;long updateTimeStamp\n<\/div>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">classDiagram\nclass FileSegmentMetadata\nFileSegmentMetadata: &#43;MessageQueue queue\nFileSegmentMetadata: &#43;int status\nFileSegmentMetadata: &#43;int type\nFileSegmentMetadata: &#43;long baseOffset\nFileSegmentMetadata: &#43;String path\nFileSegmentMetadata: &#43;long size\nFileSegmentMetadata: &#43;long createTimestamp\nFileSegmentMetadata: &#43;long beginTimestamp\nFileSegmentMetadata: &#43;long endTimestamp\nFileSegmentMetadata: &#43;long sealTimestamp\n<\/div>\n<h2 id=\"\u5f00\u53d1\u8ba1\u5212\">\u5f00\u53d1\u8ba1\u5212<\/h2>\n<p>\u9762\u5411\u4e91\u539f\u751f\u7684\u5b58\u50a8\u7cfb\u7edf\u8981\u6700\u5927\u5316\u5229\u7528\u4e91\u4e0a\u5b58\u50a8\u7684\u4ef7\u503c\uff0c\u800c\u5bf9\u8c61\u5b58\u50a8\u6b63\u662f\u4e91\u8ba1\u7b97\u7ea2\u5229\u7684\u4f53\u73b0\u3002 RocketMQ \u591a\u7ea7\u5b58\u50a8\u5e0c\u671b\u4e00\u65b9\u9762\u5229\u7528\u5bf9\u8c61\u5b58\u50a8\u4f4e\u6210\u672c\u7684\u4f18\u52bf\u5ef6\u957f\u6d88\u606f\u5b58\u50a8\u65f6\u95f4\u3001\u62d3\u5c55\u6570\u636e\u7684\u4ef7\u503c\uff1b\u53e6\u4e00\u65b9\u9762\u5229\u7528\u5176\u5171\u4eab\u5b58\u50a8\u7684\u7279\u6027\u5728\u591a\u526f\u672c\u67b6\u6784\u4e2d\u517c\u5f97\u6210\u672c\u548c\u6570\u636e\u53ef\u9760\u6027\uff0c\u4ee5\u53ca\u672a\u6765\u5411 Serverless \u67b6\u6784\u6f14\u8fdb<\/p>\n<h3 id=\"tag-\u8fc7\u6ee4\">tag \u8fc7\u6ee4<\/h3>\n<p>\u591a\u7ea7\u5b58\u50a8\u62c9\u53d6\u6d88\u606f\u65f6\u6ca1\u6709\u8ba1\u7b97\u6d88\u606f\u7684 tag \u662f\u5426\u5339\u914d\uff0ctag \u8fc7\u6ee4\u4ea4\u7ed9\u5ba2\u6237\u7aef\u5904\u7406\u3002\u8fd9\u6837\u4f1a\u5e26\u6765\u989d\u5916\u7684\u7f51\u7edc\u5f00\u9500\uff0c\u8ba1\u5212\u540e\u7eed\u5728\u670d\u52a1\u7aef\u589e\u52a0 tag \u8fc7\u6ee4\u80fd\u529b<\/p>\n<h3 id=\"\u5e7f\u64ad\u6d88\u8d39\u4ee5\u53ca\u591a\u4e2a\u6d88\u8d39\u8fdb\u5ea6\u4e0d\u540c\u7684\u6d88\u8d39\u8005\">\u5e7f\u64ad\u6d88\u8d39\u4ee5\u53ca\u591a\u4e2a\u6d88\u8d39\u8fdb\u5ea6\u4e0d\u540c\u7684\u6d88\u8d39\u8005<\/h3>\n<p>\u9884\u8bfb\u7f13\u5b58\u5931\u6548\u9700\u8981\u6240\u6709\u8ba2\u9605\u8fd9\u4e2a topic \u7684 group \u90fd\u8bbf\u95ee\u4e86\u7f13\u5b58\uff0c\u8fd9\u5728\u591a\u4e2a group \u6d88\u8d39\u8fdb\u5ea6\u4e0d\u4e00\u81f4\u7684\u60c5\u51b5\u4e0b\u5f88\u96be\u89e6\u53d1\uff0c\u5bfc\u81f4\u65e0\u7528\u7684\u6d88\u606f\u5728\u7f13\u5b58\u4e2d\u5806\u79ef<\/p>\n<p>\u9700\u8981\u8ba1\u7b97\u51fa\u6bcf\u4e2a group \u7684\u6d88\u8d39 qps \u6765\u4f30\u7b97\u67d0\u4e2a group \u80fd\u5426\u5728\u7f13\u5b58\u5931\u6548\u524d\u7528\u4e0a\u7f13\u5b58\u7684\u6d88\u606f\u3002\u5982\u679c\u7f13\u5b58\u7684\u6d88\u606f\u9884\u671f\u5728\u5931\u6548\u524d\u90fd\u4e0d\u4f1a\u88ab\u518d\u6b21\u8bbf\u95ee\uff0c\u90a3\u4e48\u5b83\u5e94\u8be5\u88ab\u7acb\u5373\u8fc7\u671f\u3002\u76f8\u5e94\u7684\u5bf9\u4e8e\u5e7f\u64ad\u6d88\u8d39\uff0c\u6d88\u606f\u7684\u8fc7\u671f\u7b56\u7565\u5e94\u88ab\u4f18\u5316\u4e3a\u6240\u6709 Client \u90fd\u8bfb\u53d6\u8fd9\u6761\u6d88\u606f\u540e\u624d\u5931\u6548<\/p>\n<h3 id=\"\u548c\u9ad8\u53ef\u7528\u67b6\u6784\u7684\u878d\u5408\">\u548c\u9ad8\u53ef\u7528\u67b6\u6784\u7684\u878d\u5408<\/h3>\n<p>\u76ee\u524d\u4e3b\u8981\u9762\u4e34\u4ee5\u4e0b\u4e09\u4e2a\u95ee\u9898\uff1a<\/p>\n<ol>\n<li>\u5143\u6570\u636e\u540c\u6b65\uff1a\u5982\u4f55\u53ef\u9760\u7684\u5728\u591a\u4e2a\u8282\u70b9\u95f4\u540c\u6b65\u5143\u6570\u636e\uff0cslave \u664b\u5347\u65f6\u5982\u4f55\u6821\u51c6\u548c\u8865\u5168\u7f3a\u5931\u7684\u5143\u6570\u636e<\/li>\n<li>\u7981\u6b62\u4e0a\u4f20\u8d85\u8fc7 confirm offset \u7684\u6d88\u606f\uff1a\u4e3a\u4e86\u907f\u514d\u6d88\u606f\u56de\u9000\uff0c\u4e0a\u4f20\u7684\u6700\u5927 offset \u4e0d\u80fd\u8d85\u8fc7 confirm offset<\/li>\n<li>slave \u664b\u5347\u65f6\u5feb\u901f\u542f\u52a8\u591a\u7ea7\u5b58\u50a8\uff1a\u53ea\u6709 master \u8282\u70b9\u5177\u6709\u5199\u6743\u9650\uff0c\u5728 slave \u8282\u70b9\u664b\u5347\u540e\u9700\u8981\u5feb\u901f\u62c9\u8d77\u591a\u7ea7\u5b58\u50a8\u65ad\u70b9\u7eed\u4f20<\/li>\n<\/ol>\n<h3 id=\"\u9ad8\u7ea7\u6d88\u606f\u7c7b\u578b\">\u9ad8\u7ea7\u6d88\u606f\u7c7b\u578b<\/h3>\n<h4 id=\"\u4e8b\u52a1\u6d88\u606f\">\u4e8b\u52a1\u6d88\u606f<\/h4>\n<p>\u4e8b\u52a1\u534a\u6d88\u606f\u56de\u67e5\u7528\u5230\u4e86 commitLog offset\uff0c\u800c\u591a\u7ea7\u5b58\u50a8\u5bf9\u6d88\u606f\u7684 commitLog offset \u505a\u4e86\u91cd\u65b0\u6620\u5c04\u4f1a\u5bfc\u81f4\u517c\u5bb9\u95ee\u9898\u3002\u5f53\u524d\u9ed8\u8ba4\u7981\u6b62\u4e0a\u4f20\u4e8b\u52a1\u534a\u6d88\u606f topic <code>RMQ_SYS_TRANS_HALF_TOPIC<\/code> \u4e2d\u7684\u6d88\u606f\uff0c\u786e\u4fdd\u5176\u751f\u547d\u5468\u671f\u5c0f\u4e8e\u672c\u5730\u6d88\u606f\u4fdd\u7559\u65f6\u95f4<\/p>\n<h4 id=\"\u5b9a\u65f6\u6d88\u606f\">\u5b9a\u65f6\u6d88\u606f<\/h4>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u672c\u8282\u4e2d\u7684\u5b9a\u65f6\u6d88\u606f\u7279\u6307\u5728 <a class=\"link\" href=\"https:\/\/shimo.im\/docs\/gXqme9PKKpIeD7qo\/read\" target=\"_blank\" rel=\"noopener\"\n>RIP-43<\/a> \u4e2d\u5f15\u5165\u7684\u57fa\u4e8e\u65f6\u95f4\u8f6e\u7684\u5b9a\u65f6\u6d88\u606f\u5b9e\u73b0\n<\/div>\n<p><\/p>\n<p>\u4e3a\u4e86\u652f\u6301\u8d85\u8fc7\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u7684\u5b9a\u65f6\u65f6\u957f\uff0c\u57fa\u4e8e\u65f6\u95f4\u8f6e\u7684\u5b9a\u65f6\u6d88\u606f\u4f1a\u5728\u6309\u7167 <code>timerRollWindowSlots<\/code> \u914d\u7f6e\u6307\u5b9a\u7684\u65f6\u95f4\u6eda\u52a8\u5b9a\u65f6\u6d88\u606f\u3002\u6bd4\u5982 broker \u914d\u7f6e\u7684\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u4e3a 3 \u5929\uff0ctimerRollWindowSlots \u914d\u7f6e\u7684\u6eda\u52a8\u95f4\u9694\u4e3a 2 \u5929\uff0c\u6d88\u606f\u7684\u5b9a\u65f6\u65f6\u95f4\u4e3a 7 \u5929\uff0c\u90a3\u4e48\u6bcf\u9694\u4e24\u5929\u6d88\u606f\u4f1a\u91cd\u590d\u5199\u5165.\u6240\u4ee5\u53ea\u8981 <code>timerRollWindowSlots<\/code> \u914d\u7f6e\u7684\u65f6\u95f4\u5c0f\u4e8e\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u5373\u53ef<\/p>\n<p>\u4e3a\u4e86\u907f\u514d\u6d88\u606f\u9891\u7e41\u6eda\u52a8\u5e26\u6765\u7684\u5199\u653e\u5927\uff0c\u4e0b\u4e00\u6b65\u8ba1\u5212\u5728\u591a\u7ea7\u5b58\u50a8\u4e2d\u5b9e\u73b0\u591a\u7ea7\u65f6\u95f4\u8f6e\u673a\u5236\uff0c\u5373\u5c06\u5927\u4e8e\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u7684\u5b9a\u65f6\u6d88\u606f\u5199\u5165\u591a\u7ea7\u5b58\u50a8\u4e2d\uff0c\u5728\u6d88\u606f\u5b9a\u65f6\u5230\u671f\u65f6\u8bfb\u53d6\u56de\u672c\u5730\u5904\u7406<\/p>"},{"title":"RocketMQ \u53ef\u89c2\u6d4b\u6027\u4e4b Metrics","link":"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics","pubDate":"Tue, 15 Nov 2022 11:16:09 +0800","guid":"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/otel-collector.jpg\" alt=\"Featured image of post RocketMQ \u53ef\u89c2\u6d4b\u6027\u4e4b Metrics\" \/><h2 id=\"\u4ece\u6d88\u606f\u7684\u751f\u547d\u5468\u671f\u770b\u53ef\u89c2\u6d4b\u80fd\u529b\">\u4ece\u6d88\u606f\u7684\u751f\u547d\u5468\u671f\u770b\u53ef\u89c2\u6d4b\u80fd\u529b<\/h2>\n<p>\u5728\u8fdb\u5165\u4e3b\u9898\u4e4b\u524d\u5148\u6765\u770b\u4e00\u4e0b RocketMQ \u751f\u4ea7\u8005\u3001\u6d88\u8d39\u8005\u548c\u670d\u52a1\u7aef\u4ea4\u4e92\u7684\u6d41\u7a0b\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 259;\nflex-basis: 623px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/producer-consumer.jpg\" data-size=\"2410x927\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/producer-consumer.jpg\"\nwidth=\"2410\"\nheight=\"927\"\nloading=\"lazy\"\nalt=\"message produce and consume process\">\n<\/a>\n<figcaption>message produce and consume process<\/figcaption>\n<\/figure><\/p>\n<p>RocketMQ \u7684\u6d88\u606f\u662f\u6309\u7167\u961f\u5217\u7684\u65b9\u5f0f\u5206\u533a\u6709\u5e8f\u50a8\u5b58\u7684\uff0c\u8fd9\u79cd\u961f\u5217\u6a21\u578b\u4f7f\u5f97\u751f\u4ea7\u8005\u3001\u6d88\u8d39\u8005\u548c\u8bfb\u5199\u961f\u5217\u90fd\u662f\u591a\u5bf9\u591a\u7684\u6620\u5c04\u5173\u7cfb\uff0c\u5f7c\u6b64\u4e4b\u95f4\u53ef\u4ee5\u65e0\u9650\u6c34\u5e73\u6269\u5c55\u3002\u5bf9\u6bd4\u4f20\u7edf\u7684\u6d88\u606f\u961f\u5217\u5982 RabbitMQ \u662f\u5f88\u5927\u7684\u4f18\u52bf\uff0c\u5c24\u5176\u662f\u5728\u6d41\u5f0f\u5904\u7406\u573a\u666f\u4e0b\u80fd\u591f\u4fdd\u8bc1\u540c\u4e00\u961f\u5217\u7684\u6d88\u606f\u88ab\u76f8\u540c\u7684\u6d88\u8d39\u8005\u5904\u7406\uff0c\u5bf9\u4e8e\u6279\u91cf\u5904\u7406\u3001\u805a\u5408\u5904\u7406\u66f4\u53cb\u597d<\/p>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u6d88\u606f\u7684\u6574\u4e2a\u751f\u547d\u5468\u671f\u4e2d\u9700\u8981\u5173\u6ce8\u7684\u91cd\u8981\u8282\u70b9\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 329;\nflex-basis: 790px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/msg-life-cycle.jpg\" data-size=\"4026x1222\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/msg-life-cycle.jpg\"\nwidth=\"4026\"\nheight=\"1222\"\nloading=\"lazy\"\nalt=\"message life cycle\">\n<\/a>\n<figcaption>message life cycle<\/figcaption>\n<\/figure><\/p>\n<p>\u9996\u5148\u662f\u6d88\u606f\u53d1\u9001\uff1a\u53d1\u9001\u8017\u65f6\u662f\u6307\u4e00\u6761\u6d88\u606f\u4ece\u751f\u4ea7\u8005\u5f00\u59cb\u53d1\u9001\u5230\u670d\u52a1\u7aef\u63a5\u6536\u5230\u5e76\u50a8\u5b58\u5728\u786c\u76d8\u4e0a\u7684\u65f6\u95f4\u3002\u5982\u679c\u662f\u5b9a\u65f6\u6d88\u606f\uff0c\u9700\u8981\u5230\u8fbe\u6307\u5b9a\u7684\u5b9a\u65f6\u65f6\u95f4\u624d\u80fd\u88ab\u6d88\u8d39\u8005\u53ef\u89c1<\/p>\n<p>\u670d\u52a1\u7aef\u6536\u5230\u6d88\u606f\u540e\u9700\u8981\u6839\u636e\u6d88\u606f\u7c7b\u578b\u8fdb\u884c\u5904\u7406\uff0c\u5bf9\u4e8e\u5b9a\u65f6\/\u4e8b\u52a1\u6d88\u606f\u53ea\u6709\u5230\u4e86\u5b9a\u65f6\u65f6\u95f4\/\u4e8b\u52a1\u63d0\u4ea4\u624d\u5bf9\u6d88\u8d39\u8005\u53ef\u89c1\u3002RocketMQ \u63d0\u4f9b\u4e86\u6d88\u606f\u5806\u79ef\u7684\u7279\u6027\uff0c\u5373\u6d88\u606f\u53d1\u9001\u5230\u670d\u52a1\u7aef\u540e\u5e76\u4e0d\u4e00\u5b9a\u7acb\u5373\u88ab\u62c9\u53d6\uff0c\u53ef\u4ee5\u6309\u7167\u5ba2\u6237\u7aef\u7684\u6d88\u8d39\u80fd\u529b\u8fdb\u884c\u6295\u9012<\/p>\n<p>\u4ece\u6d88\u8d39\u8005\u7684\u89d2\u5ea6\u4e0a\u770b\uff0c\u6709\u4e09\u4e2a\u9700\u8981\u5173\u6ce8\u7684\u9636\u6bb5\uff1a<\/p>\n<ul>\n<li>\u62c9\u53d6\u6d88\u606f\uff1a\u6d88\u606f\u4ece\u5f00\u59cb\u62c9\u53d6\u5230\u62b5\u8fbe\u5ba2\u6237\u7aef\u7684\u7f51\u7edc\u548c\u670d\u52a1\u7aef\u5904\u7406\u8017\u65f6<\/li>\n<li>\u6d88\u606f\u6392\u961f\uff1a\u7b49\u5f85\u5904\u7406\u8d44\u6e90\uff0c\u5373\u4ece\u6d88\u606f\u62b5\u8fbe\u5ba2\u6237\u7aef\u5230\u5f00\u59cb\u5904\u7406\u6d88\u606f<\/li>\n<li>\u6d88\u606f\u6d88\u8d39\uff1a\u4ece\u5f00\u59cb\u5904\u7406\u6d88\u606f\u5230\u6700\u540e\u63d0\u4ea4\u4f4d\u70b9\/\u8fd4\u56de ACK<\/li>\n<\/ul>\n<p>\u6d88\u606f\u5728\u751f\u547d\u5468\u671f\u7684\u4efb\u4f55\u4e00\u4e2a\u9636\u6bb5\uff0c\u90fd\u53ef\u4ee5\u6e05\u6670\u5730\u88ab\u5b9a\u4e49\u5e76\u4e14\u88ab\u89c2\u6d4b\u5230\uff0c\u8fd9\u5c31\u662f RocketMQ \u53ef\u89c2\u6d4b\u7684\u6838\u5fc3\u7406\u5ff5\u3002\u800c\u672c\u6587\u8981\u4ecb\u7ecd\u7684 Metrics \u5c31\u8df5\u884c\u4e86\u8fd9\u79cd\u7406\u5ff5\uff0c\u63d0\u4f9b\u8986\u76d6\u6d88\u606f\u751f\u547d\u5468\u671f\u5404\u4e2a\u9636\u6bb5\u7684\u76d1\u63a7\u57cb\u70b9\u3002\u501f\u52a9 Metrics \u63d0\u4f9b\u7684\u539f\u5b50\u80fd\u529b\u6211\u4eec\u53ef\u4ee5\u642d\u5efa\u9002\u5408\u4e1a\u52a1\u9700\u8981\u7684\u76d1\u63a7\u7cfb\u7edf\uff1a<\/p>\n<ul>\n<li>\u65e5\u5e38\u5de1\u68c0\u4e0e\u76d1\u63a7\u9884\u8b66<\/li>\n<li>\u5b8f\u89c2\u8d8b\u52bf\/\u96c6\u7fa4\u5bb9\u91cf\u5206\u6790<\/li>\n<li>\u6545\u969c\u95ee\u9898\u8bca\u65ad<\/li>\n<\/ul>\n<h2 id=\"rocketmq-4x-metrics-\u5b9e\u73b0----exporter\">RocketMQ 4.x Metrics \u5b9e\u73b0 &ndash; Exporter<\/h2>\n<p>RocketMQ \u56e2\u961f\u8d21\u732e\u7684 RocketMQ exporter \u5df2\u88ab Prometheus \u5b98\u65b9\u7684\u5f00\u6e90 Exporter \u751f\u6001\u6240\u6536\u5f55\uff0c\u63d0\u4f9b\u4e86 Broker\u3001Producer\u3001Consumer \u5404\u4e2a\u9636\u6bb5\u4e30\u5bcc\u7684\u76d1\u63a7\u6307\u6807<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/exporter-metrics-spec.png\" width=\"563\" height=\"328\"\/><figcaption>\n<h4>exporter metrics spec<\/h4>\n<\/figcaption>\n<\/figure>\n<h3 id=\"exporter-\u539f\u7406\u89e3\u6790\">Exporter \u539f\u7406\u89e3\u6790<\/h3>\n<p>RocketMQ expoter \u83b7\u53d6\u76d1\u63a7\u6307\u6807\u7684\u6d41\u7a0b\u5982\u4e0b\u56fe\u6240\u793a\uff0cExpoter \u901a\u8fc7 MQAdminExt \u5411 RocketMQ \u96c6\u7fa4\u8bf7\u6c42\u6570\u636e\u3002\u83b7\u53d6\u7684\u6570\u636e\u8f6c\u6362\u6210 Prometheus \u9700\u8981\u7684\u683c\u5f0f\uff0c\u7136\u540e\u901a\u8fc7 \/metics \u63a5\u53e3\u66b4\u9732\u51fa\u6765<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/rocketmq-exporter.jpg\" width=\"629\" height=\"378\"\/><figcaption>\n<h4>rocketmq exporter<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u968f\u7740 RocketMQ \u7684\u6f14\u8fdb\uff0cexporter \u6a21\u5f0f\u9010\u6e10\u66b4\u9732\u51fa\u4e00\u4e9b\u7f3a\u9677\uff1a<\/p>\n<ul>\n<li>\u65e0\u6cd5\u652f\u6301 RocketMQ 5.x \u4e2d\u65b0\u52a0\u5165\u7684 Proxy \u7b49\u6a21\u5757\u7684\u53ef\u89c2\u6d4b\u9700\u6c42<\/li>\n<li>\u6307\u6807\u5b9a\u4e49\u4e0d\u7b26\u5408\u5f00\u6e90\u89c4\u8303\uff0c\u96be\u4ee5\u548c\u5176\u4ed6\u5f00\u6e90\u53ef\u89c2\u6d4b\u7ec4\u4ef6\u642d\u914d\u4f7f\u7528<\/li>\n<li>\u5927\u91cf RPC \u8c03\u7528\u7ed9 Broker \u5e26\u6765\u989d\u5916\u7684\u538b\u529b<\/li>\n<li>\u62d3\u5c55\u6027\u5dee\uff0c\u589e\u52a0\/\u4fee\u6539\u6307\u6807\u9700\u8981\u5148\u4fee\u6539 Broker \u7684 admin \u63a5\u53e3<\/li>\n<\/ul>\n<p>\u4e3a\u89e3\u51b3\u4ee5\u4e0a\u95ee\u9898\uff0cRocketMQ \u793e\u533a\u51b3\u5b9a\u62e5\u62b1\u793e\u533a\u6807\u51c6\uff0c\u5728 RocketMQ 5.x \u4e2d\u63a8\u51fa\u4e86\u57fa\u4e8e OpenTelemtry \u7684 Metrics \u65b9\u6848<\/p>\n<h2 id=\"rocketmq-5x-\u539f\u751f-metrics-\u5b9e\u73b0\">RocketMQ 5.x \u539f\u751f Metrics \u5b9e\u73b0<\/h2>\n<h3 id=\"\u57fa\u4e8e-opentelemtry-\u7684-metrics\">\u57fa\u4e8e OpenTelemtry \u7684 Metrics<\/h3>\n<p>OpenTelemetry \u662f CNCF \u7684\u4e00\u4e2a\u53ef\u89c2\u6d4b\u6027\u9879\u76ee\uff0c\u65e8\u5728\u63d0\u4f9b\u53ef\u89c2\u6d4b\u6027\u9886\u57df\u7684\u6807\u51c6\u5316\u65b9\u6848\uff0c\u89e3\u51b3\u89c2\u6d4b\u6570\u636e\u7684\u6570\u636e\u6a21\u578b\u3001\u91c7\u96c6\u3001\u5904\u7406\u3001\u5bfc\u51fa\u7b49\u7684\u6807\u51c6\u5316\u95ee\u9898\uff0c\u63d0\u4f9b\u4e0e\u4e09\u65b9 vendor \u65e0\u5173\u7684\u670d\u52a1<\/p>\n<p>\u5728\u8ba8\u8bba\u65b0\u7684 Metrics \u65b9\u6848\u65f6 RocketMQ \u793e\u533a\u51b3\u5b9a\u9075\u5b88 OpenTelemetry \u89c4\u8303\uff0c\u5b8c\u5168\u91cd\u65b0\u8bbe\u8ba1\u65b0 metrics \u7684\u6307\u6807\u5b9a\u4e49\uff1a\u6570\u636e\u7c7b\u578b\u9009\u7528\u517c\u5bb9 Promethues \u7684 Counter\u3001Guage\u3001Histogram\uff0c\u5e76\u4e14\u9075\u5faa Promethues \u63a8\u8350\u7684\u6307\u6807\u547d\u540d\u89c4\u8303\uff0c\u4e0d\u517c\u5bb9\u65e7\u6709\u7684 rocketmq-exporter \u6307\u6807\u3002\u65b0\u6307\u6807\u8986\u76d6 broker\u3001proxy\u3001producer\u3001consumer \u7b49\u5404\u4e2a module\uff0c\u5bf9\u6d88\u606f\u751f\u547d\u5468\u671f\u7684\u5168\u9636\u6bb5\u63d0\u4f9b\u76d1\u63a7\u80fd\u529b<\/p>\n<h3 id=\"\u6307\u6807\u4e0a\u62a5\u65b9\u5f0f\">\u6307\u6807\u4e0a\u62a5\u65b9\u5f0f<\/h3>\n<p>\u6211\u4eec\u63d0\u4f9b\u4e86\u4e09\u79cd\u6307\u6807\u4e0a\u62a5\u7684\u65b9\u5f0f\uff1a<\/p>\n<ul>\n<li>Pull \u6a21\u5f0f\uff1a\u9002\u5408\u81ea\u8fd0\u7ef4 K8s \u548c Promethues \u96c6\u7fa4\u7684\u7528\u6237<\/li>\n<li>Push \u6a21\u5f0f\uff1a\u9002\u5408\u5e0c\u671b\u5bf9 metrics \u6570\u636e\u505a\u540e\u5904\u7406\u6216\u63a5\u5165\u4e91\u5382\u5546\u7684\u53ef\u89c2\u6d4b\u670d\u52a1\u7684\u7528\u6237<\/li>\n<li>Exporter \u517c\u5bb9\u6a21\u5f0f\uff1a\u9002\u5408\u5df2\u7ecf\u5728\u4f7f\u7528 Exporter \u548c\u6709\u8de8\u6570\u636e\u4e2d\u5fc3\uff08\u6216\u5176\u4ed6\u7f51\u7edc\u9694\u79bb\u73af\u5883\uff09\u4f20\u8f93 metrics \u6570\u636e\u9700\u6c42\u7684\u7528\u6237<\/li>\n<\/ul>\n<h4 id=\"pull\">Pull<\/h4>\n<p>Pull \u6a21\u5f0f\u65e8\u5728\u4e0e Prometheus \u517c\u5bb9\u3002\u5728 K8s \u90e8\u7f72\u73af\u5883\u4e2d\u65e0\u9700\u90e8\u7f72\u989d\u5916\u7684\u7ec4\u4ef6\uff0cprometheus \u53ef\u4ee5\u901a\u8fc7\u793e\u533a\u63d0\u4f9b\u7684 K8s \u670d\u52a1\u53d1\u73b0\u673a\u5236\uff08\u521b\u5efa PodMonitor\u3001ServiceMonitor CDR\uff09\u81ea\u52a8\u83b7\u53d6\u8981\u62c9\u53d6\u7684 broker\/proxy \u5217\u8868\uff0c\u5e76\u4ece\u4ed6\u4eec\u63d0\u4f9b\u7684 endpoint \u4e2d\u62c9\u53d6 metrics \u6570\u636e<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/pull-mode.jpg\" width=\"551\" height=\"472\"\/><figcaption>\n<h4>pull mode<\/h4>\n<\/figcaption>\n<\/figure>\n<h4 id=\"push\">Push<\/h4>\n<p>OpenTelemetry \u63a8\u8350\u4f7f\u7528 Push \u6a21\u5f0f\uff0c\u8fd9\u610f\u5473\u7740\u5b83\u9700\u8981\u90e8\u7f72\u4e00\u4e2a collector \u6765\u4f20\u8f93\u6307\u6807\u6570\u636e<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/push-mode.jpg\" width=\"583\" height=\"444\"\/><figcaption>\n<h4>push mode<\/h4>\n<\/figcaption>\n<\/figure>\n<p>OpenTelemetry \u5b98\u65b9\u63d0\u4f9b\u4e86 collector \u7684\u5b9e\u73b0\uff0c\u652f\u6301\u5bf9\u6307\u6807\u505a\u81ea\u5b9a\u4e49\u64cd\u4f5c\u5982\u8fc7\u6ee4\u3001\u5bcc\u5316\uff0c\u53ef\u4ee5\u5229\u7528\u793e\u533a\u63d0\u4f9b\u7684\u63d2\u4ef6\u5b9e\u73b0\u81ea\u5df1\u7684 collector\u3002\u5e76\u4e14\u4e91\u5382\u5546\u63d0\u4f9b\u7684\u53ef\u89c2\u6d4b\u670d\u52a1\uff08\u5982 AWS CloudWatch\u3001\u963f\u91cc\u4e91 SLS\uff09\u5927\u591a\u5df2\u7ecf\u62e5\u62b1\u4e86 OpenTelemetry \u793e\u533a\uff0c\u53ef\u4ee5\u76f4\u63a5\u5c06\u6570\u636e\u63a8\u9001\u5230\u5b83\u4eec\u63d0\u4f9b\u7684 collector \u4e2d\uff0c\u65e0\u9700\u989d\u5916\u7684\u7ec4\u4ef6\u8fdb\u884c\u6865\u63a5<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/otel-collector.jpg\" width=\"919\" height=\"513\"\/><figcaption>\n<h4>OpenTelemetry collector<\/h4>\n<\/figcaption>\n<\/figure>\n<h4 id=\"\u517c\u5bb9-rocketmq-exporter\">\u517c\u5bb9 RocketMQ Exporter<\/h4>\n<p>\u65b0\u7684 Metrics \u4e5f\u63d0\u4f9b\u5bf9 RocketMQ Exporter \u7684\u517c\u5bb9\uff0c\u73b0\u5728\u4f7f\u7528 exporter \u7684\u7528\u6237\u65e0\u9700\u53d8\u66f4\u90e8\u7f72\u67b6\u6784\u5373\u53ef\u63a5\u5165\u65b0 Metrics\u3002\u800c\u4e14\u63a7\u5236\u9762\u5e94\u7528\uff08\u5982 Promethues\uff09\u548c\u6570\u636e\u9762\u5e94\u7528\uff08\u5982 RocketMQ\uff09\u6709\u53ef\u80fd\u9694\u79bb\u90e8\u7f72\u3002\u56e0\u6b64\u501f\u52a9 Exporter \u4f5c\u4e3a\u4ee3\u7406\u6765\u83b7\u53d6\u65b0\u7684 Metrics \u6570\u636e\u4e5f\u4e0d\u5931\u4e3a\u4e00\u79cd\u597d\u7684\u9009\u62e9<\/p>\n<p>RocketMQ \u793e\u533a\u5728 Exporter \u4e2d\u5d4c\u5165\u4e86\u4e00\u4e2a OpenTelemetry collector \u5b9e\u73b0\uff0cBroker \u5c06 Metrics \u6570\u636e\u5bfc\u51fa\u5230 Exporter\uff0cExporter \u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b0\u7684 endpoint\uff08\u4e0b\u56fe\u4e2d\u7684 metrics-v2\uff09\u4f9b Prometheus \u62c9\u53d6<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/exporter-mode.jpg\" width=\"767\" height=\"447\"\/><figcaption>\n<h4>exporter mode<\/h4>\n<\/figcaption>\n<\/figure>\n<h2 id=\"\u6784\u5efa\u76d1\u63a7\u4f53\u7cfb\u6700\u4f73\u5b9e\u8df5\">\u6784\u5efa\u76d1\u63a7\u4f53\u7cfb\u6700\u4f73\u5b9e\u8df5<\/h2>\n<p>\u4e30\u5bcc\u7684\u6307\u6807\u8986\u76d6\u4e0e\u5bf9\u793e\u533a\u6807\u51c6\u7684\u9075\u5faa\u4f7f\u5f97\u53ef\u4ee5\u8f7b\u800c\u6613\u4e3e\u7684\u501f\u52a9 RocketMQ \u7684 Metrics \u80fd\u529b\u6784\u5efa\u51fa\u9002\u5408\u4e1a\u52a1\u9700\u6c42\u7684\u76d1\u63a7\u4f53\u7cfb\uff0c\u8fd9\u4e2a\u7ae0\u8282\u4e3b\u8981\u4ee5\u4e00\u4e2a\u5178\u578b\u7684\u6d41\u7a0b\u4ecb\u7ecd\u6784\u5efa\u76d1\u63a7\u4f53\u7cfb\u7684\u6700\u4f73\u5b9e\u8df5\uff1a<\/p>\n<p>\u96c6\u7fa4\u76d1\u63a7\/\u5de1\u68c0 -&gt; \u89e6\u53d1\u544a\u8b66 -&gt; \u6392\u67e5\u5206\u6790<\/p>\n<h3 id=\"\u96c6\u7fa4\u72b6\u6001\u76d1\u63a7\u4e0e\u5de1\u68c0\">\u96c6\u7fa4\u72b6\u6001\u76d1\u63a7\u4e0e\u5de1\u68c0<\/h3>\n<p>\u6211\u4eec\u5c06\u6307\u6807\u91c7\u96c6\u5230 Promethues \u540e\u5c31\u53ef\u4ee5\u57fa\u4e8e\u8fd9\u4e9b\u6307\u6807\u914d\u7f6e\u76d1\u63a7\uff0c\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e9b\u793a\u4f8b\uff1a<\/p>\n<p>\u63a5\u53e3\u76d1\u63a7\uff1a<br \/>\n\u76d1\u63a7\u63a5\u53e3\u8c03\u7528\u60c5\u51b5\uff0c\u53ef\u4ee5\u636e\u6b64\u5feb\u901f\u6293\u51fa\u5f02\u5e38\u7684\u8bf7\u6c42\u5bf9\u75c7\u4e0b\u836f<br \/>\n\u4e0b\u56fe\u7ed9\u51fa\u4e00\u4e9b\u76f8\u5173\u793a\u4f8b\uff1a\u6240\u6709 RPC \u7684\u8017\u65f6\uff08avg\u3001pt90\u3001pt99 \u7b49\uff09\u3001\u6210\u529f\u7387\u3001\u5931\u8d25\u539f\u56e0\u3001\u63a5\u53e3\u8c03\u7528\u4e0e\u8fd4\u56de\u503c\u5206\u5e03\u60c5\u51b5\u7b49<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 406;\nflex-basis: 976px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/rpc-metrics.jpg\" data-size=\"4962x1220\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/rpc-metrics.jpg\"\nwidth=\"4962\"\nheight=\"1220\"\nloading=\"lazy\"\nalt=\"rpc metrics\">\n<\/a>\n<figcaption>rpc metrics<\/figcaption>\n<\/figure><\/p>\n<p>\u5ba2\u6237\u7aef\u76d1\u63a7\uff1a<br \/>\n\u76d1\u63a7\u5ba2\u6237\u7aef\u7684\u4f7f\u7528\u60c5\u51b5\uff0c\u53d1\u73b0\u975e\u9884\u671f\u7684\u5ba2\u6237\u7aef\u4f7f\u7528\u5982\u8d85\u5927\u6d88\u606f\u53d1\u9001\u3001\u5ba2\u6237\u7aef\u4e0a\u4e0b\u7ebf\u3001\u5ba2\u6237\u7aef\u7248\u672c\u6cbb\u7406\u7b49<br \/>\n\u4e0b\u56fe\u7ed9\u51fa\u4e00\u4e9b\u76f8\u5173\u793a\u4f8b\uff1a\u5ba2\u6237\u7aef\u8fde\u63a5\u6570\u3001\u5ba2\u6237\u7aef\u8bed\u8a00\/\u7248\u672c\u5206\u5e03\u3001\u53d1\u9001\u7684\u6d88\u606f\u5927\u5c0f\/\u7c7b\u578b\u5206\u5e03<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 326;\nflex-basis: 784px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/client-metrics.jpg\" data-size=\"4976x1522\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/client-metrics.jpg\"\nwidth=\"4976\"\nheight=\"1522\"\nloading=\"lazy\"\nalt=\"client metrics\">\n<\/a>\n<figcaption>client metrics<\/figcaption>\n<\/figure><\/p>\n<p>Broker \u76d1\u63a7\uff1a<br \/>\n\u76d1\u63a7 Broker \u7684\u6c34\u4f4d\u548c\u670d\u52a1\u8d28\u91cf\uff0c\u53ca\u65f6\u53d1\u73b0\u96c6\u7fa4\u5bb9\u91cf\u74f6\u9888<br \/>\n\u4e0b\u56fe\u7ed9\u51fa\u4e00\u4e9b\u76f8\u5173\u793a\u4f8b\uff1aDispatch \u5ef6\u8fdf\u3001\u6d88\u606f\u4fdd\u7559\u65f6\u95f4\u3001\u7ebf\u7a0b\u6c60\u6392\u961f\u3001\u6d88\u606f\u5806\u79ef\u60c5\u51b5<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 404;\nflex-basis: 971px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/broker-metrics.jpg\" data-size=\"4956x1224\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/broker-metrics.jpg\"\nwidth=\"4956\"\nheight=\"1224\"\nloading=\"lazy\"\nalt=\"broker metrics\">\n<\/a>\n<figcaption>broker metrics<\/figcaption>\n<\/figure><\/p>\n<p>\u4ee5\u4e0a\u7684\u793a\u4f8b\u53ea\u662f Metrics \u7684\u51b0\u5c71\u4e00\u89d2\uff0c\u9700\u8981\u6839\u636e\u4e1a\u52a1\u9700\u8981\u7075\u6d3b\u7ec4\u5408\u4e0d\u540c\u7684\u6307\u6807\u914d\u7f6e\u76d1\u63a7\u4e0e\u5de1\u68c0<\/p>\n<h3 id=\"\u544a\u8b66\u914d\u7f6e\">\u544a\u8b66\u914d\u7f6e<\/h3>\n<p>\u6709\u4e86\u5b8c\u5584\u7684\u76d1\u63a7\u5c31\u53ef\u4ee5\u5bf9\u9700\u8981\u5173\u6ce8\u7684\u6307\u6807\u914d\u7f6e\u544a\u8b66\uff0c\u6bd4\u5982\u53ef\u4ee5\u914d\u7f6e Broker \u76d1\u63a7\u4e2d Dispatch \u5ef6\u8fdf\u8fd9\u4e2a\u6307\u6807\u7684\u544a\u8b66\uff1a<\/p>\n<figure><img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/broker-alert.jpg\" width=\"440\" height=\"726\"\/><figcaption>\n<h4>broker alert<\/h4>\n<\/figcaption>\n<\/figure>\n<p>\u6536\u5230\u544a\u8b66\u540e\u53ef\u4ee5\u8054\u52a8\u76d1\u63a7\u67e5\u770b\u5177\u4f53\u539f\u56e0\uff0c\u5173\u8054\u53d1\u9001\u63a5\u53e3\u7684\u5931\u8d25\u7387\u53ef\u4ee5\u53d1\u73b0\u6709 1.7% \u7684\u6d88\u8d39\u53d1\u9001\u5931\u8d25\uff0c\u5bf9\u5e94\u7684\u62a5\u9519\u662f\u6ca1\u6709\u521b\u5efa\u8ba2\u9605\u7ec4\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 402;\nflex-basis: 966px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/problem-analysis.jpg\" data-size=\"2416x600\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/problem-analysis.jpg\"\nwidth=\"2416\"\nheight=\"600\"\nloading=\"lazy\"\nalt=\"promblem analysis\">\n<\/a>\n<figcaption>promblem analysis<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"\u95ee\u9898\u6392\u67e5\u5206\u6790\">\u95ee\u9898\u6392\u67e5\u5206\u6790<\/h3>\n<p>\u6700\u540e\u4ee5\u6d88\u606f\u5806\u79ef\u8fd9\u4e2a\u573a\u666f\u4e3a\u4f8b\u6765\u770b\u4e00\u4e0b\u5982\u4f55\u57fa\u4e8e Metrics \u5206\u6790\u7ebf\u4e0a\u95ee\u9898<\/p>\n<h4 id=\"\u4ece\u6d88\u606f\u751f\u547d\u5468\u671f\u770b\u5806\u79ef\u95ee\u9898\">\u4ece\u6d88\u606f\u751f\u547d\u5468\u671f\u770b\u5806\u79ef\u95ee\u9898<\/h4>\n<p>\u6b63\u5982\u672c\u6587\u5f00\u7bc7\u6240\u8ff0\uff0c\u6392\u67e5 RocketMQ \u7684\u95ee\u9898\u9700\u8981\u7ed3\u5408\u6d88\u606f\u7684\u751f\u547d\u5468\u671f\u7efc\u5408\u5206\u6790\uff0c\u5982\u679c\u7247\u9762\u7684\u8ba4\u5b9a\u662f\u670d\u52a1\u7aef\/\u5ba2\u6237\u7aef\u7684\u6545\u969c\u672a\u514d\u4f1a\u8bef\u5165\u6b67\u9014<\/p>\n<p>\u5bf9\u4e8e\u5806\u79ef\u95ee\u9898\uff0c\u6211\u4eec\u4e3b\u8981\u5173\u6ce8\u6d88\u606f\u751f\u547d\u5468\u671f\u4e2d\u7684\u4e24\u4e2a\u9636\u6bb5\uff1a<\/p>\n<ul>\n<li>\u5c31\u7eea\u6d88\u606f\uff1a\u5c31\u7eea\u6d88\u606f\u662f\u53ef\u4f9b\u6d88\u8d39\u4f46\u8fd8\u672a\u88ab\u62c9\u53d6\u7684\u6d88\u606f\uff0c\u5373\u5728\u670d\u52a1\u7aef\u5806\u79ef\u7684\u6d88\u606f<\/li>\n<li>\u5904\u7406\u4e2d\u6d88\u606f\uff1a\u5904\u7406\u4e2d\u7684\u6d88\u606f\u662f\u88ab\u5ba2\u6237\u7aef\u62c9\u53d6\u4f46\u662f\u8fd8\u672a\u88ab\u6d88\u8d39\u7684\u6d88\u606f<\/li>\n<\/ul>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 256;\nflex-basis: 614px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/consume-lag.jpg\" data-size=\"2008x784\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-observability-metrics\/consume-lag.jpg\"\nwidth=\"2008\"\nheight=\"784\"\nloading=\"lazy\"\nalt=\"consume lag\">\n<\/a>\n<figcaption>consume lag<\/figcaption>\n<\/figure><\/p>\n<h4 id=\"\u591a\u7ef4\u5ea6\u6307\u6807\u5206\u6790\u5806\u79ef\u95ee\u9898\">\u591a\u7ef4\u5ea6\u6307\u6807\u5206\u6790\u5806\u79ef\u95ee\u9898<\/h4>\n<p>\u5bf9\u4e8e\u5806\u79ef\u95ee\u9898\uff0cRocketMQ \u63d0\u4f9b\u4e86\u6d88\u8d39\u5ef6\u8fdf\u76f8\u5173\u6307\u6807 <code>rocketmq_consumer_lag_latency<\/code> \u53ef\u4ee5\u57fa\u4e8e\u8fd9\u4e2a\u6307\u6807\u914d\u7f6e\u544a\u8b66\u3002\u544a\u8b66\u7684\u9608\u503c\u9700\u8981\u6839\u636e\u5f53\u524d\u4e1a\u52a1\u5bf9\u6d88\u8d39\u5ef6\u8fdf\u7684\u5bb9\u5fcd\u7a0b\u5ea6\u7075\u6d3b\u6307\u5b9a<\/p>\n<p>\u89e6\u53d1\u544a\u8b66\u540e\u5c31\u9700\u8981\u5bf9\u6d88\u606f\u5806\u79ef\u5728\u8fd8\u662f\u5c31\u7eea\u6d88\u606f\u548c\u5904\u7406\u4e2d\u6d88\u606f\u8fdb\u884c\u5206\u6790\uff0cRocketMQ \u63d0\u4f9b\u4e86 <code>rocketmq_consumer_ready_messages<\/code> \u548c <code>rocketmq_consumer_inflight_messages<\/code> \u8fd9\u4e24\u4e2a\u6307\u6807\uff0c\u7ed3\u5408\u5176\u4ed6\u6d88\u8d39\u76f8\u5173\u6307\u6807\u4e0e\u5ba2\u6237\u7aef\u914d\u7f6e\u7efc\u5408\u5206\u6790\u5373\u53ef\u5224\u65ad\u51fa\u6d88\u606f\u5806\u79ef\u7684\u6839\u56e0\uff1a<\/p>\n<ul>\n<li>case 1\uff1a\u5c31\u7eea\u6d88\u606f\u6301\u7eed\u4e0a\u6da8\uff0c\u5904\u7406\u4e2d\u6d88\u606f\u8fbe\u5230\u5ba2\u6237\u7aef\u5806\u79ef\u4e0a\u9650<\/li>\n<\/ul>\n<p>\u8fd9\u662f\u6700\u5e38\u89c1\u7684\u5806\u79ef\u573a\u666f\uff0c\u5ba2\u6237\u7aef\u5904\u7406\u4e2d\u7684\u6d88\u606f\u91cf <code>rocketmq_consumer_inflight_messages<\/code> \u8fbe\u5230\u4e86\u5ba2\u6237\u7aef\u914d\u7f6e\u7684\u9608\u503c\uff0c\u5373\u6d88\u8d39\u8005\u7684\u6d88\u8d39\u80fd\u529b\u4f4e\u4e8e\u6d88\u606f\u53d1\u9001\u91cf\u3002\u5982\u679c\u4e1a\u52a1\u8981\u6c42\u5c3d\u53ef\u80fd\u5b9e\u65f6\u7684\u6d88\u8d39\u6d88\u606f\u5c31\u9700\u8981\u589e\u52a0\u6d88\u8d39\u8005\u673a\u5668\u6570\u91cf\uff0c\u5982\u679c\u4e1a\u52a1\u5bf9\u6d88\u606f\u5ef6\u8fdf\u4e0d\u662f\u5f88\u654f\u611f\u53ef\u4ee5\u7b49\u5f85\u4e1a\u52a1\u9ad8\u5cf0\u8fc7\u53bb\u540e\u518d\u6d88\u5316\u5806\u79ef\u7684\u6d88\u606f<\/p>\n<ul>\n<li>case 2\uff1a\u5c31\u7eea\u6d88\u606f\u51e0\u4e4e\u4e3a 0\uff0c\u5904\u7406\u4e2d\u6d88\u606f\u6301\u7eed\u4e0a\u6da8<\/li>\n<\/ul>\n<p>\u8fd9\u4e2a case \u591a\u51fa\u73b0\u5728\u4f7f\u7528 RocketMQ 4.x \u5ba2\u6237\u7aef\u7684\u573a\u666f\uff0c\u6b64\u65f6\u6d88\u8d39\u4f4d\u70b9\u662f\u987a\u5e8f\u63d0\u4ea4\u7684\uff0c\u5982\u679c\u67d0\u6761\u6d88\u606f\u7684\u6d88\u8d39\u5361\u4f4f\u4f1a\u5bfc\u81f4\u4f4d\u70b9\u65e0\u6cd5\u63d0\u4ea4\u3002\u770b\u8d77\u6765\u7684\u73b0\u8c61\u662f\u6d88\u606f\u5728\u5ba2\u6237\u7aef\u5927\u91cf\u5806\u79ef\uff0c\u5373\u5904\u7406\u4e2d\u6d88\u606f\u6301\u7eed\u4e0a\u6da8\u3002\u53ef\u4ee5\u7ed3\u5408\u6d88\u8d39\u8f68\u8ff9\u548c <code>rocketmq_process_time<\/code> \u8fd9\u4e2a\u6307\u6807\u6293\u51fa\u6d88\u8d39\u6162\u7684\u6d88\u606f\u5206\u6790\u4e0a\u4e0b\u6e38\u94fe\u8def\uff0c\u627e\u5230\u6839\u56e0\u4f18\u5316\u6d88\u8d39\u903b\u8f91<\/p>\n<ul>\n<li>case 3: \u5c31\u7eea\u6d88\u606f\u6301\u7eed\u4e0a\u6da8\uff0c\u5904\u7406\u4e2d\u6d88\u606f\u51e0\u4e4e\u4e3a 0<\/li>\n<\/ul>\n<p>\u6b64\u79cd\u573a\u666f\u8bf4\u660e\u5ba2\u6237\u7aef\u6ca1\u6709\u62c9\u53d6\u5230\u6d88\u606f\uff0c\u4e00\u822c\u6709\u5982\u4e0b\u51e0\u79cd\u60c5\u51b5\uff1a<\/p>\n<ul>\n<li>\u9274\u6743\u95ee\u9898\uff1a\u68c0\u67e5 ACL \u914d\u7f6e\uff0c\u5982\u679c\u4f7f\u7528\u516c\u6709\u4e91\u4ea7\u54c1\u8bf7\u68c0\u67e5 AK\u3001SK \u914d\u7f6e<\/li>\n<li>\u6d88\u8d39\u8005 hang \u4f4f\uff1a\u5c1d\u8bd5\u6253\u5370\u7ebf\u7a0b\u5806\u6808\u6216 gc \u4fe1\u606f\u5224\u65ad\u662f\u5426\u662f\u8fdb\u7a0b\u5361\u6b7b<\/li>\n<li>\u670d\u52a1\u7aef\u54cd\u5e94\u6162\uff1a\u7ed3\u5408 RPC \u76f8\u5173\u6307\u6807\u67e5\u770b\u62c9\u53d6\u6d88\u606f\u63a5\u53e3\u8c03\u7528\u91cf\u4e0e\u8017\u65f6\u3001\u786c\u76d8\u8bfb\u5199\u5ef6\u8fdf\u3002\u68c0\u67e5\u662f\u5426\u4e3a\u670d\u52a1\u7aef\u95ee\u9898\uff0c\u5982\u786c\u76d8 IOPS \u88ab\u6253\u6ee1\u4e86\u7b49\u7b49<\/li>\n<\/ul>"},{"title":"\u4f7f\u7528 K3s \u642d\u5efa\u57fa\u4e8e Kubernetes \u73af\u5883\u7684 HomeLab","link":"https:\/\/blog.lv5.moe\/p\/use-k3s-to-build-homelab-based-on-kubernetes","pubDate":"Mon, 07 Nov 2022 15:42:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/use-k3s-to-build-homelab-based-on-kubernetes","description":"<p>\u535a\u4e3b\u5728\u548c\u670b\u53cb\u642d\u5efa\u6e38\u620f\u79c1\u670d\u7684\u65f6\u5019\u4e0d\u5e78\u5c06\u5bb6\u91cc\u7684\u865a\u62df\u5316\u5e73\u53f0\u641e\u6302\u4e86\uff08\u8bba\u5907\u4efd\u7684\u91cd\u8981\u6027\uff09\u6b63\u597d\u6700\u8fd1\u6709\u7528 Kubernetes \u7684\u9700\u6c42\uff0c\u5c31\u628a HomeLab \u505a\u4e00\u6b21\u67b6\u6784\u5347\u7ea7\uff0c\u6c34\u4e00\u7bc7\u6587\u7ae0\u8bb0\u5f55\u4e0b\u8fd9\u6b21\u5ba2\u4e32 SRE \u7684\u7ecf\u9a8c\u548c\u8e29\u8fc7\u7684\u5751<\/p>\n<p>\u6280\u672f\u9009\u578b\uff1a K3s\uff08Kubernetes\uff09 + Rancher\uff08Kubernetes Dashboard\uff09 + Traefik\uff08Gateway\uff09<\/p>\n<h2 id=\"\u5b89\u88c5-k3s\">\u5b89\u88c5 K3s<\/h2>\n<p>K3s \u662f\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u7684 Kubernetes \u53d1\u884c\u7248\uff0c\u53ea\u9700\u8981\u4e00\u884c\u547d\u4ee4\u5373\u53ef\u5b89\u88c5\u5b8c\u6574\u7684 Kubernetes \u73af\u5883<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">curl -sfL https:\/\/get.k3s.io <span class=\"p\">|<\/span> sh -s - server\n<\/span><\/span><\/code><\/pre><\/div><p>\u5b89\u88c5\u597d\u7684 K3s \u670d\u52a1\u7aef\u53ea\u6709\u4e00\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u901a\u8fc7 k3s server \u6216 k3s agent \u542f\u52a8<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">root@k3s-server:~# ls \/usr\/local\/bin\/\n<\/span><\/span><span class=\"line\"><span class=\"cl\">crictl ctr k3s k3s-killall.sh k3s-uninstall.sh kubectl\n<\/span><\/span><\/code><\/pre><\/div><p>K3s \u5360\u7528\u7684\u8d44\u6e90\u4e5f\u5f88\u4f4e\uff0c\u53ea\u9700 1 \u6838 CPU \u548c 512M \u5185\u5b58\u5373\u53ef\u8dd1\u8d77\u6765\uff0c\u8be6\u7ec6\u5206\u6790\u89c1\u5b98\u65b9\u6587\u6863\uff1a<a class=\"link\" href=\"https:\/\/docs.k3s.io\/installation\/requirements\" target=\"_blank\" rel=\"noopener\"\n>\u6700\u4f4e\u9700\u6c42<\/a> \u548c <a class=\"link\" href=\"https:\/\/docs.k3s.io\/reference\/resource-profiling\" target=\"_blank\" rel=\"noopener\"\n>\u8d44\u6e90\u5206\u6790<\/a><\/p>\n<h3 id=\"\u5b89\u88c5-k3s-server\">\u5b89\u88c5 K3s Server<\/h3>\n<p>Kubernetes \u7531 Master \u548c Worker \u8282\u70b9\u7ec4\u6210\uff0c\u5bf9\u5e94 K3s \u7684 server \u548c agent\uff0c\u5373\u9700\u8981\u5728\u4e00\u53f0\u673a\u5668\u4e0a\u5b89\u88c5 K3s Server \u4f5c\u4e3a Master Node\uff0c\u5176\u4ed6\u673a\u5668\u4e0a\u5b89\u88c5 K3s Agent \u4f5c\u4e3a Worker Node<\/p>\n<p>\u540e\u7eed\u4f1a\u5b89\u88c5 Rancher \u6765\u7ba1\u7406 K3s\uff0c\u6240\u4ee5\u8fd9\u91cc\u9700\u8981\u4f7f\u7528\u53d7\u652f\u6301\u7684 K3s \u7248\u672c\u3002\u53ef\u4ee5\u4ece<a class=\"link\" href=\"https:\/\/rancher.com\/support-maintenance-terms\/\" target=\"_blank\" rel=\"noopener\"\n>Rancher \u6587\u6863<\/a>\u4e2d\u627e\u5230 Rancher \u652f\u6301\u7684 Kubernetes \u7248\u672c\u5217\u8868<\/p>\n<p>\u7136\u540e\u4f7f\u7528\u73af\u5883\u53d8\u91cf INSTALL_K3S_VERSION \u6765\u5b89\u88c5\u6307\u5b9a\u7248\u672c\u7684 K3s server<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">curl -sfL https:\/\/get.k3s.io <span class=\"p\">|<\/span> <span class=\"nv\">INSTALL_K3S_VERSION<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;***&#34;<\/span> sh -s - server\n<\/span><\/span><\/code><\/pre><\/div><p>\u5b89\u88c5\u5b8c\u6210\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528 kubectl \u6765\u67e5\u770b K3s \u96c6\u7fa4\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~# kubectl get node\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME STATUS ROLES AGE VERSION\n<\/span><\/span><span class=\"line\"><span class=\"cl\">k3s-server Ready control-plane,master 4d4h v1.24.7+k3s1\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5b89\u88c5 K3s \u4f1a\u9644\u5e26 csictl \u548c kubectl\uff0c\u524d\u8005\u53ef\u4ee5\u7ba1\u7406 Node \u4e0a\u7684\u955c\u50cf\u548c\u5bb9\u5668\uff1b\u540e\u8005\u5e94\u8be5\u65e0\u9700\u591a\u4ecb\u7ecd\u4e86\uff0c\u9ed8\u8ba4\u4f7f\u7528\u7684 kubeconfig \u4e3a <code>\/etc\/rancher\/k3s\/k3s.yaml<\/code>\n<\/div>\n<p><\/p>\n<h3 id=\"\u5b89\u88c5-k3s-agent\">\u5b89\u88c5 K3s Agent<\/h3>\n<p>K3s agent \u7684\u5b89\u88c5\u4e5f\u5341\u5206\u7b80\u5355\uff0c\u53bb\u6389\u4e0a\u8ff0\u5b89\u88c5\u547d\u4ee4\u4e2d\u7684 server \u53c2\u6570\u5373\u53ef<\/p>\n<p>\u6b64\u5916\uff0c\u8fd8\u9700\u8981\u4e24\u4e2a\u989d\u5916\u7684\u73af\u5883\u53d8\u91cf\u6765\u6307\u5b9a K3s agent \u5982\u4f55\u8fde\u63a5\u5230 server\uff1a<\/p>\n<ul>\n<li>K3S_URL\uff1aK3s server \u63d0\u4f9b\u7684 API server \u5730\u5740\uff0c\u9ed8\u8ba4\u4e3a https:\/\/server-ip:6443<\/li>\n<li>K3S_TOKEN\uff1aK3s server \u5b89\u88c5\u65f6\u6307\u5b9a\u6216\u751f\u6210\u7684 token\uff1a\u9ed8\u8ba4\u5728 \/var\/lib\/rancher\/k3s\/server\/node-token<\/li>\n<\/ul>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">curl -sfL https:\/\/get.k3s.io <span class=\"p\">|<\/span> <span class=\"nv\">INSTALL_K3S_VERSION<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;***&#34;<\/span> <span class=\"nv\">K3S_URL<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;api-server-url&#34;<\/span> <span class=\"nv\">K3S_TOKEN<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;server-token&#34;<\/span> sh -\n<\/span><\/span><\/code><\/pre><\/div><p>\u5b89\u88c5\u5b8c\u6210\u540e\u518d\u6765\u770b\u4e00\u4e0b Node \u5217\u8868\uff0c\u53ef\u4ee5\u53d1\u73b0 worker \u8282\u70b9\u5df2\u7ecf\u6dfb\u52a0\u5230\u96c6\u7fa4\u4e2d\u4e86<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~# kubectl get node\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME STATUS ROLES AGE VERSION\n<\/span><\/span><span class=\"line\"><span class=\"cl\">k3s-server Ready control-plane,master 1m v1.24.7+k3s1\n<\/span><\/span><span class=\"line\"><span class=\"cl\">k3s-worker-0 Ready &lt;none&gt; 1m v1.24.7+k3s1\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u5b89\u88c5-rancher\">\u5b89\u88c5 Rancher<\/h2>\n<p>Rancher \u662f\u4e00\u4e2a\u5e2e\u4f60\u7ba1\u7406 K3s \u96c6\u7fa4\u4e2d\u7684\u5404\u79cd\u8d44\u6e90\u7684 dashboard\uff0c\u529f\u80fd\u5341\u5206\u4e30\u5bcc\u4f46\u662f\u5360\u7528\u7684\u8d44\u6e90\u4e5f\u6bd4\u8f83\u591a\u3002\u5982\u679c\u4f60\u53ea\u60f3\u8981\u4e00\u4e2a\u8f7b\u91cf\u7684 Kubernetes dashboard \u6765\u6d4f\u89c8\u8d44\u6e90\u53ef\u4ee5\u7565\u8fc7\u672c\u8282\u5e76\u53c2\u8003\u8fd9\u7bc7\u6587\u6863 <a class=\"link\" href=\"https:\/\/docs.k3s.io\/installation\/kube-dashboard\" target=\"_blank\" rel=\"noopener\"\n>Configure the Kubernetes Dashboard on K3s<\/a><\/p>\n<p>Rancher \u53ef\u4ee5\u5728 Docker \u6216\u8005 Kubernetes \u4e2d\u5b89\u88c5\uff0c\u6211\u4eec\u8fd9\u91cc\u4ecb\u7ecd\u4f7f\u7528 Helm \u5c06 Rancher \u5b89\u88c5\u5230\u4e0a\u9762\u521b\u5efa\u597d\u7684 K3s \u96c6\u7fa4\u4e2d<\/p>\n<h3 id=\"\u5b89\u88c5-cert-manager\">\u5b89\u88c5 cert-manager<\/h3>\n<p>Rancher \u4f7f\u7528 cert-manager \u6765\u751f\u6210\u548c\u7ba1\u7406\u8bc1\u4e66\uff0c\u5982\u679c\u8981\u81ea\u884c\u4e0a\u4f20\u8bc1\u4e66\u4e5f\u53ef\u4ee5\u8df3\u8fc7\u8fd9\u4e00\u8282<\/p>\n<p>\u9996\u5148\u6765\u5b89\u88c5 Helm\uff0c\u4e0d\u540c\u7684 Linux \u53d1\u884c\u7248\u7684\u5b89\u88c5\u65b9\u5f0f\u7565\u6709\u533a\u522b\uff0c\u975e Debian\/Ubuntu \u53ef\u4ee5\u53c2\u8003<a class=\"link\" href=\"https:\/\/helm.sh\/docs\/intro\/install\/\" target=\"_blank\" rel=\"noopener\"\n>\u5b98\u65b9\u6587\u6863<\/a>\u8fdb\u884c\u5b89\u88c5<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">apt install helm\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f7f\u7528 Helm \u6765\u5b89\u88c5 cert-manager\uff0c\u6ce8\u610f\u8fd9\u91cc\u7684\u7248\u672c v1.10.0 \u53ef\u4ee5\u6839\u636e\u9700\u8981\u8fdb\u884c\u66ff\u6362<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">kubectl apply -f https:\/\/github.com\/cert-manager\/cert-manager\/releases\/download\/v1.10.0\/cert-manager.crds.yaml\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">helm repo add jetstack https:\/\/charts.jetstack.io\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">helm repo update\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">helm install cert-manager jetstack\/cert-manager <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --namespace cert-manager <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --create-namespace <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --version v1.10.0\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"\u7b7e\u53d1-letsencrypt-\u8bc1\u4e66\">\u7b7e\u53d1 letsencrypt \u8bc1\u4e66<\/h4>\n<p>Rancher \u9ed8\u8ba4\u4f1a\u4f7f\u7528 cert-manager \u521b\u5efa\u81ea\u7b7e\u540d\u8bc1\u4e66\u3002\u5982\u679c\u4f60\u5e0c\u671b\u4f7f\u7528\u80fd\u901a\u8fc7\u6d4f\u89c8\u5668\u6821\u9a8c\u7684\u5408\u6cd5\u8bc1\u4e66\uff0c\u4e5f\u53ef\u4ee5\u7528 cert-manager \u83b7\u53d6 letsencrypt \u7b7e\u53d1\u7684\u8bc1\u4e66<\/p>\n<p>\u4f7f\u7528 cert-manager \u7b7e\u53d1\u8bc1\u4e66\u7684\u6d41\u7a0b\u5206\u4e3a\u4ee5\u4e0b\u51e0\u6b65\uff1a<\/p>\n<ol>\n<li>\u521b\u5efa Issuer<\/li>\n<\/ol>\n<p>cert-manager \u4f7f\u7528 ACME \u6765\u7b7e\u53d1\u8bc1\u4e66\uff0c\u652f\u6301 <a class=\"link\" href=\"https:\/\/cert-manager.io\/docs\/configuration\/acme\/http01\/\" target=\"_blank\" rel=\"noopener\"\n>HTTP01<\/a> \u548c <a class=\"link\" href=\"https:\/\/cert-manager.io\/docs\/configuration\/acme\/dns01\/\" target=\"_blank\" rel=\"noopener\"\n>DNS01<\/a> \u4e24\u79cd\u65b9\u5f0f\u8fdb\u884c\u6821\u9a8c<\/p>\n<p>\u535a\u4e3b\u8fd9\u91cc\u4f7f\u7528\u7684\u662f letsencrypt + DNS01 \u6821\u9a8c\u65b9\u5f0f\uff0cDNS \u63d0\u4f9b\u5546\u4e3a Cloudflare\u3002\u5982\u679c\u4f60\u4e5f\u5e0c\u671b\u4f7f\u7528\u540c\u6837\u7684\u6821\u9a8c\u65b9\u5f0f\uff0c\u4fee\u6539\u4e0b\u9762\u914d\u7f6e\u4e2d\u7684 your-api-key \u548c <a class=\"link\" href=\"mailto:admin@example.com\" >admin@example.com<\/a> \u5373\u53ef<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Secret<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cloudflare-api-key-secret<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cert-manager<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">type<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Opaque<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">stringData<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">api-key<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">&lt;your-api-key&gt;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nn\">---<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cert-manager.io\/v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">ClusterIssuer<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">letsencrypt-prod<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cert-manager<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">acme<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">email<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">admin@example.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">server<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">https:\/\/acme-v02.api.letsencrypt.org\/directory<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">privateKeySecretRef<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">letsencrypt-prod<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">solvers<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">dns01<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">cloudflare<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">email<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">admin@example.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">apiKeySecretRef<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cloudflare-api-key-secret<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">key<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">api-key<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock info\">\n<p>\u5982\u679c\u60f3\u5c06\u8fd9\u4e2a Issuer \u8bbe\u7f6e\u4e3a\u9ed8\u8ba4\u4f7f\u7528\uff0c\u53ef\u4ee5\u7528\u5982\u4e0b\u547d\u4ee4\u5347\u7ea7 cert-manager<\/p>\n<p><code>helm upgrade cert-manager jetstack\/cert-manager --set 'extraArgs={--default-issuer-name=letsencrypt-prod,--default-issuer-kind=ClusterIssuer}' -n cert-manager<\/code><\/p>\n<\/div>\n<p><\/p>\n<ol start=\"2\">\n<li>\u521b\u5efa\u8bc1\u4e66<\/li>\n<\/ol>\n<p>\u9996\u5148\u9700\u8981\u521b\u5efa\u4e00\u4e2a namespace <code>cattle-system<\/code>\uff0c\u8fd9\u4e5f\u4f1a\u7528\u5728\u540e\u7eed\u7684 Rancher \u5b89\u88c5\u4e2d<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">kubectl create namespace cattle-system\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528\u4e0a\u9762\u521b\u5efa\u7684 Issuer <code>letsencrypt-prod<\/code> \u7b7e\u53d1\u8bc1\u4e66\u4e86\uff0c\u5c06 rancher.example.com \u66ff\u6362\u6210\u4f60\u7684\u57df\u540d\u5373\u53ef<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cert-manager.io\/v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Certificate<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-rancher-ingress<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cattle-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">secretName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-rancher-ingress<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">commonName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">rancher.example.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">dnsNames<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">rancher.example.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">issuerRef<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">letsencrypt-prod<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">ClusterIssuer<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u8bc1\u4e66\u7684 secretName \u9700\u8981\u6307\u5b9a\u4e3a tls-rancher-ingress\uff0c\u8fd9\u6837 Rancher \u624d\u80fd\u627e\u5230\u8fd9\u4e2a\u8bc1\u4e66\n<\/div>\n<p><\/p>\n<ol start=\"3\">\n<li>Debug<\/li>\n<\/ol>\n<p>\u5982\u679c\u4f60\u521b\u5efa\u8bc1\u4e66\u7684\u8fc7\u7a0b\u4e00\u756a\u98ce\u987a\uff0c\u90a3\u4e48\u606d\u559c\u4f60\u53ef\u4ee5\u76f4\u63a5\u5b89\u88c5 Rancher \u4e86\uff0c\u4f46\u662f\u5982\u679c Certificate \u4e00\u76f4\u662f Pending \u72b6\u6001\u90a3\u4e48\u5c31\u5f97\u770b\u770b\u662f\u54ea\u51fa\u4e86\u95ee\u9898<\/p>\n<p>\u521b\u5efa\u8bc1\u4e66\u7684\u6d41\u7a0b\u5206\u4e3a Certificate -&gt; CertificateRequest -&gt; Order -&gt; Challenge\uff0c\u5206\u522b\u5bf9\u5e94 \u5b9a\u4e49\u8d44\u6e90 -&gt; \u751f\u6210 CSR -&gt; \u63d0\u4ea4\u7b7e\u53d1\u8bc1\u4e66\u8bf7\u6c42 -&gt; \u6821\u9a8c\u57df\u540d\u6240\u6709\u6743\u3002\u4e0a\u8ff0\u7684\u6bcf\u4e2a\u6b65\u9aa4\u90fd\u662f\u4e00\u79cd CRD\uff0cdebug \u7684\u6d41\u7a0b\u5c31\u662f describe \u6bcf\u79cd CRD \u7684\u8d44\u6e90\u770b\u770b\u6709\u4ec0\u4e48\u62a5\u9519<\/p>\n<p>\u6bd4\u5982\u535a\u4e3b\u9047\u5230\u7684\u95ee\u9898\u662f\u6821\u9a8c\u57df\u540d\u65f6\u5361\u5728<\/p>\n<p><code>Waiting for dns-01 challenge propagation: DNS record for &quot;rancher.example.com&quot; not yet propagated<\/code><\/p>\n<p>\u8fd9\u662f\u56e0\u4e3a K3s \u4f7f\u7528\u7684 DNS \u6709\u95ee\u9898\uff0c\u4e0d\u80fd\u6b63\u786e\u83b7\u53d6 DNS Challenge \u4e2d\u8bbe\u7f6e\u7684 TXT \u8bb0\u5f55\uff0c\u4f7f\u7528\u5982\u4e0b\u547d\u4ee4\u6307\u5b9a cert-manager \u4f7f\u7528\u7684 DNS \u5373\u53ef\u6b63\u5e38\u7b7e\u53d1\u8bc1\u4e66<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># https:\/\/cert-manager.io\/docs\/configuration\/acme\/dns01\/#setting-nameservers-for-dns01-self-check<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">helm upgrade cert-manager jetstack\/cert-manager --set <span class=\"s1\">&#39;extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=8.8.8.8:53\\,1.1.1.1:53&#39;<\/span> -n cert-manager\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5b89\u88c5-rancher-1\">\u5b89\u88c5 Rancher<\/h3>\n<p>\u4f7f\u7528 Helm \u5b89\u88c5 Rancher\uff0c\u9700\u8981\u5c06 rancher.example.com \u6539\u4e3a\u4e0a\u9762\u8bc1\u4e66\u7684\u57df\u540d\u5e76\u8bbe\u7f6e\u597d\u57df\u540d\u89e3\u6790<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">helm repo add rancher-latest https:\/\/releases.rancher.com\/server-charts\/latest\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">kubectl create namespace cattle-system\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">helm install rancher rancher-latest\/rancher <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --namespace cattle-system <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --set <span class=\"nv\">hostname<\/span><span class=\"o\">=<\/span>rancher.example.com <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --set <span class=\"nv\">replicas<\/span><span class=\"o\">=<\/span><span class=\"m\">1<\/span> <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --set <span class=\"nv\">bootstrapPassword<\/span><span class=\"o\">=<\/span>&lt;admin-password&gt; <span class=\"se\">\\\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"se\"><\/span> --set ingress.tls.source<span class=\"o\">=<\/span>secret\n<\/span><\/span><\/code><\/pre><\/div><p>\u5b89\u88c5\u5b8c\u6210\u540e\u5373\u53ef\u8bbf\u95ee <code>rancher.example.com<\/code> \u6765\u4f7f\u7528 Rancher<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5982\u679c\u4f60\u8df3\u8fc7\u4e86 <a class=\"link\" href=\"#%e7%ad%be%e5%8f%91-letsencrypt-%e8%af%81%e4%b9%a6\" >\u7b7e\u53d1 letsencrypt \u8bc1\u4e66<\/a> \u8fd9\u4e2a\u6b65\u9aa4\u5e76\u4e14\u4e5f\u6ca1\u6709\u81ea\u884c\u4e0a\u4f20\u8bc1\u4e66\u9700\u8981\u53bb\u6389 <code>--set ingress.tls.source=secret<\/code>\uff0c\u8fd9\u6837 Rancher \u4f1a\u4f7f\u7528 cert-manager \u6765\u521b\u5efa\u81ea\u7b7e\u540d\u8bc1\u4e66\n<\/div>\n<p><\/p>\n<h2 id=\"\u5b89\u88c5\u4f60\u7684\u5e94\u7528\">\u5b89\u88c5\u4f60\u7684\u5e94\u7528<\/h2>\n<p>\u5b89\u88c5\u5e94\u7528\u7684\u90e8\u5206\u5c31\u9760\u8bfb\u8005\u5404\u663e\u795e\u901a\u4e86\uff0c\u535a\u4e3b\u662f\u4f7f\u7528 Kompose \u5c06\u4e4b\u524d\u7684 docker-compose \u6587\u4ef6\u8f6c\u6362\u4e3a\u8f6c\u6362\u4e3a Kubernetes \u8d44\u6e90\u63cf\u8ff0\uff0c\u8fd9\u91cc\u7ed9\u51fa\u9047\u5230\u7684\u4e24\u4e2a\u95ee\u9898\u7684\u89e3\u6cd5<\/p>\n<h3 id=\"\u6302\u8f7d\u50a8\u5b58\">\u6302\u8f7d\u50a8\u5b58<\/h3>\n<p>K3s \u9ed8\u8ba4\u53ea\u63d0\u4f9b host-path \u8fd9\u4e00\u4e2a CSI\u3002\u4f7f\u7528 host-path \u4f1a\u4f7f\u4f60\u7684\u6570\u636e\u548c Node \u5f3a\u7ed1\u5b9a\uff0c\u8fd9\u663e\u7136\u5f88\u4e0d\u4e91\u539f\u751f\u3002\u535a\u4e3b\u8fd9\u91cc\u63a8\u8350\u4e24\u4e2a CSI\uff1a<a class=\"link\" href=\"https:\/\/github.com\/kubernetes-sigs\/nfs-subdir-external-provisioner\" target=\"_blank\" rel=\"noopener\"\n>nfs-subdir-external-provisioner<\/a> \u548c <a class=\"link\" href=\"https:\/\/github.com\/longhorn\/longhorn\" target=\"_blank\" rel=\"noopener\"\n>longhorn<\/a><\/p>\n<ul>\n<li>nfs-subdir-external-provisioner \u53ef\u4ee5\u5e2e\u4f60\u6700\u7b80\u5355\u7684\u5b9e\u73b0\u50a8\u5b58\u8ba1\u7b97\u5206\u79bb\uff0c\u53ea\u8981\u4f60\u7684\u50a8\u5b58\u6c60\u652f\u6301 NFS \u5c31\u53ef\u4ee5\u8ba9 Pod \u53ef\u4ee5\u5728\u4e0d\u540c\u7684 Node \u95f4\u98d8\u79fb<\/li>\n<li>longhorn \u662f\u771f\u6b63\u7684\u5206\u5e03\u5f0f\u6587\u4ef6\u7cfb\u7edf\uff0c\u63d0\u4f9b\u591a\u526f\u672c\u548c\u5907\u4efd\/\u8fd8\u539f\u7b49\u80fd\u529b<\/li>\n<\/ul>\n<h3 id=\"\u5206\u914d\u5e94\u7528\u5230\u6307\u5b9a\u7684-node\">\u5206\u914d\u5e94\u7528\u5230\u6307\u5b9a\u7684 Node<\/h3>\n<p>\u5982\u679c\u4f60\u53ea\u60f3\u4f7f\u7528 host-path \u6216\u8005\u6709\u5e94\u7528\u548c Node \u7ed1\u5b9a\u7684\u9700\u6c42\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528 nodeAffinity\uff0c\u6709 required \u548c preferred \u4e24\u79cd\u89c4\u5219\uff0c\u8fd9\u91cc\u76f4\u63a5\u7ed9\u51fa<a class=\"link\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/scheduling-eviction\/assign-pod-node\/\" target=\"_blank\" rel=\"noopener\"\n>\u5b98\u65b9\u6587\u6863<\/a>\u4e2d\u7684\u793a\u4f8b<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Pod<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">with-node-affinity<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">affinity<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">nodeAffinity<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">requiredDuringSchedulingIgnoredDuringExecution<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">nodeSelectorTerms<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">matchExpressions<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">key<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">topology.kubernetes.io\/zone<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">operator<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">In<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">values<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">antarctica-east1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">antarctica-west1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">preferredDuringSchedulingIgnoredDuringExecution<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">weight<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">preference<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">matchExpressions<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">key<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">another-node-label-key<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">operator<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">In<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">values<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">another-node-label-value<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">containers<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">with-node-affinity<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">image<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">registry.k8s.io\/pause:2.0<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u5bf9\u5916\u66b4\u9732\u4f60\u7684\u5e94\u7528\">\u5bf9\u5916\u66b4\u9732\u4f60\u7684\u5e94\u7528<\/h2>\n<h3 id=\"kubernetes-overlay-\u7f51\u7edc\">Kubernetes Overlay \u7f51\u7edc<\/h3>\n<p>\u9996\u5148\u6765\u770b\u4e00\u4e0b\u8fd0\u884c\u5e94\u7528 Pod \u7684\u4fe1\u606f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~\/service\/k8s# kubectl get pods -o wide\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES\n<\/span><\/span><span class=\"line\"><span class=\"cl\">media-index-754bc9dfdd-6cbkl 4\/4 Running 12 (25h ago) 27h 10.42.1.27 k3s-worker-0 &lt;none&gt; &lt;none&gt;\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0 Pod \u83b7\u53d6\u5230\u7684 ip <code>10.42.1.26<\/code>\uff0c\u548c\u5b83\u6240\u5728\u7684 Node ip <code>192.168.1.2<\/code> \u5b8c\u5168\u4e0d\u5728\u4e00\u4e2a\u7f51\u6bb5\u4e2d\uff0c\u4e5f\u5c31\u662f\u8bf4\u65e0\u6cd5\u4ece Kubernetes \u5916\u90e8\u76f4\u63a5\u8bbf\u95ee\u6211\u4eec\u7684\u5e94\u7528<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~\/service\/k8s# kubectl get node -o wide\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME\n<\/span><\/span><span class=\"line\"><span class=\"cl\">k3s-server Ready control-plane,master 4d12h v1.24.7+k3s1 192.168.1.1 &lt;none&gt; Debian GNU\/Linux 11 (bullseye) 5.10.0-19-amd64 containerd:\/\/1.6.8-k3s1\n<\/span><\/span><span class=\"line\"><span class=\"cl\">k3s-worker-0 Ready &lt;none&gt; 32h v1.24.7+k3s1 192.168.1.2 &lt;none&gt; Debian GNU\/Linux 11 (bullseye) 5.10.0-19-amd64 containerd:\/\/1.6.8-k3s1\n<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u5c06 Node \u6240\u5728\u7684\u7f51\u7edc\u79f0\u4e3a Underlay \u7f51\u7edc\uff0c\u662f\u771f\u5b9e\u7684\u5e95\u5c42\u7269\u7406\u7f51\u7edc\uff1b\u800c\u5c06 Pod \u6240\u5728\u7684\u7f51\u7edc\u79f0\u4e3a Overlay \u7f51\u7edc\uff0c\u662f\u7531\u8f6f\u4ef6\u5b9a\u4e49\u7684\u903b\u8f91\u7f51\u7edc\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u662f\u6253\u901a\u4e86\u4e0d\u540c Node \u95f4\u7684\u7f51\u7edc\uff0c\u5373\u4f7f Node \u5728\u4e0d\u540c\u7684\u5b50\u7f51\u4e0b\uff08\u751a\u81f3\u662f\u4e0d\u540c\u7684\u4e91\u670d\u52a1\u5546\uff09\u4e5f\u53ef\u4e3a Pod \u63d0\u4f9b\u4e00\u81f4\u7684\u7f51\u7edc\u73af\u5883\u3002K3s \u9ed8\u8ba4\u4f7f\u7528 Flannel \u901a\u8fc7 VXLAN \u6280\u672f\u6784\u5efa Overlay \u7f51\u7edc\uff0c\u76f8\u5173\u6587\u7ae0\u53ef\u4ee5\u9605\u8bfb<\/p>\n<ul>\n<li><a class=\"link\" href=\"https:\/\/zhuanlan.zhihu.com\/p\/36165475\" target=\"_blank\" rel=\"noopener\"\n>VXLAN vs VLAN<\/a><\/li>\n<li><a class=\"link\" href=\"https:\/\/www.cnblogs.com\/hukey\/p\/14296710.html\" target=\"_blank\" rel=\"noopener\"\n>Flannel \u4ecb\u7ecd\u53ca\u4f7f\u7528\u573a\u666f<\/a><\/li>\n<\/ul>\n<p>\u6240\u4ee5\u5e94\u7528\u90e8\u7f72\u5b8c\u6210\u540e\u60f3\u8981\u5206\u914d\u4e00\u4e2a\u57df\u540d\u5e76\u5bf9\u5916\u63d0\u4f9b\u670d\u52a1\u5c31\u9700\u8981\u4f7f\u7528 Kubernetes \u7684 Ingress \u7f51\u5173\uff0c\u6211\u4eec\u5148\u6765\u770b\u4e00\u4e0b\u5b98\u65b9\u6587\u6863\u4e2d\u5bf9 Ingress \u7684\u8bf4\u660e\uff1a<\/p>\n<blockquote>\n<p>Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.<br \/>\n<figure\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/use-k3s-to-build-homelab-based-on-kubernetes\/ingress.svg\" >\n<img src=\"https:\/\/blog.lv5.moe\/p\/use-k3s-to-build-homelab-based-on-kubernetes\/ingress.svg\"\nloading=\"lazy\"\nalt=\"ingress\">\n<\/a>\n<figcaption>ingress<\/figcaption>\n<\/figure><\/p>\n<\/blockquote>\n<p>\u5373\u6211\u4eec\u8bbf\u95ee\u5e94\u7528\u5b9e\u9645\u662f\u5148\u8bbf\u95ee\u5230 Kubernetes \u7684 Ingress \u7f51\u5173\uff0c\u7136\u540e Ingress \u6839\u636e\u6211\u4eec\u914d\u7f6e\u7684\u89c4\u5219\u628a\u6d41\u91cf\u8def\u7531\u5230\u5bf9\u5e94\u7684 Service \u4e0a\uff0c\u6700\u540e\u7531 Service \u5173\u8054\u7684 Pod \u63d0\u4f9b\u670d\u52a1<\/p>\n<h3 id=\"\u4f7f\u7528-traefik-ingress\">\u4f7f\u7528 Traefik Ingress<\/h3>\n<p>K3s \u9ed8\u8ba4\u4f7f\u7528 Traefik \u4f5c\u4e3a Ingress Controller\uff0cTraefik \u4f1a\u81ea\u52a8\u5c06 Ingress \u548c IngressRoute\uff08Traefik \u63d0\u4f9b\u7684 CRD\uff09\u8f6c\u6362\u4e3a\u8def\u7531\u89c4\u5219\uff0c\u6211\u4eec\u4e0b\u9762\u4ee5 Traefik dashboard \u4e3a\u4f8b\u770b\u4e0b\u5982\u4f55\u5bf9\u5916\u66b4\u9732\u670d\u52a1<\/p>\n<p>\u7b7e\u53d1\u8bc1\u4e66 tls-traefik-ingress \u5e76\u4e14\u5c06 traefik.example.com \u66ff\u6362\u4e3a\u4f60\u7684\u57df\u540d\u5373\u53ef\u5728 Kubernetes \u5916\u8bbf\u95ee Traefik dashboard<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">IngressRoute<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik-dashboard<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">entryPoints<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">websecure<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">routes<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">match<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Host(`traefik.example.com`) &amp;&amp; (PathPrefix(`\/`) || PathPrefix(`\/dashboard`) || PathPrefix(`\/api`))<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Rule<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">services<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">api@internal<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">TraefikService<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">tls<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">secretName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-traefik-ingress<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u4e2a yaml \u7684 spec \u4e3b\u8981\u5206\u4e3a entryPoints\u3001routes\u3001services \u4e09\u4e2a\u90e8\u5206<\/p>\n<ul>\n<li>entryPoints\uff1a\u6307\u5b9a\u670d\u52a1\u7684\u63a5\u5165\u70b9\uff0c\u6709\u4e24\u4e2a\u9884\u7f6e\u7684 entryPoint\uff1aweb \u548c websecure\uff0c\u524d\u8005\u5bf9\u5e94 80 \u7aef\u53e3\u7684 http \u670d\u52a1\uff0c\u540e\u8005\u5bf9\u5e94 443 \u7aef\u53e3\u7684 https \u670d\u52a1\u3002\u5982\u679c\u4f7f\u7528 websecure \u9700\u8981\u914d\u7f6e tls\uff0c\u5426\u8005\u4f1a\u4f7f\u7528 Traefik \u9ed8\u8ba4\u7684\u81ea\u7b7e\u540d\u8bc1\u4e66<\/li>\n<li>routes\uff1a\u6307\u5b9a\u8def\u7531\u89c4\u5219\uff0c\u5176\u4e2d match \u5b57\u6bb5\u7528\u4e8e\u5339\u914d\u5bf9\u4f55\u79cd\u6d41\u91cf\u5e94\u7528\u672c\u89c4\u5219<\/li>\n<li>services\uff1a\u6307\u5b9a\u540e\u7aef\u670d\u52a1\uff0cKind \u5b57\u6bb5\u53ef\u4ee5\u4e3a Service \u6216 TraefikService \u4e24\u79cd\u3002\u6211\u8fd9\u91cc\u4f7f\u7528\u7684 api@internal \u662f Traefik \u9884\u7f6e\u7684 TraefikService<\/li>\n<\/ul>\n<p>\u66f4\u8be6\u7ec6\u7684\u8bf4\u660e\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u6587\u6863\uff1a<a class=\"link\" href=\"https:\/\/doc.traefik.io\/traefik\/routing\/providers\/kubernetes-crd\/\" target=\"_blank\" rel=\"noopener\"\n>Traefik &amp; Kubernetes<\/a><\/p>\n<h4 id=\"\u4ee3\u7406\u975e-kubernetes-\u5e94\u7528\">\u4ee3\u7406\u975e Kubernetes \u5e94\u7528<\/h4>\n<p>\u524d\u9762\u63d0\u5230 Traefik \u6839\u636e\u6211\u4eec\u914d\u7f6e\u7684\u89c4\u5219\u628a\u6d41\u91cf\u8def\u7531\u5230\u5bf9\u5e94\u7684 Service \u4e0a\uff0c\u5b9e\u9645\u4e0a\u662f\u83b7\u53d6 Service \u5bf9\u5e94\u7684 Endpoints \u7684 ip\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~# kubectl get svc\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\n<\/span><\/span><span class=\"line\"><span class=\"cl\">index ClusterIP 10.43.218.102 &lt;none&gt; 8989\/TCP,7878\/TCP,9117\/TCP 41h\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">root@k3s-server:~# kubectl get endpoints\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME ENDPOINTS AGE\n<\/span><\/span><span class=\"line\"><span class=\"cl\">index 10.42.1.27:7878,10.42.1.27:8989,10.42.1.27:9117 41h\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">root@k3s-server:~\/service\/k8s# kubectl get pods -o wide\n<\/span><\/span><span class=\"line\"><span class=\"cl\">NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES\n<\/span><\/span><span class=\"line\"><span class=\"cl\">media-index-754bc9dfdd-6cbkl 4\/4 Running 12 (25h ago) 27h 10.42.1.27 k3s-worker-0 &lt;none&gt; &lt;none&gt;\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0 Endpoints \u4e2d\u7684 ip \u5c31\u662f\u5e94\u7528 Pod \u7684 ip\uff0cKubernetes \u4f1a\u6839\u636e Service \u4e2d\u914d\u7f6e\u7684 selector \u6765\u627e\u5230\u5173\u8054\u7684 Pod \u5e76\u521b\u5efa Endpoints<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Service<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">index<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">media<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">ports<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">sonarr<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">8989<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">radarr<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">7878<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">jackett<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">9117<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">selector<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">app<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">index<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u6240\u4ee5\u8ba9 Traefik \u4ee3\u7406\u975e Kubernetes \u5e94\u7528\u5c31\u9700\u8981\u624b\u52a8\u521b\u5efa Endpoints \u5e76\u4e14\u4e0d\u5728 Service \u4e2d\u6307\u5b9a selector\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Endpoints<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">media<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">subsets<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span>- <span class=\"nt\">addresses<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">ip<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">192.168.1.1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">hostname<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">ports<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">8080<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">protocol<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">TCP<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nn\">---<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Service<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">media<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">ports<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">8080<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nn\">---<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">IngressRoute<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">media<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">entryPoints<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">websecure<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">routes<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">match<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Host(`downloader.example.com`)<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Rule<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">services<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">downloader<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">media<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">port<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">8080<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><h4 id=\"\u914d\u7f6e\u8df3\u8f6c-https\">\u914d\u7f6e\u8df3\u8f6c https<\/h4>\n<p>Traefik \u7684\u8def\u7531\u89c4\u5219\u652f\u6301\u6b63\u5219\u5339\u914d\uff0c\u6211\u4eec\u53ef\u4ee5\u501f\u6b64\u914d\u7f6e\u4e00\u4e9b\u9ed8\u8ba4\u89c4\u5219\uff1ahttp \u81ea\u52a8\u8df3\u8f6c https\u3001\u9759\u6001\u8d44\u6e90\u7f13\u5b58\u7b56\u7565\u3001CORS \u89c4\u5219\u7b49\u7b49<\/p>\n<p>\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e2a\u4f7f\u7528 Middleware \u5c06\u6240\u6709\u7f51\u7ad9\u7684 http \u8bf7\u6c42\u8df3\u8f6c\u5230 https \u7684\u4f8b\u5b50\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Middleware<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">redirect-to-https<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">redirectScheme<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">scheme<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">https<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">permanent<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nn\">---<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">IngressRoute<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">default-redirect-http-to-https<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">entryPoints<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">web<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">routes<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">match<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">HostRegexp(`{alldomain:.*}`)<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Rule<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">services<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">ping@internal<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">TraefikService<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">middlewares<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">redirect-to-https<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><h4 id=\"\u914d\u7f6e\u9ed8\u8ba4\u8bc1\u4e66\">\u914d\u7f6e\u9ed8\u8ba4\u8bc1\u4e66<\/h4>\n<p>Traefik \u4e0d\u652f\u6301\u4f7f\u7528 cert-manager \u81ea\u52a8\u7533\u8bf7\u8bc1\u4e66\uff0c\u6211\u4eec\u53ef\u4ee5\u624b\u52a8\u7533\u8bf7\u6cdb\u57df\u540d\u8bc1\u4e66\u5e76\u4e14\u914d\u7f6e\u4e3a Traefik \u7684\u9ed8\u8ba4\u8bc1\u4e66\uff0c\u8fd9\u6837\u5c31\u4e0d\u5fc5\u4e3a\u6bcf\u4e2a\u7f51\u7ad9\u624b\u52a8\u914d\u7f6e\u8bc1\u4e66<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">cert-manager.io\/v1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">Certificate<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-example-default<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">secretName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-example-default<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">commonName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;*.example.com&#39;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">dnsNames<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"s1\">&#39;*.example.com&#39;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">example.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">issuerRef<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">letsencrypt-prod<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">ClusterIssuer<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nn\">---<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">TLSStore<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">default<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">defaultCertificate<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">secretName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">tls-example-default<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u521b\u5efa\u540d\u4e3a <code>default<\/code> \u7684 TLSStore \u4f1a\u8986\u76d6 Traefik \u7684\u9ed8\u8ba4 tls \u914d\u7f6e\n<\/div>\n<p><\/p>\n<h4 id=\"\u914d\u7f6e-strict-sni\">\u914d\u7f6e Strict SNI<\/h4>\n<p>\u6709\u4e86\u6cdb\u57df\u540d\u8bc1\u4e66\u6211\u4eec\u5c31\u53ef\u4ee5\u5bf9\u5916\u63d0\u4f9b\u591a\u4e2a\u7f51\u7ad9\u7684 https \u670d\u52a1\uff0c\u4f46\u662f\u8fd9\u6837\u6709\u5b58\u5728\u4e00\u4e2a\u98ce\u9669\uff1a\u5982\u679c\u4f60\u7684\u670d\u52a1\u5668\u66b4\u9732\u5728\u516c\u7f51\u4e2d\uff0c\u5e76\u4e14\u4e0d\u5e78\u88ab\u811a\u672c\u5c0f\u5b50\u626b\u5230\uff0c\u90a3\u4e48\u4ed6\u8bbf\u95ee 443 \u7aef\u53e3\u5c31\u53ef\u4ee5\u62ff\u5230\u4f60\u7684\u7f51\u7ad9\u4fe1\u606f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">root@k3s-server:~# curl https:\/\/192.168.1.1 -v\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">* Server certificate:\n<\/span><\/span><span class=\"line\"><span class=\"cl\">* subject: <span class=\"nv\">CN<\/span><span class=\"o\">=<\/span>*.example.com\n<\/span><\/span><span class=\"line\"><span class=\"cl\">* start date: Nov <span class=\"m\">4<\/span> 14:01:21 <span class=\"m\">2022<\/span> GMT\n<\/span><\/span><span class=\"line\"><span class=\"cl\">* expire date: Feb <span class=\"m\">2<\/span> 14:01:20 <span class=\"m\">2023<\/span> GMT\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u5c31\u662f\u7531 SNI \u5bfc\u81f4\u7684\u57df\u540d\u6cc4\u9732\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u8bbe\u7f6e Strict SNI \u6765\u62d2\u7edd\u6389\u975e\u6cd5\u57df\u540d\u7684\u8bbf\u95ee\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">apiVersion<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">traefik.containo.us\/v1alpha1<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">kind<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">TLSOption<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">metadata<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">name<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">default<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">namespace<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">kube-system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">spec<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">sniStrict<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u914d\u7f6e\u4e86 Strict SNI \u4f1a\u4f7f\u5f97\u9ed8\u8ba4\u8bc1\u4e66\u5931\u6548\uff0c\u9700\u8981\u4e3a\u6bcf\u4e2a\u7f51\u7ad9\u663e\u5f0f\u6307\u5b9a\u8bc1\u4e66<br \/>\n\u5173\u4e8e SNI \u7684\u8be6\u7ec6\u4ecb\u7ecd\u53ef\u4ee5\u9605\u8bfb <a class=\"link\" href=\"https:\/\/www.cloudflare.com\/zh-cn\/learning\/ssl\/what-is-sni\/\" target=\"_blank\" rel=\"noopener\"\n>Cloudflare \u7684\u6587\u7ae0<\/a>\n<\/div>\n<p><\/p>"},{"title":"\u4f7f\u7528\u5bf9\u8c61\u5b58\u50a8\u4ee3\u66ff\u786c\u76d8\u6587\u4ef6\u7cfb\u7edf\u6700\u4f73\u5b9e\u8df5","link":"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system","pubDate":"Sun, 28 Aug 2022 02:00:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system\/cover.png\" alt=\"Featured image of post \u4f7f\u7528\u5bf9\u8c61\u5b58\u50a8\u4ee3\u66ff\u786c\u76d8\u6587\u4ef6\u7cfb\u7edf\u6700\u4f73\u5b9e\u8df5\" \/><p>\u535a\u4e3b\u6700\u8fd1\u4f7f\u7528\u5bf9\u8c61\u5b58\u50a8\u4f5c\u4e3a\u786c\u76d8\u7b49\u5757\u5b58\u50a8\u6587\u4ef6\u7cfb\u7edf\u7684\u51b7\u5b58\u50a8\u66ff\u4ee3\u65b9\u6848\uff0c\u8282\u7ea6\u6570\u636e\u50a8\u5b58\u6210\u672c\u3002\u672c\u6587\u4ecb\u7ecd\u8fd9\u4e2a\u65b9\u6848\u5b9e\u73b0\u8fc7\u7a0b\u4e2d\u7684\u8e29\u5751\u8bb0\u5f55\uff0c\u4ee5\u53ca\u963f\u91cc\u4e91 OSS \u7684\u51e0\u79cd\u4f7f\u7528\u65b9\u5f0f\u7684\u6700\u4f73\u5b9e\u8df5\u4e0e\u6027\u80fd\u5206\u6790<\/p>\n<h2 id=\"\u9879\u76ee\u80cc\u666f\">\u9879\u76ee\u80cc\u666f<\/h2>\n<p>\u968f\u7740\u6211\u4eec\u7cfb\u7edf\u7684\u6570\u636e\u91cf\u8d8a\u6765\u8d8a\u5927\uff0c\u6602\u8d35\u7684 SSD \u786c\u76d8\u5728\u673a\u5668\u6210\u672c\u4e2d\u5360\u4e86\u5927\u5934\u3002\u4f46\u662f\u7edd\u5927\u591a\u6570\u6570\u636e\u968f\u7740\u4fdd\u5b58\u65f6\u95f4\u7684\u589e\u957f\u4f1a\u53d8\u6210\u201c\u51b7\u6570\u636e\u201d\uff0c\u5373\u5f88\u5c11\u6709\u8bfb\u53d6\u9700\u6c42\u3002\u5982\u679c\u6211\u4eec\u80fd\u5c06\u8fd9\u4e9b\u51b7\u6570\u636e\u8f6c\u79fb\u5230\u66f4\u4fbf\u5b9c\u7684\u50a8\u5b58\u4ecb\u8d28\u4e2d\u5c31\u53ef\u4ee5\u5927\u5e45\u964d\u4f4e\u6210\u672c<\/p>\n<p>\u4e0b\u9762\u662f\u963f\u91cc\u4e91\u51e0\u79cd\u6587\u4ef6\u5b58\u50a8\u670d\u52a1\u7684\u5bf9\u6bd4\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u7c7b\u578b<\/th>\n<th>\u89c4\u683c<\/th>\n<th>\u5ef6\u8fdf<\/th>\n<th>\u5e26\u5bbd\uff08MB\/s\uff09<\/th>\n<th>\u4ef7\u683c\uff08\u5143\/GB\/\u6708\uff09<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u5757\u5b58\u50a8<\/td>\n<td>\u666e\u901a\u4e91\u76d8<\/td>\n<td>\u5fae\u79d2\u7ea7<\/td>\n<td>30~40<\/td>\n<td>0.3<\/td>\n<\/tr>\n<tr>\n<td>\u5757\u5b58\u50a8<\/td>\n<td>\u9ad8\u6548\u4e91\u76d8<\/td>\n<td>\u5fae\u79d2\u7ea7<\/td>\n<td>140<\/td>\n<td>0.35<\/td>\n<\/tr>\n<tr>\n<td>\u5757\u5b58\u50a8<\/td>\n<td>SSD\u4e91\u76d8<\/td>\n<td>\u5fae\u79d2\u7ea7<\/td>\n<td>300<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>NAS<\/td>\n<td>\u901a\u7528\u578b<\/td>\n<td>10ms<\/td>\n<td>150<\/td>\n<td>0.3<\/td>\n<\/tr>\n<tr>\n<td>NAS<\/td>\n<td>\u6781\u901f\u578b<\/td>\n<td>2ms<\/td>\n<td>600<\/td>\n<td>1.62<\/td>\n<\/tr>\n<tr>\n<td>OSS<\/td>\n<td>\u6807\u51c6\u578b<\/td>\n<td>\u89c1\u4e0b\u6587\u6027\u80fd\u5206\u6790<\/td>\n<td>\u89c1\u4e0b\u6587\u6027\u80fd\u5206\u6790<\/td>\n<td>0.12<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u5176\u4e2d OSS \u62e5\u6709\u6781\u4e3a\u660e\u663e\u7684\u4ef7\u683c\u4f18\u52bf\uff0c\u662f\u6211\u4eec\u76ee\u524d\u4f7f\u7528\u7684 SSD \u4ef7\u683c\u7684 12%\uff0c\u662f\u901a\u7528\u578b NAS \u7684 40%\u3002\u5982\u679c\u5c06 1T \u7684 SSD \u6570\u636e\u76d8\u6362\u6210 OSS \u8282\u7701\u7684\u6210\u672c\u76f8\u5f53\u4e8e\u4e00\u53f0 8C32G \u7684 ECS<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u56e0\u4e3a\u6280\u672f\u9009\u578b\u539f\u56e0\uff0c\u535a\u4e3b\u4f7f\u7528\u963f\u91cc\u4e91 OSS \u63d0\u4f9b\u7684\u5bf9\u8c61\u5b58\u50a8\u670d\u52a1\uff0c\u4e0b\u6587\u4e2d\u201c\u5bf9\u8c61\u5b58\u50a8\u201d\u4e0e\u201c\u963f\u91cc\u4e91 OSS\u201d\u53ef\u4ee5\u7b49\u4ef7\u4e92\u6362\n<\/div>\n<p><\/p>\n<h2 id=\"oss-\u8bfb\u5199\u65b9\u5f0f\">OSS \u8bfb\u5199\u65b9\u5f0f<\/h2>\n<p>\u5757\u50a8\u5b58\u548c NAS \u539f\u751f\u652f\u6301\u6302\u8f7d\u4e3a\u6587\u4ef6\u7cfb\u7edf\uff0c\u5bf9\u73b0\u6709\u7cfb\u7edf\u65e0\u4fb5\u5165\u3002OSS \u7684\u8bfb\u5199\u65b9\u5f0f\u5219\u6bd4\u8f83\u7279\u6b8a\uff0c\u4e3b\u8981\u6709\u4ee5\u4e0b\u51e0\u79cd\uff1a<\/p>\n<h3 id=\"api\">API<\/h3>\n<h4 id=\"oss-api\">OSS API<\/h4>\n<p>\u4f7f\u7528 OSS \u7684\u5ba2\u6237\u7aef\u6216\u8005\u81ea\u884c\u5c01\u88c5 OSS \u63d0\u4f9b\u7684 Open API \u5373\u53ef\u4f7f\u7528 OSS \u63d0\u4f9b\u7684\u5bf9\u8c61\u5b58\u50a8\u670d\u52a1\uff0c\u6587\u6863\u94fe\u63a5\uff1a<a class=\"link\" href=\"https:\/\/help.aliyun.com\/document_detail\/31948.html\" target=\"_blank\" rel=\"noopener\"\n>OSS API \u53c2\u8003<\/a><\/p>\n<p>\u8fd9\u91cc\u4e0d\u5f97\u4e0d\u5410\u69fd\u4e0b OSS \u5b98\u65b9 SDK\uff0c\u90fd 2202 \u5e74\u4e86\u8fd8\u4e0d\u63d0\u4f9b\u5f02\u6b65\u63a5\u53e3\uff0c\u4eba\u5bb6 AWS S3 \u65e9\u51e0\u5e74\u5c31\u652f\u6301\u4e86&hellip;&hellip;<\/p>\n<h4 id=\"s3-api\">S3 API<\/h4>\n<p>OSS \u517c\u5bb9\u90e8\u5206 S3 API\uff0c\u57fa\u672c\u8986\u76d6\u4e86\u4e0a\u4f20\u3001\u4e0b\u8f7d\u548c\u67e5\u8be2\u5143\u6570\u636e\u63a5\u53e3\uff0c\u76f8\u5173\u6587\u6863\uff1a<a class=\"link\" href=\"https:\/\/help.aliyun.com\/document_detail\/389025.html\" target=\"_blank\" rel=\"noopener\"\n>AWS S3\u517c\u5bb9\u6027<\/a><\/p>\n<p>\u7406\u8bba\u4e0a\u652f\u6301 S3 \u7684\u5de5\u5177\u4e5f\u53ef\u5728 OSS \u4e0a\u4f7f\u7528<\/p>\n<h3 id=\"\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf\">\u6302\u8f7d\u6587\u4ef6\u7cfb\u7edf<\/h3>\n<h4 id=\"linux-fuse\">Linux fuse<\/h4>\n<p>\u5f97\u76ca\u4e8e OSS \u652f\u6301 S3 API\uff0c\u53ef\u4ee5\u4f7f\u7528 <a class=\"link\" href=\"https:\/\/github.com\/s3fs-fuse\/s3fs-fuse\" target=\"_blank\" rel=\"noopener\"\n>S3FS<\/a> \u6765\u5c06 OSS \u6302\u8f7d\u4e3a\u672c\u5730\u76ee\u5f55<\/p>\n<p>S3FS \u4f7f\u7528 Linux fuse \u6280\u672f\u5728\u7528\u6237\u7a7a\u95f4\u6784\u5efa\u6587\u4ef6\u7cfb\u7edf\uff0c\u90e8\u5206\u517c\u5bb9 POSIX\u3002\u6362\u53e5\u8bdd\u8bf4\u5c31\u662f\u53ef\u4ee5\u5f53\u6210\u4e00\u5757\u786c\u76d8\u6302\u8f7d\u4f7f\u7528\uff0c\u76f8\u5173\u4f7f\u7528\u9650\u5236\u53ef\u4ee5\u9605\u8bfb\u9879\u76ee\u6587\u6863 <a class=\"link\" href=\"https:\/\/github.com\/s3fs-fuse\/s3fs-fuse#limitations\" target=\"_blank\" rel=\"noopener\"\n>limitations \u90e8\u5206<\/a><\/p>\n<p>S3FS \u662f\u4e00\u4e2a\u7eaf\u7cb9\u7684\u5f00\u6e90\u8f6f\u4ef6\uff0c\u4e3b\u8981\u8d21\u732e\u8005\u662f Google \u548c Yahoo \u7684\u4e24\u4e2a\u8001\u54e5\u3002\u7f13\u5b58\u7b49\u529f\u80fd\u8fd8\u4e0d\u6210\u719f\uff0c\u7a33\u5b9a\u6027\u65e2\u6ca1\u6709\u5546\u4e1a\u516c\u53f8\u80cc\u4e66\u4e5f\u6ca1\u6709\u627e\u5230\u5927\u89c4\u6a21\u751f\u4ea7\u4f7f\u7528\u7684\u6848\u4f8b<\/p>\n<h4 id=\"\u865a\u62df\u6587\u4ef6\u7cfb\u7edf\">\u865a\u62df\u6587\u4ef6\u7cfb\u7edf<\/h4>\n<p>\u57fa\u4e8e\u5bf9\u8c61\u50a8\u5b58\u6784\u5efa\u7684\u5206\u5e03\u5f0f\u6587\u4ef6\u7cfb\u7edf\uff0c\u6bd4\u5982 JuiceFS\u3002\u5b83\u4e3b\u8981\u89e3\u51b3\u4e86\u4e09\u4e2a\u95ee\u9898\uff1a<\/p>\n<ol>\n<li>\u5b8c\u5168\u517c\u5bb9 POSIX\u3001HDFS<\/li>\n<li>\u652f\u6301\u901a\u8fc7 fuse\u3001csi \u6302\u8f7d\u5230\u670d\u52a1\u5668\u6216 k8s pod \u4e2d\uff0c\u4e5f\u53ef\u4f7f\u7528 S3 client\u3001WebDAV client\u3001Hadoop client \u8bbf\u95ee<\/li>\n<li>\u6258\u7ba1\u6587\u4ef6\u5143\u6570\u636e\uff0c\u89e3\u51b3\u5143\u6570\u636e\u8bbf\u95ee\u7684\u6027\u80fd\u95ee\u9898<\/li>\n<\/ol>\n<p>JuiceFS \u5b98\u65b9\u6587\u6863\u4e2d\u6709\u4e0e S3FS \u7684\u5bf9\u6bd4\uff1a<a class=\"link\" href=\"https:\/\/juicefs.com\/docs\/community\/comparison\/juicefs_vs_s3fs\/\" target=\"_blank\" rel=\"noopener\"\n>JuiceFS vs. S3FS<\/a><\/p>\n<p>JuiceFS \u4e0a\u50a8\u5b58\u7684\u6587\u4ef6\u4f1a\u88ab\u62c6\u5206\u6210\u4e3a\u4e00\u4e2a\u4e2a 4MB \u7684 Block \u50a8\u5b58\u5728\u5bf9\u8c61\u50a8\u5b58\u4e2d\uff0c\u8fd9\u610f\u5473\u7740\u4e0d\u518d\u80fd\u76f4\u63a5\u4ece OSS \u8bfb\u53d6\u6587\u4ef6\uff0c\u5fc5\u987b\u4f9d\u8d56 JuiceFS server \u7684\u8f6c\u6362<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 121;\nflex-basis: 292px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system\/juicefs-storage-format.jpg\" data-size=\"1640x1346\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system\/juicefs-storage-format.jpg\"\nwidth=\"1640\"\nheight=\"1346\"\nloading=\"lazy\"\nalt=\"JuiceFS \u6587\u4ef6\u50a8\u5b58\u683c\u5f0f\">\n<\/a>\n<figcaption>JuiceFS \u6587\u4ef6\u50a8\u5b58\u683c\u5f0f<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"oss-\u6027\u80fd\u5206\u6790\">OSS \u6027\u80fd\u5206\u6790<\/h2>\n<p>\u5c06 OSS \u6302\u8f7d\u4e3a\u6587\u4ef6\u7cfb\u7edf\u7684\u65b9\u6848\u5404\u6709\u7f3a\u70b9\uff0c\u6211\u4eec\u53ea\u80fd\u8d64\u818a\u4e0a\u9635\u7528 OSS API \u6765\u6539\u9020\u6211\u4eec\u7684\u73b0\u6709\u7cfb\u7edf\u3002\u9996\u5148\u8981\u505a\u7684\u5de5\u4f5c\u5c31\u662f\u6027\u80fd\u6d4b\u8bd5\uff0c\u770b\u4e0b OSS \u7684\u6027\u80fd\u662f\u5426\u80fd\u6ee1\u8db3\u6211\u4eec\u7684\u9700\u8981\u3002\u505a\u6027\u80fd\u5206\u6790\u4e4b\u524d\u9700\u8981\u5148\u4e86\u89e3\u5bf9\u8c61\u5b58\u50a8\u7684\u7279\u6027\uff0c\u5bf9\u5176\u80fd\u8fbe\u5230\u7684\u6027\u80fd\u6709\u4e00\u4e2a\u9884\u671f\uff1a<\/p>\n<ul>\n<li>\u65e0\u9650\u7684\u50a8\u5b58\u7a7a\u95f4<\/li>\n<li>\u6587\u4ef6\u4e00\u65e6\u5199\u5165\u65e0\u6cd5\u4fee\u6539\uff08Appendable \u7684\u6587\u4ef6\u53ef\u8ffd\u52a0\u5199\u5165\uff09<\/li>\n<li>\u4ec5\u652f\u6301\u6709\u9650\u7684 API\uff1a\u5143\u6570\u636e\u64cd\u4f5c\u5982\u904d\u5386\u6587\u4ef6\u6027\u80fd\u5dee\u3001\u65e0\u6cd5\u91cd\u547d\u540d\uff08\u76f8\u5f53\u4e8e\u91cd\u65b0\u4e0a\u4f20\uff09\u3001\u65e0\u6cd5\u76d1\u542c\u6587\u4ef6\u53d8\u66f4\u7b49\u7b49<\/li>\n<li>IOPS\/QPS \u5f88\u4f4e\u4e14<a class=\"link\" href=\"https:\/\/help.aliyun.com\/document_detail\/54464.html\" target=\"_blank\" rel=\"noopener\"\n>\u53d7\u9650<\/a>\uff0c\u9700\u5c3d\u91cf batch \u4e0a\u4f20\/\u4e0b\u8f7d\uff0c\u4f46\u8bbf\u95ee\u5ef6\u8fdf\u4e0e\u6bcf\u6b21\u8bf7\u6c42\u7684\u6570\u636e\u91cf\u6b63\u76f8\u5173<\/li>\n<li>\u5355\u7ebf\u7a0b\u5e26\u5bbd\u6709\u9650\uff0c\u5982\u9700\u66f4\u9ad8\u5e26\u5bbd\u8981\u5e76\u53d1\u8bf7\u6c42<\/li>\n<li><a class=\"link\" href=\"https:\/\/www.aliyun.com\/price\/product#\/oss\/detail\/ossbag\" target=\"_blank\" rel=\"noopener\"\n>\u8ba1\u8d39\u65b9\u5f0f<\/a>\u4e3a\u6309\u50a8\u5b58\u5bb9\u91cf\u548c API \u8c03\u7528\u6b21\u6570\u8ba1\u8d39<\/li>\n<\/ul>\n<p>\u57fa\u4e8e\u5bf9\u8c61\u5b58\u50a8\u7684\u4ee5\u4e0a\u7279\u6027\uff0c\u5728\u8bbf\u95ee\u7684\u6570\u636e\u91cf\u4e00\u5b9a\u65f6\u5ef6\u8fdf\u3001\u5e26\u5bbd\u3001\u6210\u672c\u6784\u6210\u4e09\u5143\u6096\u8bba\uff0c\u9700\u8981\u9488\u5bf9\u4e0d\u540c\u573a\u666f\u505a\u51fa\u6743\u8861\uff1a<\/p>\n<ul>\n<li>\u6bcf\u6b21\u8bf7\u6c42\u4e0a\u4f20\/\u4e0b\u8f7d\u66f4\u591a\u7684\u6570\u636e\u53ef\u4ee5\u63d0\u9ad8\u5e26\u5bbd\u4f46\u662f\u5e26\u6765\u66f4\u5927\u7684\u5ef6\u8fdf\uff0c\u53cd\u4e4b\u53ef\u4ee5\u964d\u4f4e\u5ef6\u8fdf\u4f46\u662f\u51cf\u5c11\u5e26\u5bbd<\/li>\n<li>\u591a\u4e2a\u8fde\u63a5\u5e76\u53d1\u8bf7\u6c42\u53ef\u4ee5\u63d0\u5347\u5e26\u5bbd\u5e76\u964d\u4f4e\u5ef6\u8fdf\uff0c\u4f46\u662f\u4f1a\u63d0\u9ad8\u8bf7\u6c42\u7684 QPS \u8fdb\u800c\u63d0\u9ad8\u6210\u672c<\/li>\n<\/ul>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 153;\nflex-basis: 368px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system\/impossible-trinity.jpg\" data-size=\"779x508\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/best-practices-for-alibaba-cloud-oss-to-replace-disk-file-system\/impossible-trinity.jpg\"\nwidth=\"779\"\nheight=\"508\"\nloading=\"lazy\"\nalt=\"\u4e09\u5143\u6096\u8bba\">\n<\/a>\n<figcaption>\u4e09\u5143\u6096\u8bba<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"\u4e0a\u4f20\">\u4e0a\u4f20<\/h3>\n<p>OSS \u63d0\u4f9b\u4e09\u79cd\u4e0a\u4f20 API\uff1a<\/p>\n<ul>\n<li>AppendObject<\/li>\n<li>MultipartUpload<\/li>\n<li>PutObject<\/li>\n<\/ul>\n<p>\u5176\u4e2d MultipartUpload \u5728\u6240\u6709\u5206\u7247\u5168\u90e8\u4e0a\u4f20\u5b8c\u4e4b\u524d\u6574\u4e2a\u6587\u4ef6\u662f\u4e0d\u53ef\u89c1\u7684\uff0c\u8fd9\u79cd\u65b9\u5f0f\u4e0d\u9002\u7528\u4e8e\u6211\u4eec\u7684\u573a\u666f\u9996\u5148 pass \u6389<\/p>\n<p>\u5269\u4e0b AppendObject \u548c PutObject \u5bf9\u6bd4\uff1aAppendObject \u66f4\u52a0\u7075\u6d3b\uff0c\u53ea\u4e0d\u8fc7\u662f\u4e00\u4e9b\u7248\u672c\u63a7\u5236\u3001\u52a0\u5bc6\u7b49\u529f\u80fd\u65e0\u6cd5\u4f7f\u7528\uff0c\u5e76\u4e14 AppendObject \u7684\u5199\u5165\u6027\u80fd\u76f8\u6bd4 PutObject \u66f4\u9ad8\uff1a<\/p>\n<ul>\n<li>AppendObject\uff1a60MB\/s<\/li>\n<li>PutObject\uff1a50MB\/s<\/li>\n<\/ul>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u4ee5\u4e0a\u6570\u636e\u7684\u6d4b\u8bd5\u65b9\u6cd5\u5747\u4e3a\u963f\u91cc\u4e91 ECS \u4e0a\u4f7f\u7528 OSS \u7684\u5185\u7f51\u63a5\u5165\u70b9\u4e0a\u4f20 1G \u968f\u673a\u5185\u5bb9\u7684\u6587\u4ef6\u3002\u4e0b\u6587\u5bf9\u4e0b\u8f7d\u6027\u80fd\u7684\u6d4b\u8bd5\u4f7f\u7528\u7c7b\u4f3c\u65b9\u6cd5\u4e0d\u518d\u8d58\u8ff0\n<\/div>\n<p><\/p>\n<h3 id=\"\u4e0b\u8f7d\">\u4e0b\u8f7d<\/h3>\n<p>\u4e09\u79cd\u4e0a\u4f20 API \u5206\u522b\u5bf9\u5e94\u4e09\u79cd\u6587\u4ef6\u7c7b\u578b\uff1a<\/p>\n<ul>\n<li>Appendable<\/li>\n<li>Multipart<\/li>\n<li>Normal<\/li>\n<\/ul>\n<p>\u8fd9\u4e09\u79cd\u7c7b\u578b\u7684\u6587\u4ef6\u5747\u53ef\u4f7f\u7528 GetObject API \u6765\u4e0b\u8f7d\u67d0\u4e2a\u533a\u95f4\u7684\u6570\u636e\uff0cAppendable \u548c Normal \u7c7b\u578b\u7684\u6587\u4ef6\u4e0b\u8f7d\u6027\u80fd\u6d4b\u8bd5\u5982\u4e0b\uff1a<\/p>\n<ul>\n<li>Appendable\uff1a\n<ul>\n<li>\u5355\u7ebf\u7a0b 6.6MB\/s<\/li>\n<li>5 \u7ebf\u7a0b 27.9MB\/s<\/li>\n<li>20 \u7ebf\u7a0b 108.0MB\/s<\/li>\n<\/ul>\n<\/li>\n<li>Normal\uff1a\n<ul>\n<li>\u5355\u7ebf\u7a0b 35.9MB\/s<\/li>\n<li>5 \u7ebf\u7a0b 85.0MB\/s<\/li>\n<li>20 \u7ebf\u7a0b 152.9MB\/s<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Normal \u6587\u4ef6\u548c Appendable \u6587\u4ef6\u4e0b\u8f7d\u6027\u80fd\u76f8\u6bd4\u4e8e\u4e0a\u4f20\u5dee\u8ddd\u8981\u5927\u5f97\u591a\u3002\u7279\u522b\u662f\u5728\u5e76\u53d1\u7ebf\u7a0b\u6570\u5c11\u7684\u573a\u666f\uff0cNormal \u6587\u4ef6\u76f8\u6bd4\u4e8e Appendable \u6709\u5de8\u5927\u7684\u6027\u80fd\u4f18\u52bf\u3002\u53ef\u89c1 Appendable \u6587\u4ef6\u9002\u5408\u8bfb\u5199\u6bd4\u5c0f\uff08\u8bfb\u53d6\u4e0e\u5199\u5165\u91cf\u7684\u6bd4\u503c\u3002\u8fd9\u4e2a\u503c\u8d8a\u4f4e\u8bf4\u660e\u5bf9\u8bfb\u53d6\u7684\u9700\u6c42\u8d8a\u5c0f\uff0c\u5373\u5bf9\u8bfb\u53d6\u6027\u80fd\u8981\u6c42\u66f4\u4f4e\uff09\u7684\u6587\u4ef6<\/p>\n<h3 id=\"\u5143\u6570\u636e\u64cd\u4f5c\">\u5143\u6570\u636e\u64cd\u4f5c<\/h3>\n<p>\u8003\u8651\u5230 OSS \u4e0d\u80fd\u91cd\u65b0\u5199\u5165\u6587\u4ef6\uff0c\u6240\u4ee5\u4e00\u4f46\u4e0a\u4f20\u5931\u8d25\/\u4e2d\u65ad\u5c31\u9700\u8981\u91cd\u65b0\u4e0a\u4f20\u6574\u4e2a\u6587\u4ef6\u3002\u4e3a\u4e86\u907f\u514d\u5931\u8d25\u91cd\u4f20\u6574\u4e2a\u5927\u6587\u4ef6\uff0c\u6211\u4eec\u9700\u8981\u5c06\u672c\u5730\u6587\u4ef6\u5206\u5272\u6210\u4e00\u4e2a\u4e2a\u8f83\u5c0f\u7684\u6587\u4ef6\u5207\u7247\u518d\u4e0a\u4f20<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5206\u5272\u540e\u7684\u6587\u4ef6\u4e5f\u4e0d\u80fd\u8fc7\u4e8e\u5c0f\uff0c\u5426\u5219\u4f1a\u5f71\u54cd OSS \u5185\u90e8\u7684\u9884\u8bfb\u7b56\u7565\n<\/div>\n<p><\/p>\n<p>\u4f46\u662f\u8fd9\u79cd\u65b9\u6848\u4f1a\u5bfc\u81f4 OSS \u4e0a\u7684\u6587\u4ef6\u6570\u91cf\u6025\u5267\u589e\u591a\uff0c\u800c\u4e14 ListObjects API \u83b7\u53d6\u6587\u4ef6\u5143\u6570\u636e\u6027\u80fd\u5dee\u4e14\u6bcf\u6b21\u6700\u591a\u53ea\u80fd\u8fd4\u56de 1000 \u4e2a\u6587\u4ef6\u3002\u6211\u4eec\u6700\u7ec8\u91c7\u7528\u672c\u5730\u7ba1\u7406\u5143\u6570\u636e\u7684\u65b9\u6848\uff1a\u5373\u672c\u5730\u7ef4\u62a4\u4e00\u4efd OSS \u4e0a\u6587\u4ef6\u8def\u5f84\u3001\u5927\u5c0f\u7b49\u4fe1\u606f\u3002\u8bfb\u53d6\u8bf7\u6c42\u5148\u904d\u5386\u672c\u5730\u5143\u6570\u636e\uff0c\u627e\u5230\u76f8\u5e94\u7684\u6587\u4ef6\u8def\u5f84\u540e\u518d\u4ece OSS \u83b7\u53d6\u6570\u636e<\/p>\n<h3 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h3>\n<p>\u6700\u540e\u603b\u7ed3\u4e0b\u6211\u4eec\u7684\u7cfb\u7edf\u5982\u4f55\u5e73\u8861\u6210\u672c\u548c\u6027\u80fd\uff1a<\/p>\n<ul>\n<li>\u8bfb\u5199\u6bd4\u5c0f\u7684\u6587\u4ef6\u4f7f\u7528 AppendObject \u8ffd\u52a0\u4e0a\u4f20\uff0c\u8bfb\u53d6\u65f6\u52a0\u5927\u5e76\u53d1\u6362\u53d6\u66f4\u5927\u7684\u5e26\u5bbd<\/li>\n<li>\u8bfb\u5199\u6bd4\u5927\u7684\u6587\u4ef6\u672c\u5730\u7f13\u5b58\u8d77\u6765\uff0c\u6512\u591f\u4e00\u5b9a\u5927\u5c0f\u4f7f\u7528 PutObject \u4e0a\u4f20\uff0c\u4fdd\u8bc1\u6027\u80fd\u7684\u540c\u65f6\u8282\u7ea6\u6210\u672c<\/li>\n<li>\u5143\u6570\u636e\u672c\u5730\u7ba1\u7406\u8fdb\u4e00\u6b65\u964d\u4f4e API \u8c03\u7528\u8d39<\/li>\n<\/ul>"},{"title":"\u4ece Kubernetes Pod \u5185\u5b58\u5360\u7528\u8c08 Linux \u5185\u5b58\u7ba1\u7406","link":"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management","pubDate":"Fri, 10 Jun 2022 09:54:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management\/ram.jpg\" alt=\"Featured image of post \u4ece Kubernetes Pod \u5185\u5b58\u5360\u7528\u8c08 Linux \u5185\u5b58\u7ba1\u7406\" \/><p>\u672c\u6587\u5bf9\u4e00\u4e2a\u7ebf\u4e0a k8s \u5185\u5b58\u6c34\u4f4d\u8bef\u62a5\u8b66\u6df1\u5165\u5206\u6790 Linux \u5185\u5b58\u7ba1\u7406\u4e2d\u5404\u79cd\u5185\u5b58\u6307\u6807\u8ba1\u7b97\u7684\u539f\u7406<\/p>\n<p>TLDR\uff1a\u5982\u679c\u4f60\u7684\u5e94\u7528\u4f1a\u6d89\u53ca\u8f83\u591a\u7684\u6587\u4ef6\u8bfb\u5199\uff0c\u53ef\u4ee5\u5c06 k8s \u5185\u5b58\u6c34\u4f4d\u544a\u8b66\u6307\u6807\u7531 container_memory_working_set_bytes \u6539\u4e3a container_memory_rss\u3002\u8fd9\u6837\u53ef\u4ee5\u9632\u6b62 page cache \u5360\u7528\u7a7a\u95f2\u5185\u5b58\u5e26\u6765\u7684\u8bef\u62a5\u8b66<\/p>\n<h2 id=\"\u95ee\u9898\u63cf\u8ff0\">\u95ee\u9898\u63cf\u8ff0<\/h2>\n<p>\u524d\u4e9b\u5929\u6211\u4eec\u7684 k8s \u7ebf\u4e0a\u96c6\u7fa4\u89e6\u53d1\u5185\u5b58\u6c34\u4f4d\u62a5\u8b66\uff0c\u62a5\u8b66\u663e\u793a\u67d0\u4e2a Pod \u7684\u5185\u5b58\u4f7f\u7528\u7387\u9ad8\u8fbe 85%\u3002\u7136\u800c\u767b\u9646\u5230 pod \u4e0a\u53d1\u73b0\u5e94\u7528\u5b9e\u9645\u5360\u7528\u7684\u5185\u5b58\u5360\u7528\u53ea\u6709 50%\uff0c\u4f46\u662f\u7528 free \u547d\u4ee4\u770b\u5230\u7684\u5185\u5b58\u5360\u7528\u53c8\u662f\u7b26\u5408\u62a5\u8b66\u6c34\u4f4d\uff08total 31G\uff0cfree 2.6G\uff09<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 892;\nflex-basis: 2143px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management\/free.png\" data-size=\"759x85\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management\/free.png\"\nwidth=\"759\"\nheight=\"85\"\nloading=\"lazy\"\nalt=\"free \u547d\u4ee4\u8f93\u51fa\">\n<\/a>\n<figcaption>free \u547d\u4ee4\u8f93\u51fa<\/figcaption>\n<\/figure><\/p>\n<p>\u518d\u7ec6\u770b\u4e00\u4e0b free \u6253\u5370\u51fa\u7684\u4fe1\u606f\u53d1\u73b0 buff\/cache \u5360\u7528\u6709 12G\uff0c\u8fd9\u90e8\u5206\u5185\u5b58\u7528\u5230\u54ea\u91cc\u4e86\uff1f10G \u7684 available \u662f\u4e0d\u662f\u6307\u8fd9\u4e9b cache \u4e2d\u6709 10G \u662f\u53ef\u4ee5\u91ca\u653e\u7684\uff1f\u90a3\u4e0d\u80fd\u91ca\u653e\u7684 2G \u662f\u7528\u6765\u505a\u4ec0\u4e48\u7684\uff1f\u5e94\u7528\u771f\u5b9e\u5185\u5b58\u5360\u7528\u5e94\u8be5\u770b\u54ea\u4e2a\u6307\u6807\uff1f\u63a5\u4e0b\u6765\u6211\u4eec\u4f9d\u6b21\u56de\u7b54\u8fd9\u4e9b\u95ee\u9898<\/p>\n<h2 id=\"linux-\u5185\u5b58\u5206\u7c7b\">Linux \u5185\u5b58\u5206\u7c7b<\/h2>\n<p>\u6211\u4eec\u77e5\u9053 Linux \u4e2d\u4e00\u4e2a\u975e\u5e38\u91cd\u8981\u7684\u6982\u5ff5\u662f\u4e07\u7269\u7686\u6587\u4ef6\uff0cLinux \u7684\u5185\u5b58\u5b9e\u9645\u4e0a\u662f\u5916\u5b58\u4e0a\u5404\u79cd\u6587\u4ef6\u7684\u7f13\u5b58\u3002\u4e5f\u5c31\u662f\u8bf4\u6211\u4eec\u7533\u8bf7\u7684\u5185\u5b58\u5b9e\u9645\u4e0a\u5bf9\u5e94\u4e00\u4e2a\u771f\u5b9e\u7684\u6587\u4ef6\uff08\u5404\u79cd\u8bbe\u5907\/Socket\uff09\uff0c\u8fd9\u79cd\u5185\u5b58\u88ab\u79f0\u4e3a page cache<\/p>\n<p>\u6211\u4eec\u6765\u770b\u770b Linux \u6743\u5a01\u6587\u6863\u4e2d\u662f\u5982\u4f55\u4ecb\u7ecd\u8fd9\u79cd\u5185\u5b58\u7684\uff1a<\/p>\n<blockquote>\n<p>The physical memory is volatile and the common case for getting data into the memory is to read it from files. <mark>Whenever a file is read, the data is put into the page cache to avoid expensive disk access on the subsequent reads.<\/mark> Similarly, when one writes to a file, the data is placed in the page cache and eventually gets into the backing storage device. The written pages are marked as dirty and when Linux decides to reuse them for other purposes, it makes sure to synchronize the file contents on the device with the updated data.<br \/>\n\u2014\u2014<a class=\"link\" href=\"https:\/\/www.kernel.org\/doc\/html\/latest\/admin-guide\/mm\/concepts.html#page-cache\" target=\"_blank\" rel=\"noopener\"\n>The Linux kernel user\u2019s and administrator\u2019s guide<\/a><\/p>\n<\/blockquote>\n<p>\u5176\u4e2d\u6700\u5173\u952e\u7684\u4e00\u53e5\u8bdd\uff1a\u6bcf\u5f53\u8bfb\u53d6\u4e00\u4e2a\u6587\u4ef6\uff0c\u6570\u636e\u4f1a\u88ab\u7f13\u5b58\u5728 page cache \u4e2d\u4ee5\u907f\u514d\u540e\u7eed\u8bbf\u95ee\u65f6\u91cd\u590d\u8bfb\u53d6\u78c1\u76d8\u5e26\u6765\u7684\u6602\u8d35\u5f00\u9500\u3002\u4e5f\u5c31\u662f\u8bf4\u6211\u4eec\u5e73\u65f6\u8bbf\u95ee\u6587\u4ef6\uff08read \u6216 mmap \u7cfb\u7edf\u8c03\u7528\uff09\u90fd\u4f1a\u521b\u5efa\u5bf9\u5e94\u7684 page cache\uff0c\u8fd9\u90e8\u5206\u5185\u5b58\u7531\u64cd\u4f5c\u7cfb\u7edf\u7ba1\u7406\uff0c\u5e76\u4e0d\u8bb0\u5f55\u5728\u7528\u6237\u7a0b\u5e8f\u7684\u5185\u5b58\u5f00\u9500\u4e2d<\/p>\n<p>\u8fd9\u4e2a\u6587\u6863\u4e2d\u540c\u65f6\u4e5f\u4ecb\u7ecd\u4e86\u53e6\u5916\u4e00\u79cd\u5185\u5b58\u7c7b\u578b\uff1a\u533f\u540d\u5185\u5b58\uff08anonymous memory\uff09<\/p>\n<blockquote>\n<p><mark>The anonymous memory or anonymous mappings represent memory that is not backed by a filesystem.<\/mark> Such mappings are implicitly created for program\u2019s stack and heap or by explicit calls to mmap(2) system call. Usually, the anonymous mappings only define virtual memory areas that the program is allowed to access. The read accesses will result in creation of a page table entry that references a special physical page filled with zeroes. When the program performs a write, a regular physical page will be allocated to hold the written data. The page will be marked dirty and if the kernel decides to repurpose it, the dirty page will be swapped out.<br \/>\n\u2014\u2014<a class=\"link\" href=\"https:\/\/www.kernel.org\/doc\/html\/latest\/admin-guide\/mm\/concepts.html#anonymous-memory\" target=\"_blank\" rel=\"noopener\"\n>The Linux kernel user\u2019s and administrator\u2019s guide<\/a><\/p>\n<\/blockquote>\n<p>\u8fd9\u91cc\u7684\u533f\u540d\u6307\u7684\u662f\u4e0d\u9700\u8981\u624b\u52a8\u6307\u5b9a\u5bf9\u5e94\u7684\u6587\u4ef6\uff0c\u7cfb\u7edf\u4f1a\u4e3a\u5176\u6307\u5b9a\u4e00\u4e2a\u586b\u5145\u4e3a 0 \u7684\u7279\u6b8a\u6587\u4ef6\uff08\/dev\/zero\uff09\u3002\u7a0b\u5e8f\u7684\u5806\u6808\u5c31\u5c5e\u4e8e\u8fd9\u79cd\u5185\u5b58\uff0c\u6b64\u5916\u8fd8\u6709\u4e00\u79cd\u533f\u540d\u6620\u5c04\uff08anonymous mappings\uff09\u4e5f\u5c5e\u4e8e\u533f\u540d\u5185\u5b58<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n<p>mmap \u8bbe\u7f6e flag \u4e3a MAP_PRIVATE \u65f6\u521b\u5efa\u7684\u5185\u5b58\u624d\u5c5e\u4e8e\u533f\u540d\u5185\u5b58\uff0c\u6ce8\u610f\u4e0e MAP_ANONYMOUS \u533a\u5206<\/p>\n<ul>\n<li>MAP_ANONYMOUS \u4f5c\u7528\u662f\u4e0d\u663e\u5f0f\u6307\u5b9a\u6620\u5c04\u7684\u6587\u4ef6\uff08\u9ed8\u8ba4\u4e3a \/dev\/zero\uff09<\/li>\n<li>MAP_PRIVATE \u4f5c\u7528\u662f\u4f7f\u5185\u5b58\u7684\u4fee\u6539\u5bf9\u5176\u4ed6\u8fdb\u7a0b\u4e0d\u53ef\u89c1\uff08\u5373 copy on write \u6a21\u5f0f\uff09\u5e76\u4e14\u4e0d\u4f1a\u5c06\u810f\u9875\u5199\u56de\u6587\u4ef6<\/li>\n<\/ul>\n<p>MAP_ANONYMOUS \u4e00\u822c\u548c MAP_SHARED \u6216 MAP_PRIVATE \u540c\u65f6\u4f7f\u7528\uff1a<br \/>\nmmap \u7684 flag \u8bbe\u7f6e\u4e3a MAP_ANONYMOUS|MAP_SHARED \u65f6\u521b\u5efa\u7684\u5185\u5b58\u5c5e\u4e8e page cache\uff0c\u5e38\u7528\u4e8e\u5728\u76f8\u5173\u8fdb\u7a0b\u95f4\u5171\u4eab\u5185\u5b58<br \/>\nmmap \u7684 flag \u8bbe\u7f6e\u4e3a MAP_ANONYMOUS|MAP_PRIVATE \u65f6\u521b\u5efa\u7684\u5185\u5b58\u5c5e\u4e8e\u533f\u540d\u5185\u5b58\uff0c\u5e38\u7528\u4e8e\u5185\u5b58\u5206\u914d\uff08glibc \u5206\u914d\u5927\u5757\u5185\u5b58\uff09<\/p>\n<\/div>\n<p><\/p>\n<p>\u73b0\u5728\u53ef\u4ee5\u56de\u7b54\u7b2c\u4e00\u4e2a\u95ee\u9898\uff0cbuff\/cache \u5360\u7528\u7684 12G \u5185\u5b58\u90fd\u7528\u5728\u54ea\u91cc\uff1a\u6211\u4eec\u7684\u7cfb\u7edf\u4f7f\u7528 mmap \u6620\u5c04\u4e86\u5f88\u591a\u6587\u4ef6\uff0cbuff\/cache \u5360\u7528\u7684 12G \u5185\u5b58\u5c31\u662f\u8fd9\u4e9b\u6587\u4ef6 page cache \u5360\u7528\u7684\u7a7a\u95f4<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u8fd9\u91cc\u7684 buffer \u6307\u7684\u662f buffer cache \u5757\u8bbe\u5907\u7f13\u5b58\uff0c\u800c page cache \u662f\u9875\u7f13\u5b58\u3002\u4ece\u540d\u5b57\u5c31\u53ef\u4ee5\u53d1\u73b0\u5b83\u4eec\u7684\u6570\u636e\u662f\u4e00\u6837\u7684\uff0c\u73b0\u4ee3 Linux \u4e2d\u8fd9\u4e24\u8005\u4e5f\u662f\u878d\u5408\u7684\uff1abuffer cache \u7684\u6570\u636e\u76f4\u63a5\u50a8\u5b58\u5728 page cache \u4e2d\n<\/div>\n<p><\/p>\n<h2 id=\"linux-\u5185\u5b58\u56de\u6536\u7b56\u7565\">Linux \u5185\u5b58\u56de\u6536\u7b56\u7565<\/h2>\n<p>\u6309\u7167\u6211\u4eec\u6734\u7d20\u7684\u89c2\u70b9\u53ea\u6709\u533f\u540d\u5185\u5b58\u662f\u4e0d\u53ef\u56de\u6536\u7684\uff0c cache \u90fd\u662f\u53ef\u56de\u6536\u7684\u3002\u4f46\u662f\u4e3a\u4ec0\u4e48 free \u6253\u5370\u51fa\u7684\u4fe1\u606f\u4e2d available(10G) \u5c0f\u4e8e buffer\/cache(12G) \u7684\u503c\uff1f<\/p>\n<p>\u6211\u4eec\u53ef\u4ee5\u6309\u7167 Linux \u6587\u6863\u7684\u8bf4\u660e\u5c1d\u8bd5\u6e05\u9664 page cache\uff08<code>echo 1 &gt; \/proc\/sys\/vm\/drop_caches<\/code>\uff09\u6765\u9a8c\u8bc1\u8fd9\u4e2a\u5047\u8bbe<\/p>\n<blockquote>\n<p>Writing to this will cause the kernel to drop clean caches, as well as reclaimable slab objects like dentries and inodes. Once dropped, their memory becomes free.<\/p>\n<p>To free pagecache:<br \/>\n\u00a0\u00a0\u00a0\u00a0echo 1 &gt; \/proc\/sys\/vm\/drop_caches<br \/>\nTo free reclaimable slab objects (includes dentries and inodes):<br \/>\n\u00a0\u00a0\u00a0\u00a0echo 2 &gt; \/proc\/sys\/vm\/drop_caches<br \/>\nTo free slab objects and pagecache:<br \/>\n\u00a0\u00a0\u00a0\u00a0echo 3 &gt; \/proc\/sys\/vm\/drop_caches<\/p>\n<p><mark>This is a non-destructive operation and will not free any dirty objects.<\/mark> To increase the number of objects freed by this operation, the user may run `sync&rsquo; prior to writing to \/proc\/sys\/vm\/drop_caches. This will minimize the number of dirty objects on the system and create more candidates to be dropped.<br \/>\n\u2014\u2014<a class=\"link\" href=\"https:\/\/www.kernel.org\/doc\/Documentation\/sysctl\/vm.txt\" target=\"_blank\" rel=\"noopener\"\n>Documentation for \/proc\/sys\/vm\/*<\/a><\/p>\n<\/blockquote>\n<p>\u6211\u4eec\u53d1\u73b0 free \u547d\u4ee4\u770b\u5230\u7684 buff\/cache \u5e76\u6ca1\u6709\u5168\u90e8\u88ab\u56de\u6536\u3002\u6587\u6863\u4e2d\u4e5f\u7ed9\u51fa\u4e86\u89e3\u91ca\uff1a\u810f\u9875\u5e76\u4e0d\u4f1a\u56de\u6536\uff08will not free any dirty objects\uff09\uff0c\u8fd9\u91cc\u8bf4\u7684\u810f\u9875\u5206\u4e3a\u4ee5\u4e0b\u51e0\u79cd\uff1a<\/p>\n<ol>\n<li>\u88ab\u4fee\u6539\u4f46\u672a\u5199\u56de\u78c1\u76d8\u7684 page cache\uff1a\u7528 sync \u5f3a\u5236\u810f\u9875\u843d\u76d8\u540e\u518d\u5c1d\u8bd5 drop cache \u5373\u53ef\u56de\u6536<\/li>\n<li>tmpfs\/shmem\uff1atmpfs \u548c\u5171\u4eab\u5185\u5b58\uff08SysV shared memory \u548c POSIX shared memory\uff09<\/li>\n<li>shared anonymous mmap\uff1a\u4f7f\u7528 flag \u4e3a MAP_ANONYMOUS|MAP_SHARED \u7684 mmap \u83b7\u5f97\u7684\u5185\u5b58<\/li>\n<\/ol>\n<p>\u540e\u4e24\u8005\u5728 free \u547d\u4ee4\u7684\u8f93\u51fa\u4e2d\u65e2\u5c5e\u4e8e buff\/cache\uff0c\u4e5f\u5c5e\u4e8e shared\u3002\u8fd9\u4e9b\u5185\u5b58\u5728\u4e3b\u52a8\u91ca\u653e\u524d\u4e0d\u80fd\u88ab\u56de\u6536<\/p>\n<p>\u9664\u4e86\u810f\u9875\u5916\u8fd8\u6709\u4e00\u4e9b\u7279\u6b8a\u7684\u4e0d\u53ef\u56de\u6536\u7684\u9875\u9762\uff1a<\/p>\n<ol>\n<li>\u5185\u6838\u4f7f\u7528\u7684\u9875\u9762\uff1aDMA buffer \u7b49<\/li>\n<li>\u6807\u8bb0\u4e3a unreclaimable \u7684\u9875\u9762\uff1a\u5982\u4f7f\u7528 mlock \u9501\u5b9a\u7684\u5185\u5b58<\/li>\n<\/ol>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5185\u6838\u4f7f\u7528\u7684\u9875\u9762\u4e5f\u6709\u53ef\u56de\u6536\u7684\uff0c\u6bd4\u5982\u6587\u4ef6\u7cfb\u7edf\u5143\u6570\u636e\uff08dentries\/inodes\uff09\u8fd9\u79cd\u53ef\u4ee5\u4ece\u5b58\u50a8\u8bbe\u5907\u4e2d\u91cd\u65b0\u8bfb\u53d6\u7684\u9875\u9762\u3002\u8fd9\u4e9b\u9875\u9762\u88ab\u79f0\u4e3a SReclaimable\uff0c\u53ef\u4ee5\u4f7f\u7528 <code>echo 2 &gt; \/proc\/sys\/vm\/drop_caches<\/code> \u8fdb\u884c\u56de\u6536\n<\/div>\n<p><\/p>\n<h2 id=\"linux-\u5185\u5b58\u6c34\u4f4d\u63a7\u5236\u4e0e\u53ef\u7528\u5185\u5b58\u8ba1\u7b97\">Linux \u5185\u5b58\u6c34\u4f4d\u63a7\u5236\u4e0e\u53ef\u7528\u5185\u5b58\u8ba1\u7b97<\/h2>\n<p>\u65e2\u7136\u4f46\u662f\u4e3a\u4ec0\u4e48 available \u7684\u503c\u4e0d\u7b49\u4e8e reclaimable + free\uff1f\u6211\u4eec\u7ee7\u7eed\u4ece Linux \u6587\u6863\u4e2d\u5bfb\u627e\u7b54\u6848<\/p>\n<blockquote>\n<p>When the system is not loaded, most of the memory is free and allocation requests will be satisfied immediately from the free pages supply. As the load increases, the amount of the free pages goes down and when it reaches a certain threshold (<mark>low watermark<\/mark>), an allocation request will awaken the kswapd daemon. It will asynchronously scan memory pages and either just free them if the data they contain is available elsewhere, or evict to the backing storage device (remember those dirty pages?). As memory usage increases even more and reaches another threshold - <mark>min watermark<\/mark> - an allocation will trigger direct reclaim. In this case allocation is stalled until enough memory pages are reclaimed to satisfy the request.<br \/>\n\u2014\u2014<a class=\"link\" href=\"https:\/\/www.kernel.org\/doc\/html\/latest\/admin-guide\/mm\/concepts.html#reclaim\" target=\"_blank\" rel=\"noopener\"\n>The Linux kernel user\u2019s and administrator\u2019s guide<\/a><\/p>\n<\/blockquote>\n<p>\u8fd9\u91cc\u63d0\u5230\u4e86\u4e24\u4e2a watermark\uff1a<\/p>\n<ol>\n<li>low watermark\uff1a\u5f53 free \u5185\u5b58\u4f4e\u4e8e low watermark \u65f6\u89e6\u53d1\u5f02\u6b65\u5185\u5b58\u56de\u6536<\/li>\n<li>min watermark\uff1a\u5f53\u5185\u5b58\u4f4e\u4e8e min watermark \u65f6\u6682\u505c\u5185\u5b58\u5206\u914d\uff0c\u7acb\u5373\u8fdb\u884c\u5185\u5b58\u56de\u6536<\/li>\n<\/ol>\n<p>\u4e5f\u5c31\u662f\u8bf4\u7cfb\u7edf\u4e2d\u5269\u4f59\u7684\u5185\u5b58\u4e0d\u80fd\u4f4e\u4e8e min watermark\uff0c\u8fd9\u662f\u4e00\u4e2a\u64cd\u4f5c\u7cfb\u7edf\u7684\u4fdd\u62a4\u673a\u5236\uff1a\u9884\u7559\u4e00\u90e8\u5206\u5185\u5b58\u7ed9\u5185\u5b58\u56de\u6536\u7b49\u5173\u952e\u7a0b\u5e8f\u4f7f\u7528\u3002\u8fd9\u4e9b\u7a0b\u5e8f\u4f7f\u7528 PF_MEMALLOC \u6807\u8bc6\u5ffd\u7565 watermark \u7684\u9650\u5236\uff0c\u5728\u9700\u8981\u7684\u65f6\u5019\u4e0d\u5fc5\u7b49\u5f85\u5185\u5b58\u56de\u6536\u5c31\u53ef\u4ee5\u7acb\u523b\u83b7\u5f97\u5185\u5b58<\/p>\n<p>\u53ef\u4ee5\u901a\u8fc7 <code>cat \/proc\/zoneinfo<\/code> \u770b\u5230 min watermark \u7684\u53d6\u503c\uff0c\u5355\u4f4d\u662f\u9875\u3002\u4e0b\u9762\u8fd9\u4e2a\u793a\u4f8b\u4e2d\u7cfb\u7edf\u9884\u7559\u4e86 10478 \u9875\uff0c\u4e5f\u5c31\u662f\u5927\u7ea6 40M \u7684\u5185\u5b58<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">cat \/proc\/zoneinfo\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Node 0, zone Normal\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> pages free <span class=\"m\">780839<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> min <span class=\"m\">10478<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> low <span class=\"m\">13097<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><\/code><\/pre><\/div><p>\u6240\u4ee5 free \u7684\u5185\u5b58\u5e76\u4e0d\u90fd\u662f\u53ef\u5206\u914d\u7684\uff0c\u9700\u8981\u51cf\u53bb\u7cfb\u7edf\u4fdd\u7559\u5185\u5b58\uff0c\u5373 available = reclaimable + free - reversed<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 146;\nflex-basis: 352px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management\/available.png\" data-size=\"374x255\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/from-k8s-pod-memory-usage-to-linux-memory-management\/available.png\"\nwidth=\"374\"\nheight=\"255\"\nloading=\"lazy\"\nalt=\"available \u5185\u5b58\u8ba1\u7b97\">\n<\/a>\n<figcaption>available \u5185\u5b58\u8ba1\u7b97<\/figcaption>\n<\/figure><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u9664\u4e86 watermark \u4ee5\u5916\u8fd8\u6709 min_free_kbytes \u548c watermark_scale_factor \u7b49\u53c2\u6570\u5f71\u54cd\u7cfb\u7edf\u4fdd\u7559\u5185\u5b58\u7684\u8ba1\u7b97\uff0c\u8fd9\u90e8\u5206\u5185\u5b58\u672c\u6587\u4e2d\u7edf\u79f0\u4e3a reversed \u4e0d\u518d\u8be6\u8ff0\n<\/div>\n<p><\/p>\n<h2 id=\"k8s-\u5185\u5b58\u76d1\u63a7\">k8s \u5185\u5b58\u76d1\u63a7<\/h2>\n<p>\u4e0a\u6587\u4e2d\u8bf4\u7684 buff\/cache\u3001free\u3001available \u90fd\u662f\u4ece free \u547d\u4ee4\u770b\u5230\u7684\u7ed3\u679c\uff0c\u800c k8s \u7684\u5185\u5b58\u76f8\u5173\u76d1\u63a7\u6307\u6807\u7565\u6709\u4e0d\u540c<\/p>\n<ul>\n<li>free \u547d\u4ee4\u662f\u4ece <code>\/proc\/meminfo<\/code> \u4e2d\u53d6\u503c\u8ba1\u7b97\uff0c\u76f8\u5173\u539f\u7406\u548c\u5404\u5b57\u6bb5\u89e3\u91ca\u53ef\u4ee5\u9605\u8bfb\u8fd9\u7bc7\u6587\u7ae0\uff1a <a class=\"link\" href=\"http:\/\/linuxperf.com\/?p=142\" target=\"_blank\" rel=\"noopener\"\n>\/PROC\/MEMINFO\u4e4b\u8c1c<\/a><\/li>\n<li>k8s cadvisor metrics \u6307\u6807\u662f\u4ece <code>\/sys\/fs\/cgroups\/memory\/memory.stat<\/code> \u4e2d\u53d6\u503c\u8ba1\u7b97\uff0c\u53ef\u4ee5\u9605\u8bfb\u8fd9\u7bc7\u6587\u7ae0\u6765\u9a8c\u8bc1\uff1a<a class=\"link\" href=\"https:\/\/kubernetes.io\/zh-cn\/docs\/concepts\/scheduling-eviction\/pod-overhead\/#%E9%AA%8C%E8%AF%81-pod-cgroup-%E9%99%90%E5%88%B6\" target=\"_blank\" rel=\"noopener\"\n>\u9a8c\u8bc1 Pod cgroup \u9650\u5236<\/a><\/li>\n<\/ul>\n<p>\u8fd9\u91cc\u7ed9\u51fa\u90e8\u5206 k8s cadvisor metrics \u6307\u6807\u7684\u89e3\u91ca\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>cadvisor \u6307\u6807<\/th>\n<th>\u53d6\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>container_memory_usage_bytes<\/td>\n<td>\u5206\u914d\u7684\u603b\u5185\u5b58<\/td>\n<\/tr>\n<tr>\n<td>container_memory_working_set_bytes<\/td>\n<td>\u5206\u914d\u7684\u603b\u5185\u5b58 - \u4e0d\u6d3b\u8dc3\u7684 page cache<\/td>\n<\/tr>\n<tr>\n<td>container_memory_rss<\/td>\n<td>\u4f7f\u7528\u7684\u533f\u540d\u5185\u5b58<\/td>\n<\/tr>\n<tr>\n<td>container_memory_cache<\/td>\n<td>page cache \u5360\u7528\u5185\u5b58<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>container_memory_working_set_bytes \u662f\u6700\u5e38\u7528\u7684\u5185\u5b58\u76d1\u63a7\u6307\u6807\uff0c\u4e5f\u662f\u5224\u65ad limit \u7684\u4f9d\u636e\u3002<\/p>\n<p>\u56de\u5230\u6587\u7ae0\u5f00\u5934\u7684\u95ee\u9898\uff0c\u6211\u4eec\u7ebf\u4e0a\u4f7f\u7528\u7684\u62a5\u8b66\u6307\u6807\u5c31\u662f container_memory_working_set_bytes\uff0c\u8fd9\u4e2a\u6307\u6807\u662f\u5305\u542b\u4e86\u4e00\u90e8\u5206 page cache \u7684\u6240\u4ee5\u8981\u504f\u9ad8\u4e00\u4e9b\u3002\u7528\u8fd9\u4e2a\u6307\u6807\u6765\u914d\u7f6e\u544a\u8b66\u5982\u679c\u5e94\u7528\u4f7f\u7528 page cache \u8f83\u591a\uff08\u6bd4\u5982\u6253\u5f00\u5927\u91cf\u6587\u4ef6\uff09\u5c31\u4f1a\u4ea7\u751f\u8bef\u62a5<\/p>\n<p>\u76d1\u63a7\u5185\u5b58\u6c34\u4f4d\u662f\u4e3a\u4e86\u53ca\u65f6\u53d1\u73b0\u5e94\u7528\u5b58\u5728 OOM \u7684\u98ce\u9669\uff0c\u5b9e\u9645\u4e0a\u6211\u4eec\u5e94\u8be5\u5173\u5fc3\u7684\u662f available \u6307\u6807\u3002\u4f46\u662f k8s \u53c8\u6ca1\u6709\u63d0\u4f9b\u548c available \u7b49\u4ef7\u7684 metrics\uff0c\u53ea\u80fd\u8fc2\u56de\u4f7f\u7528 container_memory_rss \u6765\u914d\u7f6e\u544a\u8b66\uff0c\u8fd9\u4e2a\u6307\u6807\u662f\u5e94\u7528\u771f\u5b9e\u5360\u7528\u7684\u5185\u5b58\u5373 unreclaimable \u90e8\u5206<\/p>"},{"title":"\u5de7\u7528 DNS \u5b9e\u73b0\u56fd\u5185\u5916\u57df\u540d ip \u5206\u6d41\u4e0a\u7f51","link":"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges","pubDate":"Fri, 03 Jun 2022 21:03:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges\/dns.png\" alt=\"Featured image of post \u5de7\u7528 DNS \u5b9e\u73b0\u56fd\u5185\u5916\u57df\u540d ip \u5206\u6d41\u4e0a\u7f51\" \/><p>\u8fd9\u7bc7\u6587\u7ae0\u8bb0\u5f55\u4e86\u5bf9\u51e0\u79cd\u5206\u6d41\u4e0a\u7f51\u65b9\u6848\uff08iptables\u3001OSPF\u3001DNS \u7b49\uff09\u7684\u5c1d\u8bd5\u4e0e\u4f18\u52a3\u6bd4\u8f83\uff0c\u6587\u4e2d\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u535a\u4e3b\u76ee\u524d\u4f7f\u7528\u7684\u57fa\u4e8e DNS \u7684\u5206\u6d41\u65b9\u6848\u7684\u539f\u7406\u4e0e\u914d\u7f6e\u6559\u7a0b<\/p>\n<h2 id=\"\u524d\u8a00\">\u524d\u8a00<\/h2>\n<p>\u672c\u6587\u9002\u5408\u4f7f\u7528\u8f6f\u8def\u7531\u505a\u900f\u660e\u4ee3\u7406\u7684\u540c\u5b66\u9605\u8bfb\uff0c\u5e76\u4e14\u9700\u8981\u6709\u4e00\u5b9a\u7684\u7f51\u7edc\u57fa\u7840\u77e5\u8bc6\u3002\u5982\u679c\u4f60\u662f\u4e00\u4e2a\u5c0f\u767d\u90a3\u4e48\u76f4\u63a5\u8df3\u5230<code>\u6781\u7b80\u914d\u7f6e<\/code>\u90e8\u5206\u7167\u7740\u64cd\u4f5c\u5373\u53ef<\/p>\n<p>\u535a\u4e3b\u5c1d\u8bd5\u8fc7\u5982\u4e0b\u51e0\u79cd\u601d\u8def\u5b9e\u73b0\u7b56\u7565\u8def\u7531\uff08PBR, <a class=\"link\" href=\"https:\/\/en.wikipedia.org\/wiki\/Policy-based_routing\" target=\"_blank\" rel=\"noopener\"\n>Policy Based Routing<\/a>\uff09<\/p>\n<ol>\n<li>iptables \u7ed9\u94fe\u63a5\u6253\u6807<\/li>\n<li>OSPF \u7b49\u8def\u7531\u534f\u8bae<\/li>\n<li>Clash\u3001V2ray \u7b49\u4ee3\u7406\u5de5\u5177<\/li>\n<li>DNS \u5206\u6d41<\/li>\n<\/ol>\n<p>\u524d\u4e24\u8005\u7684\u601d\u8def\u7c7b\u4f3c\uff0c\u90fd\u662f\u4f7f\u7528\u4e2d\u56fd ip \u767d\u540d\u5355\u6765\u5c06\u56fd\u5916 ip \u8f6c\u53d1\u5230\u65c1\u8def\u7531\u7b49\u900f\u660e\u4ee3\u7406\u8bbe\u5907\u4e0a\u3002\u4f46\u662f\u65e0\u8bba\u662f iptables \u8fd8\u662f OSPF \u914d\u7f6e\u90fd\u975e\u5e38\u590d\u6742\uff0c\u7279\u522b\u662f OSPF \u7b49\u8def\u7531\u534f\u8bae\u79d1\u73ed\u51fa\u8eab\u7684\u4eba\u90fd\u4e0d\u4e00\u5b9a\u73a9\u5f97\u8f6c\u3002\u6211\u4eec\u914d\u7f6e\u5bb6\u5ead\u7f51\u7edc\u8ffd\u6c42\u7684\u662f\u7b80\u5355\u597d\u7528\uff0c\u4f7f\u7528\u8fd9\u6837\u590d\u6742\u7684\u65b9\u6848\u524d\u671f\u8c03\u8bd5\u4ee5\u53ca\u540e\u671f\u66f4\u65b0 ip \u5217\u8868\u90fd\u5f88\u4e0d\u65b9\u4fbf<\/p>\n<p>\u4f7f\u7528\u4ee3\u7406\u5de5\u5177\u7684\u5206\u6d41\u529f\u80fd\u505a\u7b56\u7565\u8def\u7531\u7b80\u5355\u5b9e\u7528\uff0cClash\u3001V2ray \u7b49\u5ba2\u6237\u7aef\u90fd\u4f1a\u6709\u5f00\u7bb1\u5373\u7528\u7684\u914d\u7f6e\u63d0\u4f9b\u3002\u4f46\u662f\u7f3a\u70b9\u4e5f\u5f88\u660e\u663e\uff1a\u6240\u6709\u7684\u6d41\u91cf\u90fd\u4f1a\u7ecf\u8fc7\u4ee3\u7406\u7a0b\u5e8f\uff0c\u65e0\u6cd5\u505a\u5230\u5206\u8bbe\u5907\u4ee3\u7406\uff0c\u5bf9\u4e8e\u6709\u6709 BT\u3001PCDN \u7b49\u9700\u6c42\u53ea\u60f3\u90e8\u5206\u8bbe\u5907\u8d70\u4ee3\u7406\u7684\u540c\u5b66\u4e0d\u592a\u9002\u7528<\/p>\n<p>\u4f7f\u7528 DNS \u5206\u6d41\u65b9\u6848\u62e5\u6709 iptables \u548c OSPF \u505a\u7b56\u7565\u8def\u7531\u7684\u4e30\u5bcc\u529f\u80fd\uff0c\u5e76\u4e14\u517c\u5177\u4f7f\u7528\u4ee3\u7406\u5de5\u5177\u5206\u6d41\u914d\u7f6e\u7b80\u5355\u7684\u4f18\u70b9<\/p>\n<ol>\n<li>\u4e30\u5bcc\u7684\u5206\u6d41\u7b56\u7565\uff1a\u53ef\u4ee5\u6309\u56fd\u5185\u5916 ip \u5206\u6d41\u4e5f\u53ef\u4ee5\u6309\u57df\u540d\u5206\u6d41<\/li>\n<li>\u914d\u7f6e\u7b80\u5355\uff1a\u6700\u7b80\u5355\u7684\u4f7f\u7528\u65b9\u6cd5\u53ea\u9700\u4fee\u6539 Clash \u7684\u914d\u7f6e\u5373\u53ef<\/li>\n<li>\u53bb\u5e7f\u544a\uff1a\u53ef\u4ee5\u963b\u65ad\u5e7f\u544a\u57df\u540d\u7684 DNS \u89e3\u6790\u6765\u7981\u6b62\u5e7f\u544a\u52a0\u8f7d<\/li>\n<li>\u5206\u8bbe\u5907\u4ee3\u7406\uff1a\u5bf9\u9700\u8981\u4ee3\u7406\u7684\u8bbe\u5907\u4f7f\u7528\u5206\u6d41 DNS \u8f6c\u53d1\u5230\u4ee3\u7406\u670d\u52a1\u5668\uff0c\u5176\u4ed6\u8bbe\u5907\u4f7f\u7528\u4e0a\u6e38\u516c\u5171 DNS \u76f4\u8fde\u51fa\u516c\u7f51<\/li>\n<\/ol>\n<p>\u4f46\u662f\u8fd9\u4e2a\u65b9\u6848\u4e5f\u6709\u7f3a\u70b9\uff0c\u5bf9\u4e8e\u76f4\u63a5\u4f7f\u7528 ip \u7684\u8f6f\u4ef6\u5c31\u65e0\u80fd\u4e3a\u529b\u4e86\u3002\u5f53\u7136\u8fd9\u79cd\u60c5\u51b5\u975e\u5e38\u7f55\u89c1\uff08\u76ee\u524d\u535a\u4e3b\u53ea\u53d1\u73b0 Telegram\uff09\uff0c\u800c\u4e14\u53ea\u9700\u989d\u5916\u6dfb\u52a0\u4e00\u6761\u9759\u6001\u8def\u7531\u5373\u53ef\u89e3\u51b3<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u4ec0\u4e48\uff1f\u4f60\u95ee\u6211 DNS \u662f\u5565\u73a9\u610f\uff1f\u90a3\u6211\u5efa\u8bae\u4f60<del>\u5173\u6389\u672c\u6587<\/del>\uff0c\u6216\u8005\u9605\u8bfb\u8fd9\u7bc7\u6587\u7ae0\uff1a<a class=\"link\" href=\"https:\/\/draveness.me\/dns-coredns\/\" target=\"_blank\" rel=\"noopener\"\n>\u8be6\u89e3 DNS \u4e0e CoreDNS \u7684\u5b9e\u73b0\u539f\u7406<\/a>\n<\/div>\n<p><\/p>\n<h2 id=\"\u7f51\u7edc\u67b6\u6784\">\u7f51\u7edc\u67b6\u6784<\/h2>\n<p>\u9700\u8981\u4e24\u4e2a\u989d\u5916\u7ec4\u4ef6\uff08\u6781\u7b80\u914d\u7f6e\u4e0b\u8fd9\u4e24\u4e2a\u7ec4\u4ef6\u5408\u4e8c\u4e3a\u4e00\uff09\uff1a<\/p>\n<ol>\n<li>\u505a\u900f\u660e\u4ee3\u7406\u7684\u8f6f\u8def\u7531\uff0c\u53ef\u4ee5\u662f\u4e3b\u8def\u7531\u4e5f\u53ef\u4ee5\u662f\u65c1\u8def\u7531<\/li>\n<li>\u5206\u6d41 DNS<\/li>\n<\/ol>\n<p>\u539f\u7406\u5176\u5b9e\u5f88\u7b80\u5355\uff1a\u5206\u6d41 DNS \u52ab\u6301 DNS \u8bf7\u6c42\uff0c\u9700\u8981\u8d70\u4ee3\u7406\u7684\u57df\u540d\u8fd4\u56de\u900f\u660e\u4ee3\u7406 ip\uff0c\u65e0\u9700\u8d70\u4ee3\u7406\u7684\u57df\u540d\u76f4\u63a5\u8fd4\u56de\u771f\u5b9e ip<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">flowchart BT\nDNS[(\u5206\u6d41 DNS)] --&gt;|\u56fd\u5185\u76f4\u8fde| UpDNS\nDNS --&gt;|\u56fd\u5916\u8d70\u4ee3\u7406| Proxy --&gt; \u4ee3\u7406\u670d\u52a1\u5668\nUpDNS[\u4e0a\u6e38\u516c\u5171 DNS] --&gt;|\u76f4\u63a5\u51fa\u516c\u7f51| Internet\nInternet[\u4e92\u8054\u7f51]\nProxy[(\u900f\u660e\u4ee3\u7406)]\nDesktop(\u7535\u8111) --&gt;|\u5206\u6d41| DNS\nPhone(\u624b\u673a) --&gt;|\u5206\u6d41| DNS\nBT(BT \u4e0b\u8f7d\u673a) --&gt;|\u5168\u5c40\u76f4\u8fde| UpDNS\nIOT(\u667a\u80fd\u5bb6\u5c45\u8bbe\u5907) --&gt;|\u5168\u5c40\u76f4\u8fde| UpDNS\n<\/div>\n<h2 id=\"dns-\u5206\u6d41\u914d\u7f6e\">DNS \u5206\u6d41\u914d\u7f6e<\/h2>\n<h3 id=\"\u6781\u7b80\u914d\u7f6e\">\u6781\u7b80\u914d\u7f6e<\/h3>\n<p>\u4f7f\u7528 fake-ip \u6a21\u5f0f\u7684 Clash \u65e2\u4f5c\u4e3a\u900f\u660e\u4ee3\u7406\u53c8\u4f5c\u4e3a DNS Server\uff0c\u8fd9\u79cd\u65b9\u5f0f\u914d\u7f6e\u975e\u5e38\u7b80\u5355\uff0c\u53ea\u9700\u8981\u4e00\u4e2a\u80fd\u8fd0\u884c Clash \u7684\u8bbe\u5907\u5373\u53ef<\/p>\n<p>\u9996\u5148\u4f60\u9700\u8981\u90e8\u7f72\u597d Clash\uff08\u8bf7\u81ea\u884c\u5bfb\u627e\u6559\u7a0b\uff0c\u4f5c\u4e3a\u4e3b\u8def\u7531\u3001\u65c1\u8def\u7531\u90fd\u53ef\u4ee5\uff0c\u4f7f\u7528\u865a\u62df\u673a\u3001docker\u3001lxc \u6ca1\u9650\u5236\uff09 \u7136\u540e\u4fee\u6539\u5982\u4e0b\u914d\u7f6e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">dns<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">enable<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u5f00\u542f fake-ip \u6a21\u5f0f<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">enhanced-mode<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">fake-ip<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u9009\u62e9\u4fdd\u7559 ip \u6bb5\uff0c\u4e00\u822c\u4fdd\u6301\u9ed8\u8ba4\u5373\u53ef<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">fake-ip-range<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">198.18.0.1<\/span><span class=\"l\">\/16<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u6307\u5b9a Clash DNS \u76d1\u542c\u5730\u5740<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">listen<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"m\">0.0.0.0<\/span><span class=\"p\">:<\/span><span class=\"m\">53<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u6307\u5b9a\u4e0a\u6e38\u516c\u5171 DNS<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">nameserver<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"m\">223.5.5.5<\/span><span class=\"p\">:<\/span><span class=\"m\">53<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u6dfb\u52a0\u9700\u8981\u76f4\u8fde\u7684\u56fd\u5185\u57df\u540d<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">fake-ip-filter<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">baidu.com<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span>- <span class=\"l\">...<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"nt\">tun<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">enable<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">stack<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">system<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"l\">\/\/ \u81ea\u52a8\u4e3a fake-ip-range \u4e2d\u7684 ip \u6bb5\u6dfb\u52a0\u8def\u7531<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">auto-route<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u4e2a\u914d\u7f6e\u505a\u4e86\u4e09\u4ef6\u4e8b<\/p>\n<ol>\n<li>\u5f00\u542f dns \u670d\u52a1\u5e76\u6307\u5b9a\u4e3a fake-ip \u6a21\u5f0f\uff0c\u76d1\u542c 53 \u7aef\u53e3<\/li>\n<li>\u5bf9\u4e8e fake-ip-filter \u4e2d\u7684\u56fd\u5185\u57df\u540d\u76f4\u63a5\u8fd4\u56de\u771f\u5b9e ip\uff0c\u8fd9\u4e9b\u57df\u540d\u7684\u6d41\u91cf\u4e0d\u518d\u7ecf\u8fc7\u4ee3\u7406<\/li>\n<li>\u5f00\u542f tun \u6a21\u5f0f\u5e76\u81ea\u52a8\u6dfb\u52a0\u8def\u7531\uff0c\u5c06\u53d1\u5f80 fake-ip \u7684\u8bf7\u6c42\u4ea4\u7ed9 clash \u5904\u7406<\/li>\n<\/ol>\n<p>\u6700\u5173\u952e\u7684\u662f\u9700\u8981\u5c06\u5e38\u89c1\u56fd\u5185\u57df\u540d\u52a0\u5165\u5230 fake-ip-filter \u4e2d\uff0c\u8fd9\u91cc\u63a8\u8350\u4e00\u4e2a\u6bcf\u65e5\u66f4\u65b0\u56fd\u5185\u57df\u540d\u7684\u9879\u76ee\uff1a<a class=\"link\" href=\"https:\/\/github.com\/felixonmars\/dnsmasq-china-list\" target=\"_blank\" rel=\"noopener\"\n>felixonmars\/dnsmasq-china-list<\/a><\/p>\n<p>\u4f60\u53ef\u4ee5\u81ea\u884c\u4e0b\u8f7d accelerated-domains.china.conf \u6587\u4ef6\u5e76\u4e3a\u5176\u4e2d\u7684\u57df\u540d\u52a0\u4e0a <code>+.<\/code> \u524d\u7f00\u7136\u540e\u6dfb\u52a0\u5230 fake-ip-filter \u4e2d\u3002\u5982\u679c\u4f60\u6070\u597d\u4f7f\u7528 openclash \u53ef\u4ee5\u7528\u535a\u4e3b\u7684\u811a\u672c\uff0c\u53ef\u4ee5\u81ea\u52a8\u4e0b\u8f7d\u56fd\u5185\u57df\u540d\u5217\u8868\u5e76\u5199\u5165 openclash \u7684\u914d\u7f6e\u6587\u4ef6\u4e2d<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">rm -f accelerated-domains.china.conf\n<\/span><\/span><span class=\"line\"><span class=\"cl\">wget https:\/\/raw.githubusercontent.com\/felixonmars\/dnsmasq-china-list\/master\/accelerated-domains.china.conf -O \/root\/accelerated-domains.china.conf\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo<\/span> <span class=\"s1\">&#39;\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">#LAN\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.lan\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.localdomain\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.example\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.invalid\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.localhost\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.test\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.local\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.home.arpa\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">#\u653e\u884cNTP\u670d\u52a1\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">time.*.com\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">time.*.gov\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">time.*.edu.cn\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">time.*.apple.com\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">ntp.*.com\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.time.edu.cn\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.ntp.org.cn\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">+.pool.ntp.org\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">time1.cloud.tencent.com\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">*.cn\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;<\/span> &gt; \/etc\/openclash\/custom\/openclash_custom_fake_filter.list\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">awk -F \/ <span class=\"s1\">&#39;{print &#34;+.&#34;$2}&#39;<\/span> \/root\/accelerated-domains.china.conf &gt;&gt; \/etc\/openclash\/custom\/openclash_custom_fake_filter.list\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo<\/span> fake-ip-filter: &gt; \/tmp\/openclash_fake_filter.list\n<\/span><\/span><span class=\"line\"><span class=\"cl\">awk <span class=\"s1\">&#39;{print &#34; - &#39;<\/span><span class=\"se\">\\&#39;<\/span><span class=\"s1\">&#39;&#34;$1&#34;&#39;<\/span><span class=\"se\">\\&#39;<\/span><span class=\"s1\">&#39;&#34;}&#39;<\/span> \/etc\/openclash\/custom\/openclash_custom_fake_filter.list &gt;&gt; \/tmp\/openclash_fake_filter.list\n<\/span><\/span><\/code><\/pre><\/div><p>\u770b\u5230\u8fd9\u91cc\u606d\u559c\u4f60\u5168\u90e8\u914d\u7f6e\u5df2\u7ecf\u5b8c\u6210\uff0c\u662f\u4e0d\u662f\u5f88\u7b80\u5355\uff1f\u63a5\u4e0b\u6765\u5c06\u9700\u8981\u8d70\u4ee3\u7406\u7684\u8bbe\u5907 DNS \u6539\u4e3a Clash DNS \u7684\u5730\u5740\u5373\u53ef\u4eab\u53d7\u5206\u6d41\u4e0a\u7f51<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5982\u679c\u4f60\u7684 clash \u8fd0\u884c\u5728\u65c1\u8def\u7531\u4e0a\uff0c\u8fd8\u9700\u8981\u5728\u4e3b\u8def\u7531\u7684\u8def\u7531\u8868\u4e2d\u6dfb\u52a0\u4e00\u9879\uff0c\u5c06 fake-ip \u6307\u5411\u65c1\u8def\u7531\n<\/div>\n<p><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># 198.18.0.1\/16 \u662f fake-ip-range \u914d\u7f6e\u7684 ip \u6bb5<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># 192.168.2.254 \u662f\u65c1\u8def\u7531 ip<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 198.18.0.1\/16 gw 192.168.2.254\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u9664\u975e\u4f60\u719f\u6089 linux \u7f51\u7edc\u914d\u7f6e\uff0c\u5426\u5219\u5c3d\u91cf\u4f7f\u7528\u539f\u751f clash \u800c\u4e0d\u662f openclash \u4e4b\u7c7b\u7684\u5468\u8fb9\u9879\u76ee\uff0c\u5b83\u4eec\u5f80\u5f80\u4f1a\u6dfb\u52a0 iptables \u89c4\u5219\u5c06\u7ecf\u8fc7\u672c\u673a\u7684\u8fde\u63a5\u90fd\u8f6c\u53d1\u5230 clash\n<\/div>\n<p><\/p>\n<p>\u5728\u8fd0\u884c clash \u7684\u670d\u52a1\u5668\u4e0a\u4f7f\u7528 mtr \u6216 traceroute \u6765\u9a8c\u8bc1\u5206\u6d41\u7b56\u7565\u662f\u5426\u751f\u6548\uff1a\u5982\u679c mtr \u7684\u7ed3\u679c\u663e\u793a\u65e0\u9700\u4ee3\u7406\u7684\u57df\u540d\u4e0d\u6b62\u4e00\u8df3\u5e76\u4e14\u6ca1\u6709\u7ecf\u8fc7 fake-ip-range \u7684 ip \u6bb5\u5219\u5206\u6d41\u914d\u7f6e\u6b63\u786e\uff1b\u4e5f\u53ef\u4ee5\u89c2\u5bdf Clash \u63a7\u5236\u53f0\uff0c\u770b\u770b\u662f\u5426\u6709\u65e0\u9700\u8d70\u4ee3\u7406\u57df\u540d\u8fde\u4e0a\u6765<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u914d\u7f6e\u6709\u8bef<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">root@OpenWrt:~# mtr -r --tcp www.baidu.com\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Start: 2022-06-09T21:37:36+0800\n<\/span><\/span><span class=\"line\"><span class=\"cl\">HOST: OpenWrt Loss% Snt Last Avg Best Wrst StDev\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 1.<span class=\"p\">|<\/span>-- 198.18.0.19<span class=\"o\">(<\/span>fake-ip<span class=\"o\">)<\/span> 0.0% <span class=\"m\">10<\/span> 0.2 0.1 0.1 0.2 0.0\n<\/span><\/span><\/code><\/pre><\/div><div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u914d\u7f6e\u6b63\u786e<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">root@OpenWrt:~# mtr -r --tcp ntp.aliyun.com\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Start: 2022-06-09T21:40:51+0800\n<\/span><\/span><span class=\"line\"><span class=\"cl\">HOST: OpenWrt Loss% Snt Last Avg Best Wrst StDev\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 1.<span class=\"p\">|<\/span>-- &lt;\u4e3b\u8def\u7531 ip&gt; 0.0% <span class=\"m\">10<\/span> 0.1 0.1 0.1 0.2 0.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 2.<span class=\"p\">|<\/span>-- &lt;\u516c\u7f51\u51fa\u53e3 ip&gt; 10.0% <span class=\"m\">10<\/span> 6.0 5.2 3.1 9.5 1.9\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 3.<span class=\"p\">|<\/span>-- 117.49.47.202 0.0% <span class=\"m\">10<\/span> 4.1 5.0 4.0 6.5 1.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 4.<span class=\"p\">|<\/span>-- 116.251.94.198 0.0% <span class=\"m\">10<\/span> 10.0 11.0 10.0 13.0 1.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 5.<span class=\"p\">|<\/span>-- ??? 100.0 <span class=\"m\">10<\/span> 0.0 0.0 0.0 0.0 0.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 6.<span class=\"p\">|<\/span>-- ??? 100.0 <span class=\"m\">10<\/span> 0.0 0.0 0.0 0.0 0.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 7.<span class=\"p\">|<\/span>-- ??? 100.0 <span class=\"m\">10<\/span> 0.0 0.0 0.0 0.0 0.0\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 8.<span class=\"p\">|<\/span>-- 203.107.6.88 0.0% <span class=\"m\">10<\/span> 24.7 24.7 24.4 26.2 0.5\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u7cbe\u51c6\u5206\u6d41\u914d\u7f6e\">\u7cbe\u51c6\u5206\u6d41\u914d\u7f6e<\/h3>\n<p>\u4f7f\u7528 Clash DNS \u7684\u65b9\u6848\u867d\u7136\u914d\u7f6e\u975e\u5e38\u7b80\u5355\uff0c\u4f46\u662f\u6bd5\u7adf\u4e0d\u53ef\u80fd\u5c06\u6240\u6709\u56fd\u5185\u57df\u540d\u90fd\u7edf\u8ba1\u51fa\u6765\uff0c\u8fd8\u9700\u8981\u6839\u636e ip \u8fdb\u884c\u66f4\u7cbe\u51c6\u7684\u5206\u6d41<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">flowchart BT\nDNS[\u5206\u6d41 DNS] --&gt;|\u56fd\u5185 ip| UpDNS\nDNS --&gt;|\u56fd\u5185\u57df\u540d| UpDNS\nDNS --&gt;|\u56fd\u5916 ip| ClashDNS\nDNS --&gt;|GFW \u9ed1\u540d\u5355\u57df\u540d| ClashDNS\nClashDNS[Clash DNS] --&gt; UpDNS\nUpDNS[\u4e0a\u6e38\u516c\u5171 DNS]\n<\/div>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u591a\u6570\u7cfb\u7edf\u4e0d\u652f\u6301\u6307\u5b9a DNS \u7aef\u53e3\uff0c\u6240\u4ee5\u5206\u6d41 DNS \u548c Clash DNS \u6700\u597d\u5206\u914d\u4e0d\u540c\u7684 ip\uff08\u53ef\u4ee5\u5728\u5355\u7f51\u5361\u4e0a\u5206\u914d\u591a\u4e2a\u5185\u7f51 ip\uff09\n<\/div>\n<p><\/p>\n<p>\u535a\u4e3b\u9009\u7528 <a class=\"link\" href=\"https:\/\/github.com\/IrineSistiana\/mosdns-cn\" target=\"_blank\" rel=\"noopener\"\n>IrineSistiana\/mosdns-cn<\/a> \u4f5c\u4e3a\u5206\u6d41 DNS\uff0c\u8fd9\u91cc\u5f15\u7528 mosdns-cn \u5b98\u65b9\u6587\u6863\u4e0a\u4ecb\u7ecd\u7684\u5206\u6d41\u89c4\u5219<\/p>\n<blockquote>\n<p>\u5206\u6d41\u6a21\u5f0f<br \/>\nmosdns-cn \u4f1a\u6839\u636e\u7528\u6237\u63d0\u4f9b\u7684\u6570\u636e\u91c7\u7528\u4ee5\u4e0b\u5206\u6d41\u6a21\u5f0f\u3002<\/p>\n<p>\u914d\u7f6e\u4e86 &ndash;local-ip \u672c\u5730 IP<\/p>\n<ol>\n<li>\u5982\u679c\u8bf7\u6c42\u7684\u57df\u540d\u5339\u914d\u5230 &ndash;local-domain \u672c\u5730\u57df\u540d\u3002\u5219\u76f4\u63a5\u4f7f\u7528 &ndash;local-upstream \u672c\u5730\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u5982\u679c\u8bf7\u6c42\u7684\u57df\u540d\u5339\u914d\u5230 &ndash;remote-domain \u8fdc\u7a0b\u57df\u540d\u3002\u5219\u76f4\u63a5\u4f7f\u7528&ndash;remote-upstream \u8fdc\u7a0b\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u975e A\/AAAA \u7c7b\u578b\u7684\u8bf7\u6c42\u5c06\u76f4\u63a5\u4f7f\u7528 &ndash;local-upstream \u672c\u5730\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u540c\u65f6\u8f6c\u53d1\u81f3\u672c\u5730\u548c\u8fdc\u7a0b\u4e0a\u6e38\u83b7\u53d6\u5e94\u7b54\u3002<\/li>\n<li>\u5982\u679c\u672c\u5730\u4e0a\u6e38\u7684\u5e94\u7b54\u5305\u542b &ndash;local-ip \u672c\u5730 IP\u3002\u5219\u76f4\u63a5\u91c7\u7528\u672c\u5730\u4e0a\u6e38\u7684\u7ed3\u679c\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u5426\u5219\u91c7\u7528\u8fdc\u7a0b\u4e0a\u6e38\u7684\u7ed3\u679c\u3002\u7ed3\u675f\u3002<\/li>\n<\/ol>\n<p>\u53ea\u914d\u7f6e\u4e86 &ndash;local-domain \u672c\u5730\u57df\u540d<\/p>\n<ol>\n<li>\u5982\u679c\u8bf7\u6c42\u7684\u57df\u540d\u5339\u914d\u5230 &ndash;local-domain \u672c\u5730\u57df\u540d\u3002\u5219\u76f4\u63a5\u4f7f\u7528 &ndash;local-upstream \u672c\u5730\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u5176\u4ed6\u6240\u6709\u8bf7\u6c42\u4f1a\u4f7f\u7528 &ndash;remote-upstream \u8fdc\u7a0b\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<\/ol>\n<p>\u53ea\u914d\u7f6e\u4e86 &ndash;remote-domain \u8fdc\u7a0b\u57df\u540d<\/p>\n<ol>\n<li>\u5982\u679c\u8bf7\u6c42\u7684\u57df\u540d\u5339\u914d\u5230 &ndash;remote-domain \u8fdc\u7a0b\u57df\u540d\u3002\u5219\u76f4\u63a5\u4f7f\u7528&ndash;remote-upstream \u8fdc\u7a0b\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<li>\u5176\u4ed6\u6240\u6709\u8bf7\u6c42\u4f1a\u4f7f\u7528 &ndash;local-upstream \u672c\u5730\u4e0a\u6e38\u3002\u7ed3\u675f\u3002<\/li>\n<\/ol>\n<\/blockquote>\n<p>Github \u4e0a\u6709\u8be6\u7ec6\u4f7f\u7528\u6559\u7a0b\uff0c\u8fd9\u91cc\u7ed9\u51fa\u535a\u4e3b\u4f7f\u7528\u7684\u542f\u52a8\u811a\u672c\uff0c\u6bcf\u6b21\u542f\u52a8\u65f6\u62c9\u53d6\u6700\u65b0\u7684\u56fd\u5185\u5916\u57df\u540d\/ip \u6570\u636e<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"nv\">RELEASE_URL<\/span><span class=\"o\">=<\/span><span class=\"k\">$(<\/span>curl -s https:\/\/api.github.com\/repos\/Loyalsoldier\/v2ray-rules-dat\/releases\/latest <span class=\"p\">|<\/span> grep browser_download_url<span class=\"k\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">GEOSITE_URL<\/span><span class=\"o\">=<\/span><span class=\"k\">$(<\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">&#34;<\/span><span class=\"nv\">$RELEASE_URL<\/span><span class=\"s2\">&#34;<\/span> <span class=\"p\">|<\/span> grep geosite.dat<span class=\"se\">\\&#34;<\/span> <span class=\"p\">|<\/span> cut -d<span class=\"s1\">&#39;&#34;&#39;<\/span> -f4<span class=\"k\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">GEOIP_URL<\/span><span class=\"o\">=<\/span><span class=\"k\">$(<\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">&#34;<\/span><span class=\"nv\">$RELEASE_URL<\/span><span class=\"s2\">&#34;<\/span> <span class=\"p\">|<\/span> grep geoip.dat<span class=\"se\">\\&#34;<\/span> <span class=\"p\">|<\/span> cut -d<span class=\"s1\">&#39;&#34;&#39;<\/span> -f4<span class=\"k\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"o\">[<\/span> -z <span class=\"nv\">$GEOSITE_URL<\/span> <span class=\"o\">]<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">then<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nb\">echo<\/span> <span class=\"s2\">&#34;GEOSITE_URL required!&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nb\">exit<\/span> <span class=\"m\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">fi<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"o\">[<\/span> -z <span class=\"nv\">$GEOIP_URL<\/span> <span class=\"o\">]<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">then<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nb\">echo<\/span> <span class=\"s2\">&#34;GEOIP_URL required!&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nb\">exit<\/span> <span class=\"m\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">fi<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo<\/span> <span class=\"nv\">$GEOSITE_URL<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo<\/span> <span class=\"nv\">$GEOIP_URL<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nb\">echo<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">wget <span class=\"nv\">$GEOSITE_URL<\/span> -O geosite.dat\n<\/span><\/span><span class=\"line\"><span class=\"cl\">wget <span class=\"nv\">$GEOIP_URL<\/span> -O geoip.dat\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">mosdns-cn -s :53 --blacklist-domain <span class=\"s2\">&#34;geosite.dat:category-ads-all&#34;<\/span> --local-upstream 223.5.5.5:53 --local-domain <span class=\"s2\">&#34;geosite.dat:cn&#34;<\/span> --local-ip <span class=\"s2\">&#34;geoip.dat:cn&#34;<\/span> --remote-upstream https:\/\/8.8.8.8\/dns-query --remote-domain <span class=\"s2\">&#34;geosite.dat:geolocation-!cn&#34;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u53bb\u5e7f\u544adns-\u89e3\u6790\u7edf\u8ba1\u914d\u7f6e\">\u53bb\u5e7f\u544a\/DNS \u89e3\u6790\u7edf\u8ba1\u914d\u7f6e<\/h3>\n<p>mos-dns \u652f\u6301\u914d\u7f6e\u9ed1\u540d\u5355\u57df\u540d\u76f4\u63a5\u7ed9\u51fa\u7a7a\u54cd\u5e94\uff0c\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e00\u673a\u5236\u963b\u65ad\u5e7f\u544a\u57df\u540d\u7684\u8bbf\u95ee\uff1a<code>mosdns-cn --blacklist-domain &quot;geosite.dat:category-ads-all&quot;<\/code><\/p>\n<p>\u4f46\u662f\u76ee\u524d\u5c11\u6709\u5927\u4f6c\u5206\u4eab\u9002\u914d mosdns-cn \u7684\u53bb\u5e7f\u544a\u89c4\u5219\uff0c\u8fd9\u79cd\u4e13\u4e1a\u7684\u4e8b\u60c5\u8fd8\u662f\u4ea4\u7ed9 Adguard Home \u6765\u505a\uff1a<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">flowchart BT\nDNS[\u5206\u6d41 DNS] --&gt;|\u56fd\u5185 ip| AdguardHome\nDNS --&gt;|\u56fd\u5185\u57df\u540d| AdguardHome\nDNS --&gt;|\u56fd\u5916 ip| ClashDNS\nDNS --&gt;|GFW \u9ed1\u540d\u5355\u57df\u540d| ClashDNS\nClashDNS[Clash DNS] --&gt; AdguardHome\nAdguardHome[Adguard Home] --&gt; UpDNS\nUpDNS[\u4e0a\u6e38\u516c\u5171 DNS]\n<\/div>\n<p>\u5c06 Adguard Home \u653e\u5728 mosdns-cn \u548c Clash DNS \u7684\u4e0a\u6e38\u8fd8\u6709\u5176\u4ed6\u597d\u5904\uff0c\u53ef\u4ee5\u501f\u52a9\u5b83\u7684\u4eea\u8868\u76d8\u548c\u65e5\u5fd7\u5206\u6790\u51fa\u6574\u4e2a\u7f51\u7edc\u8bbf\u95ee\u7684\u7f51\u7ad9<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 112;\nflex-basis: 270px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges\/adguard-home.jpg\" data-size=\"1217x1078\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges\/adguard-home.jpg\"\nwidth=\"1217\"\nheight=\"1078\"\nloading=\"lazy\"\nalt=\"Adguard Home \u4eea\u8868\u76d8\">\n<\/a>\n<figcaption>Adguard Home \u4eea\u8868\u76d8<\/figcaption>\n<\/figure><\/p>\n<p>Adguard Home \u7684\u90e8\u7f72\u6559\u7a0b\u7f51\u4e0a\u6709\u5f88\u591a\uff0c\u80fd\u770b\u5230\u8fd9\u91cc\u7684\u4eba\u80af\u5b9a\u4e5f\u4e0d\u7528\u6211\u8d58\u8ff0\u4e86\u3002\u8fd9\u91cc\u63a8\u8350\u4e00\u4e2a\u535a\u4e3b\u81ea\u7528\u7684\u8fc7\u6ee4\u89c4\u5219\uff0c\u6709\u4e86\u5b83\u5c31\u4e0d\u9700\u8981\u5176\u4ed6\u89c4\u5219\u4e86\uff1a<a class=\"link\" href=\"https:\/\/github.com\/BlueSkyXN\/AdGuardHomeRules\" target=\"_blank\" rel=\"noopener\"\n>BlueSkyXN\/AdGuardHomeRules<\/a><\/p>\n<h2 id=\"\u5176\u4ed6\u914d\u7f6e\">\u5176\u4ed6\u914d\u7f6e<\/h2>\n<h3 id=\"\u81ea\u52a8\u8bbe\u7f6e\u8bbe\u5907\u7684-dns-\u670d\u52a1\u5668\">\u81ea\u52a8\u8bbe\u7f6e\u8bbe\u5907\u7684 DNS \u670d\u52a1\u5668<\/h3>\n<p>\u5728<code>\u6781\u7b80\u914d\u7f6e<\/code>\u4e2d\u535a\u4e3b\u63d0\u5230<code>\u5c06\u9700\u8981\u8d70\u4ee3\u7406\u7684\u8bbe\u5907 DNS \u6539\u4e3a\u5206\u6d41 DNS<\/code>\uff0c\u8fd9\u4e00\u6b65\u53ef\u4ee5\u624b\u52a8\u6539\u4e5f\u53ef\u4ee5\u501f\u52a9 DHCP \u81ea\u52a8\u914d\u7f6e\uff1aDHCP Option 6 \u7684\u4f5c\u7528\u5c31\u662f\u6307\u5b9a\u5ba2\u6237\u7aef\u4f7f\u7528\u7684 DNS\uff0c\u5728 Openwrt LAN \u63a5\u53e3\u7684\u9ad8\u7ea7\u8bbe\u7f6e\u4e2d\u5373\u53ef\u627e\u5230\u8be5\u8bbe\u7f6e<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 254;\nflex-basis: 610px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges\/openwrt-dhcp-option.jpg\" data-size=\"1134x446\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/use-dns-to-create-split-routing-for-different-domain-or-ip-ranges\/openwrt-dhcp-option.jpg\"\nwidth=\"1134\"\nheight=\"446\"\nloading=\"lazy\"\nalt=\"Openwrt DHCP Option \u914d\u7f6e\">\n<\/a>\n<figcaption>Openwrt DHCP Option \u914d\u7f6e<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"\u4e3a\u76f4\u63a5\u4f7f\u7528-ip-\u7684-app-\u8bbe\u7f6e\u8def\u7531\">\u4e3a\u76f4\u63a5\u4f7f\u7528 IP \u7684 APP \u8bbe\u7f6e\u8def\u7531<\/h3>\n<p>\u76f4\u63a5\u4f7f\u7528 ip \u7684\u8f6f\u4ef6\u6ca1\u6709\u7ecf\u8fc7 DNS \u81ea\u7136\u5c31\u65e0\u6cd5\u83b7\u53d6\u5230 Clash \u7684 fake-ip\uff0c\u5bf9\u4e8e\u8fd9\u79cd\u60c5\u51b5\u9700\u8981\u5728\u4e3b\u8def\u7531\u4e0a\u6dfb\u52a0\u9759\u6001\u8def\u7531\u5c06\u8fd9\u4e9b\u8f6f\u4ef6\u4f7f\u7528\u7684 ip \u7684\u4e0b\u4e00\u8df3\u8def\u7531\u6539\u4e3a Clash \u7684 fake-ip<\/p>\n<p>\u76ee\u524d\u6211\u53ea\u53d1\u73b0 Telegram \u5b58\u5728\u8fd9\u79cd\u60c5\u51b5\uff0c\u9700\u8981\u6dfb\u52a0\u7684\u8def\u7531\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># 192.18.1.254 \u662f fake-ip\uff0c\u53ef\u4ee5\u4ece fake-ip-range \u4e2d\u968f\u4fbf\u9009\u62e9\u4e00\u4e2a<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 91.108.4.0\/22 gw 192.18.1.254\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 91.108.8.0\/22 gw 192.18.1.254\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 91.108.12.0\/22 gw 192.18.1.254\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 91.108.16.0\/22 gw 192.18.1.254\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 91.108.56.0\/22 gw 192.18.1.254\n<\/span><\/span><span class=\"line\"><span class=\"cl\">route add -net 149.154.160.0\/20 gw 192.18.1.254\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"PVE \u865a\u62df\u5316\u9ed1\u82f9\u679c\u663e\u5361\u76f4\u901a\u53ca\u8fdc\u7a0b\u8bbf\u95ee\u6559\u7a0b","link":"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial","pubDate":"Wed, 13 Apr 2022 17:14:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/hackintosh-logo.png\" alt=\"Featured image of post PVE \u865a\u62df\u5316\u9ed1\u82f9\u679c\u663e\u5361\u76f4\u901a\u53ca\u8fdc\u7a0b\u8bbf\u95ee\u6559\u7a0b\" \/><p>PVE \u865a\u62df\u5316\u9ed1\u82f9\u679c\u663e\u5361\u76f4\u901a\u6559\u7a0b\uff08\u6838\u663e&amp;\u72ec\u663e\u901a\u7528\uff09\uff0c\u4f4e\u5ef6\u8fdf\u8fdc\u7a0b\u8bbf\u95ee\u65b9\u6848\uff1aVNC\u3001ARD\u3001ToDesk\u3001ParSec\u3001Jump Desktop \u7b49\u8fdc\u7a0b\u684c\u9762\u534f\u8bae\/\u8f6f\u4ef6\u6d4b\u8bd5\u6a2a\u8bc4<\/p>\n<h2 id=\"\u9002\u7528\u573a\u666f\">\u9002\u7528\u573a\u666f<\/h2>\n<p>\u535a\u4e3b\u66fe\u7ecf\u7528\u7b14\u8bb0\u672c\u88c5\u9ed1\u82f9\u679c\u505a\u8fc7\u4e00\u6bb5\u65f6\u95f4\u7684\u4e3b\u529b\u673a\uff0c\u4f46\u662f\u56e0\u4e3a\u6709\u4f7f\u7528 Windows \u7684\u5f3a\u9700\u6c42\uff0c\u53cc\u7cfb\u7edf\u5207\u6362\u4e0d\u65b9\u4fbf\u6240\u4ee5\u6700\u7ec8\u6362\u56de\u7684 Windows\u3002\u5f53\u65f6\u5c31\u5728\u60f3\u5982\u679c\u6709\u4e00\u53f0\u670d\u52a1\u5668\u8dd1\u7740 MacOS\uff0c\u968f\u65f6\u53ef\u4ee5\u4ece\u4e3b\u529b\u673a Windows \u8fdc\u7a0b\u8bbf\u95ee\u5c82\u4e0d\u662f\u4e24\u5168\u5176\u7f8e\u3002\u4f46\u662f\u8fd1\u5e74\u77ff\u6f6e\u663e\u5361\u4ef7\u683c\u865a\u9ad8\uff0c\u5b9e\u5728\u662f\u6ca1\u6709\u5165\u624b\u7684\u6b32\u671b\uff0c\u6700\u8fd1\u8d81\u77ff\u96be\u663e\u5361\u4ef7\u683c\u4e0b\u8dcc\u5165\u624b\u4e00\u5757 AMD RX460 \u5b9e\u8df5\u4e00\u4e0b\u8fd9\u4e2a\u60f3\u6cd5<\/p>\n<p>\u9605\u8bfb\u672c\u6587\u9700\u8981\u7684\u524d\u7f6e\u6b65\u9aa4\uff1a<\/p>\n<ol>\n<li>\u4e00\u53f0\u8fd0\u884c PVE \u7684\u4e3b\u673a<\/li>\n<li>\u5728 PVE \u4e0a\u6210\u529f\u5b89\u88c5\u9ed1\u82f9\u679c\uff08\u4f7f\u7528 \uff09<\/li>\n<li>\u81f3\u5c11\u8fdb\u5165\u9ed1\u82f9\u679c\u4e00\u6b21\u5f00\u542f <code>\u8bbe\u7f6e-&gt;\u5171\u4eab-&gt;\u5c4f\u5e55\u5171\u4eab<\/code>\uff08\u663e\u5361\u76f4\u901a\u53ef\u80fd\u4f1a\u5bfc\u81f4 PVE \u81ea\u5e26\u7684 VNC \u5361\u5728\u767d\u82f9\u679c\u754c\u9762\uff09<\/li>\n<\/ol>\n<p>\u9ed1\u82f9\u679c\u80fd\u5426\u6210\u529f\u8fd0\u884c\u548c\u786c\u4ef6\u4ee5\u53ca\u9a71\u52a8\u6709\u5f88\u5927\u7684\u5173\u7cfb\uff0c\u800c\u4f7f\u7528 PVE \u4f7f\u7528\u7684 KVM \u865a\u62df\u5316\u6280\u672f\u53ef\u4ee5\u6700\u5927\u7a0b\u5ea6\u4e0a\u5c4f\u853d\u786c\u4ef6\u7684\u5dee\u5f02\u63d0\u9ad8\u6210\u529f\u7387\uff0c\u501f\u52a9 <a class=\"link\" href=\"https:\/\/github.com\/thenickdude\/KVM-Opencore\" target=\"_blank\" rel=\"noopener\"\n>KVM-Opencore<\/a> \u9879\u76ee\u63d0\u4f9b\u7684\u9a71\u52a8\u53ef\u4ee5\u505a\u5230\u5f00\u7bb1\u5373\u7528\uff0c\u4e0d\u7528\u6298\u817e<\/p>\n<p>PVE \u548c\u9ed1\u82f9\u679c\u5b89\u88c5\u6559\u7a0b\u8fd9\u91cc\u63a8\u8350\u4e24\u7bc7\u535a\u5ba2\uff0c\u5199\u7684\u975e\u5e38\u8be6\u7ec6<\/p>\n<ul>\n<li><a class=\"link\" href=\"https:\/\/www.nicksherlock.com\/2021\/10\/installing-macos-12-monterey-on-proxmox-7\" target=\"_blank\" rel=\"noopener\"\n>Installing macOS 12 \u201cMonterey\u201d on Proxmox 7<\/a><\/li>\n<li><a class=\"link\" href=\"https:\/\/www.sqlsec.com\/2022\/04\/pve.html\" target=\"_blank\" rel=\"noopener\"\n>\u56fd\u5149\u7684 PVE \u751f\u4ea7\u73af\u5883\u914d\u7f6e\u4f18\u5316\u8bb0\u5f55<\/a><\/li>\n<\/ul>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5bf9\u4e8e\u56fd\u5149\u8fd9\u7bc7\u6587\u7ae0\u6709\u4e00\u5904\u52d8\u8bef\uff0c\u6587\u7ae0\u4e2d\u8bf4\u5230 PVE 7.1 \u4e0d\u80fd\u663e\u5361\u76f4\u901a\uff0c\u5b9e\u9645\u4e0a\u6211\u6d4b\u8bd5\u662f\u53ef\u4ee5\u7684\uff0c\u8bfb\u8005\u53ef\u4ee5\u5728\u4e0b\u6587\u4e2d\u627e\u5230\u6211\u4f7f\u7528\u7684\u8f6f\u4ef6\u7248\u672c\n<\/div>\n<p><\/p>\n<h2 id=\"\u4e3b\u8981\u914d\u7f6e\">\u4e3b\u8981\u914d\u7f6e<\/h2>\n<h3 id=\"\u786c\u4ef6\u914d\u7f6e\">\u786c\u4ef6\u914d\u7f6e<\/h3>\n<p>CPU: i5 10400<br \/>\nGPU: UHD630\u3001AMD RX460<\/p>\n<p>\u5176\u4ed6\u786c\u4ef6\u5747\u865a\u62df\u5316<\/p>\n<h3 id=\"\u8f6f\u4ef6\u7248\u672c\">\u8f6f\u4ef6\u7248\u672c<\/h3>\n<p>\u865a\u62df\u5316\u5e73\u53f0\uff1aPVE<\/p>\n<p>\u4e3b\u8981\u8f6f\u4ef6\u5305\u7248\u672c\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">~ pveversion -v\n<\/span><\/span><span class=\"line\"><span class=\"cl\">proxmox-ve: 7.1-1 <span class=\"o\">(<\/span>running kernel: 5.13.19-6-pve<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">pve-manager: 7.1-12 <span class=\"o\">(<\/span>running version: 7.1-12\/b3c09de3<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">pve-kernel-helper: 7.1-14\n<\/span><\/span><span class=\"line\"><span class=\"cl\">pve-kernel-5.13: 7.1-9\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><\/code><\/pre><\/div><p>MacOS \u7248\u672c\uff1amacOS Monterey 12.3.1(21E258)\uff08\u4f7f\u7528 <a class=\"link\" href=\"https:\/\/github.com\/thenickdude\/OSX-KVM\" target=\"_blank\" rel=\"noopener\"\n>OSX-KVM<\/a> \u9879\u76ee\u5236\u4f5c\u955c\u50cf\uff09<br \/>\nOpenCore&amp;EFI \u7248\u672c\uff1a<a class=\"link\" href=\"https:\/\/github.com\/thenickdude\/KVM-Opencore\/releases\/tag\/v16\" target=\"_blank\" rel=\"noopener\"\n>KVM-Opencore v16<\/a><\/p>\n<h2 id=\"\u663e\u5361\u76f4\u901a\">\u663e\u5361\u76f4\u901a<\/h2>\n<p>\u56e0\u4e3a\u6211\u662f\u901a\u8fc7\u8fdc\u7a0b\u8bbf\u95ee\u4f7f\u7528\u9ed1\u82f9\u679c\uff0c\u6240\u4ee5\u5e76\u6ca1\u6709\u628a\u8981\u76f4\u901a\u7684 GPU \u8bbe\u7f6e\u4e3a\u4e3b GPU\uff0c\u8fd9\u662f\u672c\u6587\u548c\u5176\u4ed6\u76f4\u901a\u6559\u7a0b\u7684\u4e3b\u8981\u533a\u522b\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u662f\u53ef\u4ee5\u7528 PVE \u7684\u540e\u53f0\u76f4\u63a5\u67e5\u770b\u9ed1\u82f9\u679c\u542f\u52a8\u60c5\u51b5\u3001\u8fdb\u5165 Recovery \u6a21\u5f0f\u7b49<\/p>\n<p>\u53c2\u8003 <a class=\"link\" href=\"https:\/\/wiki.archlinux.org\/title\/PCI_passthrough_via_OVMF_%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29\" target=\"_blank\" rel=\"noopener\"\n>Arch Linux wiki<\/a><\/p>\n<h3 id=\"\u542f\u7528-iommu\">\u542f\u7528 IOMMU<\/h3>\n<p>\u8fd9\u91cc\u5f15\u7528 Arch Linux wiki \u4e2d\u5bf9 IOMMU \u7684\u4ecb\u7ecd\uff1a<\/p>\n<blockquote>\n<p>IOMMU \u662f Intel VT-d \u548c AMD-Vi \u7684\u901a\u7528\u540d\u79f0\u3002<br \/>\nVT-d \u6307\u7684\u662f\u76f4\u63a5\u8f93\u5165\/\u8f93\u51fa\u865a\u62df\u5316(Intel Virtualization Technology for Directed I\/O)\uff0c\u4e0d\u5e94\u4e0e VT-x(x86 \u5e73\u53f0\u4e0b\u7684 Intel \u865a\u62df\u5316\u6280\u672f\uff0cIntel Virtualization Technology)\u6df7\u6dc6\u3002VT-x \u53ef\u4ee5\u8ba9\u4e00\u4e2a\u786c\u4ef6\u5e73\u53f0\u4f5c\u4e3a\u591a\u4e2a\u201c\u865a\u62df\u201d\u5e73\u53f0\uff0c\u800c VT-d \u63d0\u9ad8\u4e86\u865a\u62df\u5316\u7684\u5b89\u5168\u6027\u3001\u53ef\u9760\u6027\u548c I\/O \u6027\u80fd\u3002<\/p>\n<\/blockquote>\n<p>\u9996\u5148\u5728 BIOS \u4e2d\u5f00\u542f VT-d<\/p>\n<p>\u7136\u540e\u4fee\u6539\u5185\u6838\u53c2\u6570\u5f00\u542f IOMMU\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\"><span class=\"line\"><span class=\"cl\"><span class=\"gd\">- GRUB_CMDLINE_LINUX_DEFAULT=&#34;quiet&#34;\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"gd\"><\/span><span class=\"gi\">+ GRUB_CMDLINE_LINUX_DEFAULT=&#34;quiet intel_iommu=on iommu=pt pcie_acs_override=downstream video=efifb:off&#34;\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u89e3\u91ca\u4e0b\u8fd9\u51e0\u4e2a\u53c2\u6570\u7684\u4f5c\u7528\uff1a<\/p>\n<ul>\n<li>intel_iommu=on\uff1a\u5f00\u542f IOMMU\uff0c\u5bf9\u4e8e AMD CPU \u9700\u8981\u4f7f\u7528 amd_iommu=on<\/li>\n<li>iommu=pt\uff1apt \u662f passthrough \u7684\u7f29\u5199\uff0c\u53ef\u4ee5\u63d0\u9ad8\u6027\u80fd<\/li>\n<li>pcie_acs_override=downstream: \u53ef\u4ee5\u5c06\u540c\u4e00 Group \u4e2d\u7684\u8bbe\u5907\u5206\u5f00\u76f4\u901a<\/li>\n<li>video=efifb:off\uff1a\u7981\u7528 efifb \u9a71\u52a8\uff0c\u9632\u6b62\u51fa\u73b0\u62a5\u9519 BAR 3: cannot reserve [mem]<\/li>\n<\/ul>\n<p>\u66f4\u65b0\u5185\u6838\u53c2\u6570<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">update-grub\n<\/span><\/span><\/code><\/pre><\/div><p>\u91cd\u542f\u540e\u53ef\u4ee5\u7528\u4ee5\u4e0b\u811a\u672c\u6d4b\u8bd5<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">bash -c <span class=\"s2\">&#34;<\/span><span class=\"k\">$(<\/span>curl -fsSL https:\/\/gist.githubusercontent.com\/ShadowySpirits\/018ea8675100baf768afff0d835e7862\/raw\/8e1c12f5766f0d308628ad1373b2f8603c523480\/check_iommu.sh<span class=\"k\">)<\/span><span class=\"s2\">&#34;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u4f60\u9047\u5230\u7f51\u7edc\u95ee\u9898\u53ef\u4ee5\u76f4\u63a5\u590d\u5236\u5e76\u6267\u884c\u4ee5\u4e0b\u811a\u672c\u5185\u5bb9\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bas\" data-lang=\"bas\"><span class=\"line\"><span class=\"cl\"><span class=\"err\">#<\/span><span class=\"o\">!\/<\/span><span class=\"vg\">bin<\/span><span class=\"o\">\/<\/span><span class=\"vg\">bash<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"vg\">shopt<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"vg\">s<\/span><span class=\"w\"> <\/span><span class=\"vg\">nullglob<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"vg\">for<\/span><span class=\"w\"> <\/span><span class=\"vg\">g<\/span><span class=\"w\"> <\/span><span class=\"vg\">in<\/span><span class=\"w\"> <\/span><span class=\"err\">$<\/span><span class=\"p\">(<\/span><span class=\"vg\">find<\/span><span class=\"w\"> <\/span><span class=\"o\">\/<\/span><span class=\"vg\">sys<\/span><span class=\"o\">\/<\/span><span class=\"vg\">kernel<\/span><span class=\"o\">\/<\/span><span class=\"vg\">iommu_groups<\/span><span class=\"o\">\/*<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"vg\">maxdepth<\/span><span class=\"w\"> <\/span><span class=\"il\">0<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"vg\">type<\/span><span class=\"w\"> <\/span><span class=\"vg\">d<\/span><span class=\"w\"> <\/span><span class=\"o\">|<\/span><span class=\"w\"> <\/span><span class=\"vg\">sort<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"vg\">V<\/span><span class=\"p\">);<\/span><span class=\"w\"> <\/span><span class=\"vg\">do<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"vg\">echo<\/span><span class=\"w\"> <\/span><span class=\"s2\">&#34;IOMMU Group ${g##*\/}:&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"vg\">for<\/span><span class=\"w\"> <\/span><span class=\"vg\">d<\/span><span class=\"w\"> <\/span><span class=\"vg\">in<\/span><span class=\"w\"> <\/span><span class=\"err\">$<\/span><span class=\"vg\">g<\/span><span class=\"o\">\/<\/span><span class=\"vg\">devices<\/span><span class=\"o\">\/*<\/span><span class=\"p\">;<\/span><span class=\"w\"> <\/span><span class=\"vg\">do<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"vg\">echo<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"vg\">e<\/span><span class=\"w\"> <\/span><span class=\"s2\">&#34;\\t$(lspci -nns ${d##*\/})&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"vg\">done<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"vg\">done<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u770b\u5230\u7c7b\u4f3c\u4ee5\u4e0b\u4fe1\u606f\u8bf4\u660e IOMMU \u5f00\u542f\u6210\u529f<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">IOMMU Group 0:\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 00:00.0 Host bridge [0600]: Intel Corporation Comet Lake-S 6c Host Bridge\/DRAM Controller [8086:9b53] (rev 05)\n<\/span><\/span><span class=\"line\"><span class=\"cl\">IOMMU Group 1:\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 00:01.0 PCI bridge [0604]: Intel Corporation 6th-10th Gen Core Processor PCIe Controller (x16) [8086:1901] (rev 05)\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">IOMMU Group 6:\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 00:1c.0 PCI bridge [0604]: Intel Corporation Device [8086:a394] (rev f0)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 03:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD\/ATI] Baffin [Radeon RX 460\/560D \/ Pro 450\/455\/460\/555\/555X\/560\/560X] [1002:67ef] (rev cf)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 03:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD\/ATI] Baffin HDMI\/DP Audio [Radeon RX 550 640SP \/ RX 560\/560X] [1002:aae0]\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5982\u679c\u4e0a\u9762\u6ca1\u6709\u5f00\u542f <code>pcie_acs_override=downstream<\/code> \u5c31\u53ea\u80fd\u5c06\u6574\u4e2a Group \u4e0b\u7684\u8bbe\u5907\u90fd\u76f4\u901a\u7ed9\u67d0\u4e2a\u865a\u62df\u673a\n<\/div>\n<p><\/p>\n<h3 id=\"\u9694\u79bb-gpu\">\u9694\u79bb GPU<\/h3>\n<p>\u6211\u4eec\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u9a71\u52a8\u7a0b\u5e8f\uff08vfio\uff09\u63a5\u7ba1\u663e\u5361\uff0c\u8fd9\u6837\u624d\u80fd\u540e\u7eed\u5c06\u663e\u5361\u5206\u914d\u7ed9\u865a\u62df\u673a<\/p>\n<p>\u5728 PVE \u5bbf\u4e3b\u673a\u7684 \/etc\/modules \u4e2d\u6dfb\u52a0 vfio \u6a21\u5757<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">vfio\n<\/span><\/span><span class=\"line\"><span class=\"cl\">vfio_iommu_type1\n<\/span><\/span><span class=\"line\"><span class=\"cl\">vfio_pci\n<\/span><\/span><span class=\"line\"><span class=\"cl\">vfio_virqfd\n<\/span><\/span><\/code><\/pre><\/div><p>\u4fee\u6539 \/etc\/modprobe.d\/vfio.conf \u5c06\u663e\u5361\u7684\u4f9b\u5e94\u5546-\u8bbe\u5907 ID \u4f20\u9012\u7ed9 vfio \u9a71\u52a8\uff0c\u4f9b\u5e94\u5546-\u8bbe\u5907 ID \u53ef\u4ee5\u5728\u4e0a\u9762\u811a\u672c\u7684\u8f93\u51fa\u7684 <code>[]<\/code> \u4e2d\u627e\u5230\uff0c\u591a\u4e2a\u8bbe\u5907\u7528 <code>,<\/code> \u5206\u9694<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">options vfio-pci ids=device_id1,device_id2 disable_vga=1\n<\/span><\/span><\/code><\/pre><\/div><p>\u4ee5\u6211\u7684 RX460 \u4e3a\u4f8b\uff0c\u5b83\u7684\u4f9b\u5e94\u5546-\u8bbe\u5907 ID \u662f 1002:67ef \u548c 1002:aae0<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">IOMMU Group 6:\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 00:1c.0 PCI bridge [0604]: Intel Corporation Device [8086:a394] (rev f0)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 03:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD\/ATI] Baffin [Radeon RX 460\/560D \/ Pro 450\/455\/460\/555\/555X\/560\/560X] [1002:67ef] (rev cf)\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> 03:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD\/ATI] Baffin HDMI\/DP Audio [Radeon RX 550 640SP \/ RX 560\/560X] [1002:aae0]\n<\/span><\/span><\/code><\/pre><\/div><p>\u6240\u4ee5\u9700\u8981\u6dfb\u52a0\u7684\u5185\u5bb9\u662f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\">options vfio-pci ids=1002:67ef,1002:aae0 disable_vga=1\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u5728 PVE \u5bbf\u4e3b\u673a\u7684 \/etc\/modprobe.d\/blacklist.conf \u4e2d\u7981\u7528\u5176\u4ed6\u663e\u5361\u9a71\u52a8\uff0c\u9632\u6b62\u8fd9\u4e9b\u9a71\u52a8\u5728 vfio \u524d\u52a0\u8f7d<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\"><span class=\"line\"><span class=\"cl\"># NVIDIA\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist nvidiafb\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist nouveau\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist nvidia\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist snd_hda_intel\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"># Intel\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist snd_hda_codec_hdmi\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist i915\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"># AMD\n<\/span><\/span><span class=\"line\"><span class=\"cl\">blacklist radeon\n<\/span><\/span><\/code><\/pre><\/div><p>\u6700\u540e\u5e94\u7528\u66f4\u6539\u5e76\u91cd\u542f<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">update-initramfs -u\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5206\u914d\u663e\u5361\">\u5206\u914d\u663e\u5361<\/h3>\n<p>\u91cd\u542f\u540e\u5c31\u53ef\u4ee5\u5c06\u663e\u5361\u5206\u914d\u7ed9\u865a\u62df\u673a\u4e86\uff1a<\/p>\n<p>\u5728\u8bbe\u5907\u4e2d\u9009\u62e9\u6dfb\u52a0 PCI \u8bbe\u5907\uff0c\u7136\u540e\u9009\u62e9\u4f60\u8981\u6dfb\u52a0\u7684\u663e\u5361\u5373\u53ef\uff08\u72ec\u663e\u6838\u663e\u90fd\u53ef\u4ee5\uff09<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 238;\nflex-basis: 572px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/pve-passthrough.jpeg\" data-size=\"599x251\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/pve-passthrough.jpeg\"\nwidth=\"599\"\nheight=\"251\"\nloading=\"lazy\"\nalt=\"pve \u76f4\u901a\u9009\u9879\">\n<\/a>\n<figcaption>pve \u76f4\u901a\u9009\u9879<\/figcaption>\n<\/figure><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u4e0d\u540c\u7684\u663e\u5361\u8fd9\u91cc\u9009\u62e9\u7684\u9009\u9879\u4e0d\u592a\u4e00\u6837\uff0c\u6839\u636e\u6211\u7684\u8bd5\u9a8c\uff1a<br \/>\n\u76f4\u901a UHD630 \u53ea\u9700\u8981\u52fe\u9009 <code>\u5168\u529f\u80fd\uff08All Functions\uff09<\/code><br \/>\n\u76f4\u901a AMD RX460 \u9664\u4e86 <code>\u4e3b GPU\uff08Primary GPU\uff09<\/code> \u5916\u7684\u9009\u9879\u90fd\u9700\u8981\u52fe\u9009\n<\/div>\n<p><\/p>\n<p>\u76f4\u901a\u4e4b\u540e PVE \u81ea\u5e26\u7684 VNC \u53ef\u80fd\u4f1a\u5361\u5728\u767d\u82f9\u679c\u754c\u9762\uff0c\u5176\u5b9e\u7cfb\u7edf\u5df2\u7ecf\u6b63\u5e38\u542f\u52a8\uff0c\u53ef\u4ee5\u4f7f\u7528 MacOS \u81ea\u5e26\u7684 VNC \u8fdb\u884c\u8fde\u63a5<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 141;\nflex-basis: 339px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/stuck-apple.png\" data-size=\"670x474\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/stuck-apple.png\"\nwidth=\"670\"\nheight=\"474\"\nloading=\"lazy\"\nalt=\"\u767d\u82f9\u679c\">\n<\/a>\n<figcaption>\u767d\u82f9\u679c<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u8fdc\u7a0b\u8bbf\u95ee\">\u8fdc\u7a0b\u8bbf\u95ee<\/h2>\n<h3 id=\"\u5206\u8fa8\u7387\u8c03\u6574\">\u5206\u8fa8\u7387\u8c03\u6574<\/h3>\n<p>\u5f53\u4f60\u901a\u8fc7 PVE \u81ea\u5e26\u7684 VNC \u8fde\u63a5\u9ed1\u82f9\u679c\u7684\u65f6\u5019\u4f1a\u53d1\u73b0\u6709\u4e00\u4e2a\u5206\u8fa8\u7387\u4e3a 1080p \u7684\u5185\u7f6e\u663e\u793a\u5668\uff0c\u5e76\u4e14\u6ca1\u6709\u5176\u4ed6\u5206\u8fa8\u7387\u7684\u9009\u9879\uff0c\u6240\u4ee5\u9700\u8981\u4e00\u4e9b\u5947\u6280\u6deb\u5de7\u6765\u5f3a\u5236\u4fee\u6539\u5206\u8fa8\u7387\uff1a<\/p>\n<p>\u8fd9\u91cc\u7528\u5230\u4e24\u4e2a\u8f6f\u4ef6\uff1aBetterDummy \u548c SwitchResX<\/p>\n<p>\u9996\u5148\u4f7f\u7528 BetterDummy \u521b\u5efa\u4e00\u4e2a\u548c\u4f60\u7269\u7406\u663e\u793a\u5668\u6bd4\u4f8b\u4e00\u81f4\u7684\u865a\u62df\u663e\u793a\u5668\u5e76\u8bbe\u4e3a\u4e3b\u663e\u793a\u5668<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 114;\nflex-basis: 275px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/create-new-dummy.jpeg\" data-size=\"525x458\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/create-new-dummy.jpeg\"\nwidth=\"525\"\nheight=\"458\"\nloading=\"lazy\"\nalt=\"\u521b\u5efa\u865a\u62df\u663e\u793a\u5668\">\n<\/a>\n<figcaption>\u521b\u5efa\u865a\u62df\u663e\u793a\u5668<\/figcaption>\n<\/figure><\/p>\n<p>\u7136\u540e\u4f7f\u7528 SwitchResX \u4fee\u6539\u865a\u62df\u663e\u793a\u5668\u5206\u8fa8\u7387\u4e3a\u4f60\u7269\u7406\u663e\u793a\u5668\u7684\u539f\u751f\u5206\u8fa8\u7387<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 209;\nflex-basis: 502px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/switch-res.jpeg\" data-size=\"538x257\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/switch-res.jpeg\"\nwidth=\"538\"\nheight=\"257\"\nloading=\"lazy\"\nalt=\"\u4fee\u6539\u5206\u8fa8\u7387\">\n<\/a>\n<figcaption>\u4fee\u6539\u5206\u8fa8\u7387<\/figcaption>\n<\/figure><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u4e0d\u63a8\u8350\u4f7f\u7528\u5e26\u6709 HiDPI \u7684\u5206\u8fa8\u7387\uff0c\u56e0\u4e3a HiDPI \u662f\u4e00\u79cd\u8d85\u91c7\u6837\u6280\u672f\uff08HiDPI \u539f\u7406\u53ef\u4ee5\u53c2\u8003<a class=\"link\" href=\"https:\/\/blog.skk.moe\/post\/hidpi-what-why-how\/\" target=\"_blank\" rel=\"noopener\"\n>\u8fd9\u7bc7\u6587\u7ae0<\/a>\uff09\u9760\u6e32\u67d3\u66f4\u591a\u7684\u50cf\u7d20\u6765\u4f7f\u56fe\u50cf\u201c\u770b\u8d77\u6765\u201d\u66f4\u6e05\u6670\u3002\u4f46\u662f\u5927\u90e8\u5206\u8fdc\u7a0b\u684c\u9762\u8f6f\u4ef6\u90fd\u4f1a\u5c06\u539f\u751f\u5206\u8fa8\u7387\u538b\u7f29\u4e3a\u5f53\u524d\u7269\u7406\u5c4f\u5e55\u5206\u8fa8\u7387\u8fdb\u884c\u4f20\u8f93\uff0c\u6240\u4ee5\u5f00\u542f HiDPI \u9664\u4e86\u4f1a\u6d6a\u8d39\u8ba1\u7b97\u8d44\u6e90\u3001\u589e\u52a0\u5ef6\u8fdf\u5916\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\n<\/div>\n<p><\/p>\n<p>\uff08\u53ef\u9009\uff09\u4f7f\u7528 SwitchResX \u5173\u95ed\u9ed8\u8ba4\u663e\u793a\u5668<br \/>\n\u8fd9\u4e2a\u6b65\u9aa4\u4e0d\u662f\u5fc5\u987b\u7684\uff0c\u5982\u679c\u4f60\u7684\u8fdc\u7a0b\u684c\u9762\u8f6f\u4ef6\u65e0\u6cd5\u9009\u62e9\u7528\u4e8e\u4e32\u6d41\u7684\u663e\u793a\u5668\uff08\u6bd4\u5982 VNC Viewer\uff09\u53ef\u4ee5\u5173\u95ed\u9ed8\u8ba4\u663e\u793a\u5668\u6765\u5f3a\u5236\u8f6f\u4ef6\u4f7f\u7528\u865a\u62df\u663e\u793a\u5668<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 174;\nflex-basis: 418px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/disable-default-display.jpeg\" data-size=\"469x269\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/pve-virtualized-hackintosh-gpu-passthrough-and-remote-access-tutorial\/disable-default-display.jpeg\"\nwidth=\"469\"\nheight=\"269\"\nloading=\"lazy\"\nalt=\"\u5173\u95ed\u9ed8\u8ba4\u663e\u793a\u5668\">\n<\/a>\n<figcaption>\u5173\u95ed\u9ed8\u8ba4\u663e\u793a\u5668<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"\u539f\u751f\u65b9\u6848\">\u539f\u751f\u65b9\u6848<\/h3>\n<p>MacOS \u539f\u751f\u63d0\u4f9b VNC \u548c ARD \u4e24\u79cd\u534f\u8bae\u8fdb\u884c\u8fdc\u7a0b\u8bbf\u95ee\uff0c\u53ef\u4ee5\u5728 <code>\u8bbe\u7f6e-&gt;\u5206\u4eab<\/code> \u4e2d\u5f00\u542f<\/p>\n<h4 id=\"vnc\">VNC<\/h4>\n<p>\u81ea\u5e26\u7684 VNC \u662f\u9609\u5272\u7248\u7684\uff0c\u4f53\u9a8c\u4e0a\u505a\u7684\u5f88\u5dee\uff1a\u4e0d\u652f\u6301\u8c03\u6574\u753b\u8d28\u3001\u5206\u8fa8\u7387\uff0c\u4e0d\u652f\u6301\u9009\u62e9\u663e\u793a\u5668\uff08\u591a\u663e\u793a\u5668\u4f1a\u6a2a\u5411\u62fc\u63a5\u663e\u793a\u5185\u5bb9\uff09\u4ece Windows \u8bbf\u95ee\u952e\u4f4d\u6620\u5c04\u6709\u95ee\u9898\u5e76\u4e14\u65e0\u6cd5\u4fee\u6539\uff0c\u5361\u987f\u4e25\u91cd\uff0c\u62d6\u52a8\u7a97\u53e3\u7684\u65f6\u5019\u5c24\u5176\u660e\u663e\u3002\u552f\u4e00\u7684\u4f18\u70b9\u662f\u753b\u8d28\u975e\u5e38\u597d\uff0c\u662f\u672c\u6587\u4ecb\u7ecd\u7684\u6240\u6709\u65b9\u6848\u4e2d\u552f\u4e00\u4e00\u4e2a\u4f7f\u7528\u539f\u751f\u5206\u8fa8\u7387\u4f20\u8f93\uff08\u5f00\u542f HiDPI \u753b\u8d28\u660e\u663e\u63d0\u5347\uff09<\/p>\n<h4 id=\"ard\">ARD<\/h4>\n<p>ARD \u5c5e\u4e8e\u662f VNC \u5957\u58f3\uff0c\u53ef\u4ee5\u4f7f\u7528 Apple \u5b98\u65b9\u7684 <a class=\"link\" href=\"https:\/\/apps.apple.com\/us\/app\/apple-remote-desktop\/id409907375?mt=12\" target=\"_blank\" rel=\"noopener\"\n>Apple Remote Desktop<\/a> \u8f6f\u4ef6\uff08\u552e\u4ef7\u9ad8\u8fbe 518\uff0c\u4e0d\u4f1a\u771f\u6709\u51a4\u5927\u5934\u4f1a\u4e70\u5427\u3002\u3002\u3002\uff09\u8fde\u63a5\u9ed1\u82f9\u679c\u4e3b\u673a\u3002\u76f8\u6bd4\u4e8e VNC\uff0cARD \u652f\u6301\u9009\u62e9\u663e\u793a\u5668\uff0c\u63d0\u4f9b 4 \u6321\u53ef\u8c03\u7684\u56fe\u50cf\u8d28\u91cf\uff0c\u5728\u4fdd\u8bc1\u753b\u8d28\u7684\u524d\u63d0\u4e0b\u63d0\u4f9b\u4e0d\u9519\u7684\u5ef6\u8fdf\u8868\u73b0\u3002\u5e76\u4e14\u9664\u4e86\u8fdc\u7a0b\u684c\u9762\u4ee5\u5916\u8fd8\u63d0\u4f9b\u547d\u4ee4\u6267\u884c\u3001\u7cfb\u7edf\u62a5\u544a\u3001\u6587\u4ef6\u4f20\u8f93\u7b49\u7cfb\u7edf\u7ba1\u7406\u529f\u80fd\uff0c\u7f3a\u70b9\u662f\u53ea\u652f\u6301 MacOS\uff08Windows \u4e0b\u53ef\u4ee5\u4f7f\u7528\u652f\u6301 VNC \u534f\u8bae\u7684\u8f6f\u4ef6\u8fde\u63a5\uff0c\u4f46\u662f\u4f1a\u9000\u5316\u6210\u548c\u539f\u751f VNC \u4e00\u6837\u7684\u5783\u573e\u4f53\u9a8c\uff09<\/p>\n<h4 id=\"\u81ea\u5efa-vnc-server\">\u81ea\u5efa VNC Server<\/h4>\n<p>\u65e2\u7136\u81ea\u5e26\u7684 VNC \u5982\u6b64\u4e0d\u582a\u4f7f\u7528\uff0cARD \u53c8\u4e0d\u63d0\u4f9b Windows \u5ba2\u6237\u7aef\uff0c\u6211\u4eec\u53ea\u80fd\u6c42\u52a9\u4e8e\u7b2c\u4e09\u65b9\u8f6f\u4ef6\u6765\u63d0\u4f9b\u6ee1\u8840\u7248 VNC \u534f\u8bae\u652f\u6301\u3002\u8fd9\u91cc\u63a8\u8350 <a class=\"link\" href=\"https:\/\/www.realvnc.com\/en\/connect\/download\/vnc\/macos\/\" target=\"_blank\" rel=\"noopener\"\n>Real VNC<\/a>\uff0c\u53ef\u4ee5\u517c\u5177 VNC \u9ad8\u753b\u8d28\u548c ARD \u7684\u4f4e\u5ef6\u8fdf\uff0c\u9664\u4e86\u4e0d\u652f\u6301 HiDPI \u5916\u57fa\u672c\u4e0a\u80fd\u63d0\u4f9b\u548c\u8fde\u63a5\u663e\u793a\u5668\u4e00\u81f4\u7684\u4f53\u9a8c<\/p>\n<h3 id=\"\u7b2c\u4e09\u65b9\u8f6f\u4ef6\u79c1\u6709\u534f\u8bae\">\u7b2c\u4e09\u65b9\u8f6f\u4ef6\/\u79c1\u6709\u534f\u8bae<\/h3>\n<h4 id=\"todesk\">ToDesk<\/h4>\n<p>ToDesk \u5728\u6211\u7684\u4f53\u9a8c\u4e2d\u5361\u987f\u975e\u5e38\u4e25\u91cd\u3002\u9664\u4e86\u63d0\u4f9b\u514d\u8d39\u7684\u5185\u7f51\u7a7f\u900f\u4ee5\u5916\uff0c\u76f8\u6bd4\u5176\u4ed6\u65b9\u6848\u57fa\u672c\u4e0a\u6beb\u65e0\u4f18\u52bf\u53ef\u8a00\uff0c\u5982\u679c\u4f60\u6709\u516c\u7f51 IP \u7684\u8bdd\u4e0d\u8981\u9009\u62e9\u5b83\u3002\u6240\u4ee5\u540d\u6c14\u5927\u7684\uff08\u5c24\u5176\u662f\u56fd\u4ea7\u8f6f\u4ef6\uff09\u4e0d\u4e00\u5b9a\u771f\u7684\u597d\u7528\u3002\u3002\u3002<\/p>\n<h4 id=\"parsec\">ParSec<\/h4>\n<p>ParSec \u7684\u539f\u672c\u7528\u9014\u662f\u6e38\u620f\u4e32\u6d41\uff0c\u63d0\u4f9b\u7cbe\u7ec6\u7684\u914d\u7f6e\u9879\u53ef\u4f9b\u9009\u62e9\uff0c\u7ec6\u8282\u4e0a\u4f53\u9a8c\u5f88\u8212\u9002\u3002\u76f8\u6bd4\u4e8e\u5176\u4ed6\u65b9\u6848\u5b83\u7684\u5ef6\u8fdf\u548c\u753b\u9762\u8d28\u91cf\u5f88\u7a33\u5b9a\uff0c\u4e0d\u4f1a\u5728\u753b\u9762\u5feb\u901f\u53d8\u5316\u65f6\u5361\u987f\u6216\u8005\u7cca\u6389\uff0c\u5e76\u4e14\u652f\u6301\u64ad\u653e\u88ab\u63a7\u4e3b\u673a\u58f0\u97f3\u3002\u53ef\u80fd\u662f\u73b0\u5728 Mac \u7248\u8fd8\u5904\u4e8e Beta \u9636\u6bb5\u7684\u539f\u56e0\uff0cParSec \u5bf9\u6027\u80fd\u8981\u6c42\u5f88\u9ad8\uff0cRX460 \u5728 2560\u00d71440 \u5206\u8fa8\u7387\u4e0b\u5ef6\u8fdf 20ms \u5de6\u53f3\uff0c3440\u00d71440\uff082k \u5e26\u9c7c\u5c4f\uff09\u5206\u8fa8\u7387\u4e0b\u5ef6\u8fdf 40ms \u5de6\u53f3<\/p>\n<h4 id=\"jump-desktop\">Jump Desktop<\/h4>\n<p>Jump Desktop \u662f\u8001\u724c mac \u8fdc\u7a0b\u684c\u9762\u5e94\u7528\uff0c\u4f7f\u7528\u79c1\u6709\u7684 Fluid \u534f\u8bae\u3002\u5ef6\u8fdf\u4f4e\u3001\u5e26\u5bbd\u5360\u7528\u4f4e\uff0c\u4f46\u662f\u753b\u9762\u4e5f\u662f\u6700\u7cca\u7684\uff0c\u7279\u522b\u662f\u7a97\u53e3\u62d6\u52a8\u7b49\u753b\u9762\u5feb\u901f\u53d8\u5316\u7684\u573a\u666f\u6d82\u62b9\u611f\u975e\u5e38\u4e25\u91cd\u3002Jump Desktop \u652f\u6301\u81ea\u5b9a\u4e49\u4efb\u4f55\u6309\u952e\u6216\u662f\u7ec4\u5408\u952e\u7684\u6620\u5c04\uff0c\u548c ParSec \u4e00\u6837\u4e5f\u652f\u6301\u64ad\u653e\u88ab\u63a7\u4e3b\u673a\u58f0\u97f3<\/p>\n<h2 id=\"\u603b\u7ed3\u4e0e\u6027\u80fd\u6d4b\u8bd5\">\u603b\u7ed3\u4e0e\u6027\u80fd\u6d4b\u8bd5<\/h2>\n<p>\u6d4b\u8bd5\u73af\u5883\uff1a<\/p>\n<p>GPU\uff1a \u76f4\u901a RX460 GeekBench 5 Metal \u5206 21000 \u5de6\u53f3\uff0c\u6027\u80fd\u5927\u81f4\u76f8\u5f53\u4e8e M1 \u6838\u663e<br \/>\n\u7f51\u7edc\uff1a\u5185\u7f51\uff08\u7f51\u7edc\u5ef6\u8fdf &lt;1ms\uff09<br \/>\n\u5206\u8fa8\u7387\uff1a3440x1440\uff08\u975e HiDPI\uff09<br \/>\n\u8f6f\u4ef6\u7248\u672c\uff1a\u5404\u8f6f\u4ef6\u5747\u4f7f\u7528\u5f53\u524d\u6700\u65b0\u514d\u8d39\/\u8bd5\u7528\u7248\uff0c\u753b\u8d28\u9009\u62e9\u6700\u9ad8\u4e00\u6863<\/p>\n<table>\n<thead>\n<tr>\n<th>\u8f6f\u4ef6\/\u534f\u8bae<\/th>\n<th>\u5ef6\u8fdf<\/th>\n<th>\u753b\u8d28<\/th>\n<th>\u6309\u952e\u6620\u5c04<\/th>\n<th>\u591a\u663e\u793a\u5668<\/th>\n<th>\u58f0\u97f3<\/th>\n<th>\u6587\u4ef6\u4f20\u8f93<\/th>\n<th>\u8fde\u63a5\u65b9\u5f0f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u539f\u751f VNC<\/td>\n<td>\u9ad8<\/td>\n<td>\u6700\u597d\uff08\u652f\u6301 HiDPI\uff09<\/td>\n<td>\u4e0d\u652f\u6301\u4fee\u6539<\/td>\n<td>\u62fc\u63a5\u6240\u6709\u663e\u793a\u5668<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u76f4\u8fde<\/td>\n<\/tr>\n<tr>\n<td>RealVNC<\/td>\n<td>\u4f4e\uff082ms\uff09<\/td>\n<td>\u6700\u597d<\/td>\n<td>\u81ea\u5b9a\u4e49\u4efb\u4f55\u6309\u952e\u6620\u5c04<\/td>\n<td>\u670d\u52a1\u7aef\u914d\u7f6e<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u76f4\u8fde<\/td>\n<\/tr>\n<tr>\n<td>ARD<\/td>\n<td>\u4e2d\u7b49<\/td>\n<td>\u4e00\u822c\uff08\u6eda\u52a8\u65f6\u753b\u9762\u4f1a\u7cca\uff09<\/td>\n<td>\u4e0d\u652f\u6301\u4fee\u6539<\/td>\n<td>\u5ba2\u6237\u7aef\u9009\u62e9<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u76f4\u8fde<\/td>\n<\/tr>\n<tr>\n<td>ToDesk<\/td>\n<td>\u9ad8<\/td>\n<td>\u4e00\u822c\uff08\u6709\u660e\u663e\u6d82\u62b9\u611f\uff09<\/td>\n<td>\u81ea\u5b9a\u4e49\u529f\u80fd\u952e\u6620\u5c04<\/td>\n<td>\u5ba2\u6237\u7aef\u9009\u62e9<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u514d\u8d39\u5185\u7f51\u7a7f\u900f<\/td>\n<\/tr>\n<tr>\n<td>ParSec<\/td>\n<td>\u4e2d\u7b49\uff0840ms\uff09<\/td>\n<td>\u8f83\u597d\uff08\u6709\u8f7b\u5fae\u6d82\u62b9\u611f\uff09<\/td>\n<td>\u4e0d\u652f\u6301\u4fee\u6539<\/td>\n<td>\u5ba2\u6237\u7aef\u9009\u62e9<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u76f4\u8fde\uff08\u81ea\u52a8 UPNP\uff09<\/td>\n<\/tr>\n<tr>\n<td>Jump Desktop<\/td>\n<td>\u4f4e\uff0810ms\uff09<\/td>\n<td>\u5dee\uff08\u753b\u9762\u6700\u7cca\uff09<\/td>\n<td>\u81ea\u5b9a\u4e49\u4efb\u4f55\u6309\u952e\u6620\u5c04<\/td>\n<td>\u5ba2\u6237\u7aef\u9009\u62e9<\/td>\n<td>\u652f\u6301<\/td>\n<td>\u4e0d\u652f\u6301<\/td>\n<td>\u76f4\u8fde\uff08\u81ea\u52a8 UPNP\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u9664 ToDesk \u5916\u7684\u65b9\u6848\u82e5\u60f3\u8981\u901a\u8fc7\u516c\u7f51\u8bbf\u95ee\u5747\u9700\u8981\u88ab\u63a7\u7aef\u5177\u5907\u516c\u7f51 IP \u5e76\u914d\u7f6e\u7aef\u53e3\u6620\u5c04\u6216\u81ea\u884c\u642d\u5efa\u5185\u7f51\u7a7f\u900f<br \/>\nParSec \u548c Jump Desktop \u4f1a\u901a\u8fc7 UPNP \u5e2e\u4f60\u81ea\u52a8\u6620\u5c04\u7aef\u53e3\uff0c\u5e76\u4e14\u767b\u9646\u5b83\u4eec\u7684\u8d26\u53f7\u53ef\u4ee5\u76f4\u63a5\u770b\u5230\u4f60\u7684\u88ab\u63a7\u7aef\u4e3b\u673a\uff0c\u4e0d\u7528\u901a\u8fc7 IP \u624b\u52a8\u6dfb\u52a0\u4e3b\u673a\uff0c\u5c24\u5176\u9002\u7528\u4e8e\u4f60\u7684\u516c\u7f51 IP \u662f\u52a8\u6001 IP \u7684\u60c5\u51b5\n<\/div>\n<p><\/p>"},{"title":"RocketMQ \u8d1f\u8f7d\u5747\u8861\u65f6\u673a\u548c\u5f71\u54cd","link":"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence","pubDate":"Mon, 28 Mar 2022 17:15:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/rocketmq_logo.png\" alt=\"Featured image of post RocketMQ \u8d1f\u8f7d\u5747\u8861\u65f6\u673a\u548c\u5f71\u54cd\" \/><p>\u672c\u6587\u7efc\u5408 RocketMQ client \u4e0e broker \u7684\u6e90\u7801\u4ecb\u7ecd\u8d1f\u8f7d\u5747\u8861\u673a\u5236\u53d1\u751f\u7684\u65f6\u95f4\u3001\u5ba2\u6237\u7aef\u53d1\u751f\u8d1f\u8f7d\u5bf9\u6d88\u8d39\u7684\u5f71\u54cd\uff08\u6d88\u606f\u5806\u79ef\/\u6d88\u8d39\u6bdb\u523a\u7b49\uff09\u5e76\u4e14\u7ed9\u51fa\u4e00\u4e9b\u6700\u4f73\u5b9e\u8df5\u7684\u63a8\u8350<\/p>\n<h2 id=\"\u5199\u5728\u524d\u9762\">\u5199\u5728\u524d\u9762<\/h2>\n<p>\u7f51\u4e0a\u5927\u591a\u6570\u8bb2 RocketMQ \u8d1f\u8f7d\u5747\u8861\u7684\u6587\u7ae0\u53ea\u4ecb\u7ecd\u51e0\u79cd\u5206\u914d MessageQueue \u7684\u7b56\u7565\u6216\u662f\u957f\u7bc7\u5927\u8bba\u5206\u6790\u5ba2\u6237\u7aef RebalanceService \u7684\u4ee3\u7801\u3002\u4f46\u662f\u5176\u5b9e\u8d1f\u8f7d\u5747\u8861\u662f\u5ba2\u6237\u7aef\u4e0e\u670d\u52a1\u7aef\u4e92\u76f8\u914d\u5408\u7684\u8fc7\u7a0b\uff0c\u672c\u6587\u7efc\u5408\u670d\u52a1\u7aef\u548c\u5ba2\u6237\u7aef\u4ee3\u7801\u56de\u7b54\u5982\u4e0b\u4e09\u4e2a\u95ee\u9898\uff1a<\/p>\n<ol>\n<li>\u4f55\u65f6\u4f1a\u53d1\u751f\u8d1f\u8f7d\u5747\u8861<\/li>\n<li>\u8d1f\u8f7d\u5747\u8861\u5bf9\u6d88\u8d39\u6709\u4f55\u5f71\u54cd<\/li>\n<li>\u5982\u4f55\u51cf\u5c11\u8d1f\u8f7d\u5747\u8861\u5bf9\u6d88\u8d39\u7684\u5f71\u54cd<\/li>\n<\/ol>\n<p>\u5982\u679c\u4e0d\u60f3\u770b\u8be6\u7ec6\u5206\u6790\uff0c\u8fd9\u91cc\u76f4\u63a5\u7ed9\u51fa\u7ed3\u8bba\uff1a<\/p>\n<p>\u8d1f\u8f7d\u5747\u8861\u65f6\u673a\uff1a<\/p>\n<ul>\n<li>\u4e3b\u52a8\u8d1f\u8f7d\u5747\u8861\n<ol>\n<li>\u542f\u52a8\u65f6\u7acb\u5373\u8fdb\u884c\u8d1f\u8f7d\u5747\u8861<\/li>\n<li>\u5b9a\u65f6\uff08\u9ed8\u8ba4 20s\uff09\u8d1f\u8f7d\u5747\u8861\u4e00\u6b21<\/li>\n<\/ol>\n<\/li>\n<li>\u88ab\u52a8\u8d1f\u8f7d\u5747\u8861\uff08\u6536\u5230 broker \u901a\u77e5\uff09\n<ol>\n<li>\u5ba2\u6237\u7aef\u4e0a\u4e0b\u7ebf<\/li>\n<\/ol>\n<ul>\n<li>\u4e0a\u7ebf\n<ol>\n<li>\u65b0\u5ba2\u6237\u7aef\u53d1\u9001\u5fc3\u8df3\u5230 broker<\/li>\n<\/ol>\n<\/li>\n<li>\u4e0b\u7ebf\n<ol>\n<li>\u5ba2\u6237\u7aef\u53d1\u9001\u4e0b\u7ebf\u8bf7\u6c42\u5230 broker<\/li>\n<li>\u5e95\u5c42\u8fde\u63a5\u5f02\u5e38\uff1a\u54cd\u5e94 netty channel \u7684 IDLE\/CLOSE\/EXCEPTION \u4e8b\u4ef6<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<ol start=\"2\">\n<li>\u8ba2\u9605\u5173\u7cfb\u53d8\u5316\uff1a\u8ba2\u9605\u65b0 topic \u6216\u6709\u65e7\u7684 topic \u4e0d\u518d\u8ba2\u9605<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<p>\u8d1f\u8f7d\u5747\u8861\u5bf9\u6d88\u8d39\u7684\u5f71\u54cd\uff1a<\/p>\n<ol>\n<li>\u5bf9\u4e8e\u65b0\u5206\u914d\u7684\u961f\u5217\u53ef\u80fd\u4f1a\u91cd\u590d\u6d88\u8d39\uff0c\u8fd9\u4e5f\u662f\u5b98\u65b9\u8981\u6c42\u6d88\u8d39\u8981\u505a\u597d\u5e42\u7b49\u7684\u539f\u56e0<\/li>\n<li>\u5bf9\u4e8e\u4e0d\u518d\u8d1f\u8d23\u7684\u961f\u5217\u4f1a\u77ed\u65f6\u95f4\u6d88\u8d39\u505c\u6b62\uff0c\u5982\u679c\u539f\u672c\u7684\u6d88\u8d39 TPS \u5f88\u9ad8\u6216\u8005\u6b63\u597d\u51fa\u73b0\u751f\u4ea7\u9ad8\u5cf0\u5c31\u4f1a\u9020\u6210\u6d88\u8d39\u6bdb\u523a<\/li>\n<\/ol>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 180;\nflex-basis: 433px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/consume_glitch.png\" data-size=\"725x401\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/consume_glitch.png\"\nwidth=\"725\"\nheight=\"401\"\nloading=\"lazy\"\nalt=\"\u6d88\u8d39\u6bdb\u523a\uff08\u7eff\u8272\u662f\u6b63\u5e38\u6d88\u8d39\u66f2\u7ebf\uff0c\u9ec4\u8272\u4e3a\u51fa\u73b0\u6bdb\u523a\u7684\u6d88\u8d39\u66f2\u7ebf\uff09\">\n<\/a>\n<figcaption>\u6d88\u8d39\u6bdb\u523a\uff08\u7eff\u8272\u662f\u6b63\u5e38\u6d88\u8d39\u66f2\u7ebf\uff0c\u9ec4\u8272\u4e3a\u51fa\u73b0\u6bdb\u523a\u7684\u6d88\u8d39\u66f2\u7ebf\uff09<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u6e90\u7801\u5206\u6790\">\u6e90\u7801\u5206\u6790<\/h2>\n<p>\u9996\u5148\u660e\u786e\u4e0b\u4e0a\u4e0b\u6587\uff1a\u6e90\u7801\u5206\u6790\u57fa\u4e8e <a class=\"link\" href=\"https:\/\/github.com\/apache\/rocketmq\/tree\/release-4.9.3\" target=\"_blank\" rel=\"noopener\"\n>RocketMQ release-4.9.3<\/a> \u5206\u652f\u7684\u4ee3\u7801\u4ee5\u53ca\u96c6\u7fa4\u6d88\u8d39\u6a21\u5f0f\u7684 push \u6d88\u8d39\u8005\u3002\u5e7f\u64ad\u6a21\u5f0f\u4e0d\u5728\u672c\u6587\u7684\u8ba8\u8bba\u8303\u56f4\u5185<\/p>\n<h3 id=\"client-\u4e3b\u52a8\u89e6\u53d1\">Client \u4e3b\u52a8\u89e6\u53d1<\/h3>\n<p>\u5728\u540c\u4e00\u4e2a JVM \u4e2d\u4e0d\u7ba1\u521b\u5efa\u591a\u5c11 consumer\uff0c\u5b83\u4eec\u603b\u662f\u5171\u4eab\u540c\u4e00\u4e2a MQClientInstance\uff0c\u8fd9\u4e2a MQClientInstance \u63a5\u7ba1\u548c\u6240\u6709 consumer \u548c broker \u7684\u4ea4\u4e92\u4ee5\u53ca\u534f\u8c03\u8d1f\u8f7d\u5747\u8861<\/p>\n<div class=\"mermaid\" style=\"margin: auto; width: 80%;\">classDiagram\nclass MQProducer\n&lt;&lt;interface&gt;&gt; MQProducer\nMQProducer &lt;|-- DefaultMQProducer\nClientConfig &lt;|-- DefaultMQProducer\nDefaultMQProducer: &#43;DefaultMQProducerImpl defaultMQProducerImpl\nDefaultMQProducer: &#43;start()\nDefaultMQProducer ..&gt; DefaultMQProducerImpl: use\nDefaultMQProducerImpl: &#43;MQClientInstance mQClientFactory\nDefaultMQProducerImpl: &#43;start()\nclass MQConsumer\n&lt;&lt;interface&gt;&gt; MQConsumer\nMQConsumer &lt;|-- DefaultMQPushConsumer\nClientConfig &lt;|-- DefaultMQPushConsumer\nDefaultMQPushConsumer: &#43;DefaultMQPushConsumerImpl defaultMQPushConsumerImpl\nDefaultMQPushConsumer: &#43;start()\nDefaultMQPushConsumer ..&gt; DefaultMQPushConsumerImpl: use\nDefaultMQPushConsumerImpl: &#43;MQClientInstance mQClientFactory\nDefaultMQPushConsumerImpl: &#43;start()\nDefaultMQProducerImpl ..&gt; MQClientInstance: use\nDefaultMQPushConsumerImpl ..&gt; MQClientInstance: use\nMQClientInstance: &#43;start()\n<\/div>\n<p>MQClientInstance \u6709\u4e24\u4e2a\u8d1f\u8f7d\u5747\u8861\u76f8\u5173\u7684\u65b9\u6cd5\uff1a<code>rebalanceImmediately<\/code> \u548c <code>doRebalance<\/code><br \/>\n\u524d\u8005\u5728\u6d88\u8d39\u8005\u542f\u52a8\u548c\u6536\u5230 Broker \u901a\u77e5\u65f6\u5524\u9192 RebalanceService \u8fdb\u884c\u8d1f\u8f7d\u5747\u8861\uff0c\u800c RebalanceService \u8c03\u7528\u540e\u8005\u6267\u884c\u8d1f\u8f7d\u5747\u8861\u903b\u8f91<br \/>\n\u8ddf\u8e2a <code>doRebalance<\/code> \u65b9\u6cd5\uff0c\u6211\u4eec\u53d1\u73b0\u5b9e\u9645\u7684\u8d1f\u8f7d\u5747\u8861\u903b\u8f91\u5728 <code>RebalanceImpl#rebalanceByTopic<\/code> \u4e2d\u5b9e\u73b0\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">private<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">rebalanceByTopic<\/span><span class=\"o\">(<\/span><span class=\"kd\">final<\/span> <span class=\"n\">String<\/span> <span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">isOrder<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u83b7\u53d6\u6240\u6709 MessageQueue\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">Set<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageQueue<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">mqSet<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">topicSubscribeInfoTable<\/span><span class=\"o\">.<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"n\">topic<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u83b7\u53d6\u5f53\u524d group \u6240\u6709\u5728\u7ebf\u7684\u6d88\u8d39\u8005\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">String<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">cidAll<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">mQClientFactory<\/span><span class=\"o\">.<\/span><span class=\"na\">findConsumerIdList<\/span><span class=\"o\">(<\/span><span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"n\">consumerGroup<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u6392\u5e8f\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">Collections<\/span><span class=\"o\">.<\/span><span class=\"na\">sort<\/span><span class=\"o\">(<\/span><span class=\"n\">mqAll<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Collections<\/span><span class=\"o\">.<\/span><span class=\"na\">sort<\/span><span class=\"o\">(<\/span><span class=\"n\">cidAll<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u83b7\u53d6\u5f53\u524d\u5ba2\u6237\u7aef\u914d\u7f6e\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">AllocateMessageQueueStrategy<\/span> <span class=\"n\">strategy<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">allocateMessageQueueStrategy<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageQueue<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">allocateResult<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">null<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u6839\u636e\u6307\u5b9a\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u8ba1\u7b97\u81ea\u5df1\u8981\u8d1f\u8d23\u7684\u961f\u5217\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">allocateResult<\/span> <span class=\"o\">=<\/span> <span class=\"n\">strategy<\/span><span class=\"o\">.<\/span><span class=\"na\">allocate<\/span><span class=\"o\">(<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">consumerGroup<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">mQClientFactory<\/span><span class=\"o\">.<\/span><span class=\"na\">getClientId<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">mqAll<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u6839\u636e\u8ba1\u7b97\u7ed3\u679c\u521b\u5efa ProcessQueue \uff08\u7528\u4e8e\u62c9\u53d6\u3001\u6d88\u8d39\u6d88\u606f\u7684\u6570\u636e\u7ed3\u6784\uff09\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">changed<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">updateProcessQueueTableInRebalance<\/span><span class=\"o\">(<\/span><span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"n\">allocateResultSet<\/span><span class=\"o\">,<\/span> <span class=\"n\">isOrder<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">changed<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u5982\u679c ProcessQueue \u6709\u66f4\u65b0\u5219\u8fdb\u884c\u4e00\u4e9b\u5904\u7406\u5de5\u4f5c\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">messageQueueChanged<\/span><span class=\"o\">(<\/span><span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"n\">mqSet<\/span><span class=\"o\">,<\/span> <span class=\"n\">allocateResultSet<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u901a\u8fc7\u5206\u6790\u4ee5\u4e0a\u4ee3\u7801\u6211\u4eec\u53ef\u4ee5\u770b\u51fa\u8d1f\u8f7d\u5747\u8861\u7684\u5b9e\u9645\u5de5\u4f5c\u662f\u8ba1\u7b97\u51fa\u5f53\u524d\u5ba2\u6237\u7aef\u5206\u914d\u7684 MessageQueue\uff0c\u5e76\u4e14\u4fdd\u6301 ProcessQueue \u4e0e\u5206\u914d\u5230\u7684 MessageQueue \u4e00\u4e00\u5bf9\u5e94\uff0c\u521b\u5efa ProcessQueue \u7684\u5177\u4f53\u6d41\u7a0b\u5728 <code>RebalanceImpl#updateProcessQueueTableInRebalance<\/code> \u65b9\u6cd5\u4e2d\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">private<\/span> <span class=\"kt\">boolean<\/span> <span class=\"nf\">updateProcessQueueTableInRebalance<\/span><span class=\"o\">(<\/span><span class=\"kd\">final<\/span> <span class=\"n\">String<\/span> <span class=\"n\">topic<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">Set<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageQueue<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">mqSet<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">isOrder<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u5220\u9664\u4e0d\u518d\u8d1f\u8d23\u7684 MessageQueue \u5bf9\u5e94\u7684 ProcessQueue\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">Iterator<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Entry<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageQueue<\/span><span class=\"o\">,<\/span> <span class=\"n\">ProcessQueue<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"n\">it<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">processQueueTable<\/span><span class=\"o\">.<\/span><span class=\"na\">entrySet<\/span><span class=\"o\">().<\/span><span class=\"na\">iterator<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">while<\/span> <span class=\"o\">(<\/span><span class=\"n\">it<\/span><span class=\"o\">.<\/span><span class=\"na\">hasNext<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Entry<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageQueue<\/span><span class=\"o\">,<\/span> <span class=\"n\">ProcessQueue<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">next<\/span> <span class=\"o\">=<\/span> <span class=\"n\">it<\/span><span class=\"o\">.<\/span><span class=\"na\">next<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">MessageQueue<\/span> <span class=\"n\">mq<\/span> <span class=\"o\">=<\/span> <span class=\"n\">next<\/span><span class=\"o\">.<\/span><span class=\"na\">getKey<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ProcessQueue<\/span> <span class=\"n\">pq<\/span> <span class=\"o\">=<\/span> <span class=\"n\">next<\/span><span class=\"o\">.<\/span><span class=\"na\">getValue<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">mq<\/span><span class=\"o\">.<\/span><span class=\"na\">getTopic<\/span><span class=\"o\">().<\/span><span class=\"na\">equals<\/span><span class=\"o\">(<\/span><span class=\"n\">topic<\/span><span class=\"o\">))<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(!<\/span><span class=\"n\">mqSet<\/span><span class=\"o\">.<\/span><span class=\"na\">contains<\/span><span class=\"o\">(<\/span><span class=\"n\">mq<\/span><span class=\"o\">))<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u505c\u6b62 ProcessQueue \u7684\u6d88\u8d39\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">pq<\/span><span class=\"o\">.<\/span><span class=\"na\">setDropped<\/span><span class=\"o\">(<\/span><span class=\"kc\">true<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u5411 Broker \u66f4\u65b0 offset\uff0c\u5982\u679c\u662f\u987a\u5e8f\u6d88\u8d39\u4f1a\u91ca\u653e\u7533\u8bf7\u7684\u9501\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">removeUnnecessaryMessageQueue<\/span><span class=\"o\">(<\/span><span class=\"n\">mq<\/span><span class=\"o\">,<\/span> <span class=\"n\">pq<\/span><span class=\"o\">))<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">it<\/span><span class=\"o\">.<\/span><span class=\"na\">remove<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">changed<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">true<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">log<\/span><span class=\"o\">.<\/span><span class=\"na\">info<\/span><span class=\"o\">(<\/span><span class=\"s\">&#34;doRebalance, {}, remove unnecessary mq, {}&#34;<\/span><span class=\"o\">,<\/span> <span class=\"n\">consumerGroup<\/span><span class=\"o\">,<\/span> <span class=\"n\">mq<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u4e3a\u65b0\u5206\u914d\u7684 MessageQueue \u521b\u5efa ProcessQueue\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">PullRequest<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">pullRequestList<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">ArrayList<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">PullRequest<\/span><span class=\"o\">&gt;();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">MessageQueue<\/span> <span class=\"n\">mq<\/span> <span class=\"o\">:<\/span> <span class=\"n\">mqSet<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(!<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">processQueueTable<\/span><span class=\"o\">.<\/span><span class=\"na\">containsKey<\/span><span class=\"o\">(<\/span><span class=\"n\">mq<\/span><span class=\"o\">))<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ProcessQueue<\/span> <span class=\"n\">pq<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">ProcessQueue<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">nextOffset<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"n\">0<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ProcessQueue<\/span> <span class=\"n\">pre<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">processQueueTable<\/span><span class=\"o\">.<\/span><span class=\"na\">putIfAbsent<\/span><span class=\"o\">(<\/span><span class=\"n\">mq<\/span><span class=\"o\">,<\/span> <span class=\"n\">pq<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"broker-\u901a\u77e5\u89e6\u53d1\">Broker \u901a\u77e5\u89e6\u53d1<\/h3>\n<p>\u901a\u8fc7\u4e0a\u6587\u6211\u4eec\u77e5\u9053\u9664\u4e86 RebalanceService \u5b9a\u65f6\u8fdb\u884c\u8d1f\u8f7d\u5747\u8861\u4ee5\u5916\uff0c\u8fd8\u53ef\u4ee5\u8c03\u7528 <code>MQClientInstance#rebalanceImmediately<\/code> \u65b9\u6cd5\u7acb\u523b\u89e6\u53d1\u8d1f\u8f7d\u5747\u8861\u3002\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u5728\u6d88\u8d39\u8005\u542f\u52a8\u548c\u6536\u5230 Broker \u901a\u77e5\u65f6\u8c03\u7528\uff08<code>ClientRemotingProcessor#notifyConsumerIdsChanged<\/code>\uff09<br \/>\n\u800c Broker \u4f1a\u5728\u5982\u4e0b\u51e0\u4e2a\u65b9\u6cd5\u4e2d\u53d1\u9001\u901a\u77e5\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 474;\nflex-basis: 1139px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/notify_timing.png\" data-size=\"660x139\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/notify_timing.png\"\nwidth=\"660\"\nheight=\"139\"\nloading=\"lazy\"\nalt=\"Broker \u901a\u77e5\">\n<\/a>\n<figcaption>Broker \u901a\u77e5<\/figcaption>\n<\/figure><\/p>\n<p>\u6211\u4eec\u4f9d\u6b21\u5206\u6790\u8fd9\u4e09\u4e2a\u65b9\u6cd5\uff1a<\/p>\n<p><code>ConsumerManager#registerConsumer<\/code> \u65b9\u6cd5\u5904\u7406\u6765\u81ea\u5ba2\u6237\u7aef\u7684\u5fc3\u8df3\u8bf7\u6c42<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">public<\/span> <span class=\"kt\">boolean<\/span> <span class=\"nf\">registerConsumer<\/span><span class=\"o\">(<\/span><span class=\"kd\">final<\/span> <span class=\"n\">String<\/span> <span class=\"n\">group<\/span><span class=\"o\">,<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">ClientChannelInfo<\/span> <span class=\"n\">clientChannelInfo<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ConsumeType<\/span> <span class=\"n\">consumeType<\/span><span class=\"o\">,<\/span> <span class=\"n\">MessageModel<\/span> <span class=\"n\">messageModel<\/span><span class=\"o\">,<\/span> <span class=\"n\">ConsumeFromWhere<\/span> <span class=\"n\">consumeFromWhere<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kd\">final<\/span> <span class=\"n\">Set<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">SubscriptionData<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">subList<\/span><span class=\"o\">,<\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">isNotifyConsumerIdsChangedEnable<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u662f\u5426\u662f\u65b0\u5ba2\u6237\u7aef\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">r1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">consumerGroupInfo<\/span><span class=\"o\">.<\/span><span class=\"na\">updateChannel<\/span><span class=\"o\">(<\/span><span class=\"n\">clientChannelInfo<\/span><span class=\"o\">,<\/span> <span class=\"n\">consumeType<\/span><span class=\"o\">,<\/span> <span class=\"n\">messageModel<\/span><span class=\"o\">,<\/span> <span class=\"n\">consumeFromWhere<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u66f4\u65b0\u8ba2\u9605\u6570\u636e\uff0c\u5f53\u8ba2\u9605\u65b0 topic \u6216\u6709\u65e7\u7684 topic \u4e0d\u518d\u8ba2\u9605\u65f6\u8fd4\u56de true\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kt\">boolean<\/span> <span class=\"n\">r2<\/span> <span class=\"o\">=<\/span> <span class=\"n\">consumerGroupInfo<\/span><span class=\"o\">.<\/span><span class=\"na\">updateSubscription<\/span><span class=\"o\">(<\/span><span class=\"n\">subList<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">r1<\/span> <span class=\"o\">||<\/span> <span class=\"n\">r2<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u53ef\u4ee5\u5728 BrokerConfig \u4e2d\u914d\u7f6e\uff0c\u9ed8\u8ba4\u4e3a true\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">isNotifyConsumerIdsChangedEnable<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u901a\u77e5\u5ba2\u6237\u7aef\u8fdb\u884c\u8d1f\u8f7d\u5747\u8861\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">consumerIdsChangeListener<\/span><span class=\"o\">.<\/span><span class=\"na\">handle<\/span><span class=\"o\">(<\/span><span class=\"n\">ConsumerGroupEvent<\/span><span class=\"o\">.<\/span><span class=\"na\">CHANGE<\/span><span class=\"o\">,<\/span> <span class=\"n\">group<\/span><span class=\"o\">,<\/span> <span class=\"n\">consumerGroupInfo<\/span><span class=\"o\">.<\/span><span class=\"na\">getAllChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p><code>ConsumerManager#unregisterConsumer<\/code> \u65b9\u6cd5\u5904\u7406\u6765\u81ea\u5ba2\u6237\u7aef\u7684\u4e0b\u7ebf\u8bf7\u6c42\uff0c\u548c <code>ConsumerManager#registerConsumer<\/code> \u7c7b\u4f3c\uff0c\u4e0d\u518d\u8d58\u8ff0<\/p>\n<p><code>ConsumerManager#doChannelCloseEvent<\/code> \u65b9\u6cd5\u5728\u5982\u4e0b\u4e09\u4e2a\u65b9\u6cd5\u4e2d\u8c03\u7528<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 802;\nflex-basis: 1926px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/channel_close.png\" data-size=\"570x71\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/rocketmq-rebalancing-timing-and-influence\/channel_close.png\"\nwidth=\"570\"\nheight=\"71\"\nloading=\"lazy\"\nalt=\"Channel Close\">\n<\/a>\n<figcaption>Channel Close<\/figcaption>\n<\/figure><\/p>\n<p>\u8fd9\u4e09\u4e2a\u65b9\u6cd5\u5728 <code>NettyRemotingAbstract#run<\/code> \u4e2d\u8c03\u7528\uff0c\u5904\u7406 netty channel \u7684\u4e8b\u4ef6\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@Override<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">run<\/span><span class=\"o\">()<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kd\">final<\/span> <span class=\"n\">ChannelEventListener<\/span> <span class=\"n\">listener<\/span> <span class=\"o\">=<\/span> <span class=\"n\">NettyRemotingAbstract<\/span><span class=\"o\">.<\/span><span class=\"na\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannelEventListener<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">while<\/span> <span class=\"o\">(!<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">isStopped<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">try<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">NettyEvent<\/span> <span class=\"n\">event<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">eventQueue<\/span><span class=\"o\">.<\/span><span class=\"na\">poll<\/span><span class=\"o\">(<\/span><span class=\"n\">3000<\/span><span class=\"o\">,<\/span> <span class=\"n\">TimeUnit<\/span><span class=\"o\">.<\/span><span class=\"na\">MILLISECONDS<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">event<\/span> <span class=\"o\">!=<\/span> <span class=\"kc\">null<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"n\">listener<\/span> <span class=\"o\">!=<\/span> <span class=\"kc\">null<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">switch<\/span> <span class=\"o\">(<\/span><span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getType<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">case<\/span> <span class=\"n\">IDLE<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">listener<\/span><span class=\"o\">.<\/span><span class=\"na\">onChannelIdle<\/span><span class=\"o\">(<\/span><span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getRemoteAddr<\/span><span class=\"o\">(),<\/span> <span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">break<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">case<\/span> <span class=\"n\">CLOSE<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">listener<\/span><span class=\"o\">.<\/span><span class=\"na\">onChannelClose<\/span><span class=\"o\">(<\/span><span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getRemoteAddr<\/span><span class=\"o\">(),<\/span> <span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">break<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">case<\/span> <span class=\"n\">CONNECT<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">listener<\/span><span class=\"o\">.<\/span><span class=\"na\">onChannelConnect<\/span><span class=\"o\">(<\/span><span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getRemoteAddr<\/span><span class=\"o\">(),<\/span> <span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">break<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">case<\/span> <span class=\"n\">EXCEPTION<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">listener<\/span><span class=\"o\">.<\/span><span class=\"na\">onChannelException<\/span><span class=\"o\">(<\/span><span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getRemoteAddr<\/span><span class=\"o\">(),<\/span> <span class=\"n\">event<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">break<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">default<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">break<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"o\">(<\/span><span class=\"n\">Exception<\/span> <span class=\"n\">e<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">log<\/span><span class=\"o\">.<\/span><span class=\"na\">warn<\/span><span class=\"o\">(<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">getServiceName<\/span><span class=\"o\">()<\/span> <span class=\"o\">+<\/span> <span class=\"s\">&#34; service has exception. &#34;<\/span><span class=\"o\">,<\/span> <span class=\"n\">e<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u4e5f\u5c31\u662f\u8bf4 channel \u4e8b\u4ef6 IDLE\/CLOSE\/EXCEPTION \u90fd\u4f1a\u89e6\u53d1\u91cd\u65b0\u8d1f\u8f7d\u5747\u8861\uff0c\u9664\u4e86\u5e95\u5c42\u8fde\u63a5\u7684\u53d8\u5316\u5916 Broker \u4e5f\u4f1a\u5728\u957f\u65f6\u95f4\u6ca1\u6536\u5230\u5ba2\u6237\u7aef\u5fc3\u8df3\u65f6\u4e3b\u52a8\u65ad\u5f00\u8fde\u63a5\u89e6\u53d1\u8d1f\u8f7d\u5747\u8861\uff0c\u8be6\u89c1 <code>ConsumerManager#scanNotActiveChannel<\/code>\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">scanNotActiveChannel<\/span><span class=\"o\">()<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">Iterator<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Entry<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Channel<\/span><span class=\"o\">,<\/span> <span class=\"n\">ClientChannelInfo<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"n\">itChannel<\/span> <span class=\"o\">=<\/span> <span class=\"n\">channelInfoTable<\/span><span class=\"o\">.<\/span><span class=\"na\">entrySet<\/span><span class=\"o\">().<\/span><span class=\"na\">iterator<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">while<\/span> <span class=\"o\">(<\/span><span class=\"n\">itChannel<\/span><span class=\"o\">.<\/span><span class=\"na\">hasNext<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Entry<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Channel<\/span><span class=\"o\">,<\/span> <span class=\"n\">ClientChannelInfo<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">nextChannel<\/span> <span class=\"o\">=<\/span> <span class=\"n\">itChannel<\/span><span class=\"o\">.<\/span><span class=\"na\">next<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ClientChannelInfo<\/span> <span class=\"n\">clientChannelInfo<\/span> <span class=\"o\">=<\/span> <span class=\"n\">nextChannel<\/span><span class=\"o\">.<\/span><span class=\"na\">getValue<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kt\">long<\/span> <span class=\"n\">diff<\/span> <span class=\"o\">=<\/span> <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">currentTimeMillis<\/span><span class=\"o\">()<\/span> <span class=\"o\">-<\/span> <span class=\"n\">clientChannelInfo<\/span><span class=\"o\">.<\/span><span class=\"na\">getLastUpdateTimestamp<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u9ed8\u8ba4\u4e24\u5206\u949f\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">diff<\/span> <span class=\"o\">&gt;<\/span> <span class=\"n\">CHANNEL_EXPIRED_TIMEOUT<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u5173\u95ed\u8fde\u63a5\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">RemotingUtil<\/span><span class=\"o\">.<\/span><span class=\"na\">closeChannel<\/span><span class=\"o\">(<\/span><span class=\"n\">clientChannelInfo<\/span><span class=\"o\">.<\/span><span class=\"na\">getChannel<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">itChannel<\/span><span class=\"o\">.<\/span><span class=\"na\">remove<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">...<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6700\u540e\u603b\u7ed3\u4e00\u4e0b\u5728\u5982\u4e0b\u573a\u666f Broker \u4f1a\u4e3b\u52a8\u901a\u77e5\u5ba2\u6237\u7aef\u89e6\u53d1\u8d1f\u8f7d\u5747\u8861\uff1a<\/p>\n<ol>\n<li>\u5ba2\u6237\u7aef\u4e0a\u4e0b\u7ebf\n<ul>\n<li>\u4e0a\u7ebf\n<ol>\n<li>\u65b0\u5ba2\u6237\u7aef\u53d1\u9001\u5fc3\u8df3\u5230 broker<\/li>\n<\/ol>\n<\/li>\n<li>\u4e0b\u7ebf\n<ol>\n<li>\u65b0\u5ba2\u6237\u7aef\u53d1\u9001\u4e0b\u7ebf\u8bf7\u6c42\u5230 broker<\/li>\n<li>\u5e95\u5c42\u8fde\u63a5\u5f02\u5e38\uff1a\u54cd\u5e94 netty channel \u7684 IDLE\/CLOSE\/EXCEPTION \u4e8b\u4ef6<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<\/li>\n<li>\u8ba2\u9605\u5173\u7cfb\u53d8\u5316\uff1a\u8ba2\u9605\u65b0 topic \u6216\u6709\u65e7\u7684 topic \u4e0d\u518d\u8ba2\u9605<\/li>\n<\/ol>\n<h2 id=\"\u6700\u4f73\u5b9e\u8df5\">\u6700\u4f73\u5b9e\u8df5<\/h2>\n<h3 id=\"\u907f\u514d\u9891\u7e41\u4e0a\u4e0b\u7ebf\">\u907f\u514d\u9891\u7e41\u4e0a\u4e0b\u7ebf<\/h3>\n<p>\u4ece\u4e0a\u8ff0\u6e90\u7801\u5206\u6790\u53ef\u4ee5\u770b\u51fa\uff0c\u8d1f\u8f7d\u5747\u8861\u662f\u4e00\u4e2a\u975e\u5e38\u9891\u7e41\u7684\u64cd\u4f5c\uff0c\u5e76\u4e0d\u662f\u6bcf\u4e00\u6b21\u8d1f\u8f7d\u5747\u8861\u90fd\u4f1a\u5bf9\u6d88\u8d39\u4ea7\u751f\u5f71\u54cd\u3002\u8d1f\u8f7d\u5747\u8861\u5bf9\u5ba2\u6237\u7aef\u7684\u5f71\u54cd\u53cd\u6620\u5728\u5bf9 ProcessQueue \u7684\u53d8\u66f4\u4e0a\u3002\u56e0\u4e3a\u6ca1\u6709\u4e00\u4e2a\u534f\u8c03\u673a\u5236\u786e\u4fdd\u65b0\u65e7 ProcessQueue \u7684\u521b\u5efa\u987a\u5e8f\uff0c\u6240\u4ee5\u53ef\u80fd\u4f1a\u53d1\u751f\u4e24\u79cd\u60c5\u51b5\uff1a<\/p>\n<ol>\n<li>\u65e7 ProcessQueue \u9500\u6bc1\u65e9\u4e8e\u65b0 ProcessQueue \u521b\u5efa\uff1a\u6b64\u65f6\u6d88\u8d39\u77ed\u6682\u505c\u6b62\uff0c\u4f1a\u9020\u6210\u6d88\u8d39\u5ef6\u8fdf<\/li>\n<li>\u65b0 ProcessQueue \u521b\u5efa\u65e9\u4e8e\u65e7 ProcessQueue \u9500\u6bc1\uff1a\u6b64\u65f6\u4f1a\u6709\u77ed\u6682\u7684\u65f6\u95f4\u4e24\u4e2a\u6d88\u8d39\u8005\u540c\u65f6\u6d88\u8d39\u540c\u4e00\u4e2a\u961f\u5217\uff0c\u4f1a\u6d88\u8d39\u4f4d\u70b9\u56de\u9000\u6216\u91cd\u590d\u6d88\u8d39\uff0c\u8fd9\u4e5f\u662f\u5b98\u65b9\u8981\u6c42\u6d88\u8d39\u8981\u505a\u597d\u5e42\u7b49\u7684\u539f\u56e0<\/li>\n<\/ol>\n<p>\u6240\u4ee5\u4e3a\u4e86\u907f\u514d\u8d1f\u8f7d\u5747\u8861\u7684\u5f71\u54cd\u5e94\u8be5\u5c3d\u91cf\u51cf\u5c11\u5ba2\u6237\u7aef\u7684\u4e0a\u4e0b\u7ebf\uff0c\u540c\u65f6\u505a\u597d\u6d88\u8d39\u5e42\u7b49<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5728\u6709\u5e94\u7528\u91cd\u542f\u6216\u4e0b\u7ebf\u524d\u8981\u8c03\u7528 <code>shutdown<\/code> \u65b9\u6cd5\uff0c\u8fd9\u6837 Broker \u6536\u5230\u5ba2\u6237\u7aef\u7684\u4e0b\u7ebf\u8bf7\u6c42\u540e\u4f1a\u7acb\u523b\u89e6\u53d1\u8d1f\u8f7d\u5747\u8861\n<\/div>\n<p><\/p>\n<h3 id=\"\u9009\u62e9\u5408\u9002\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\">\u9009\u62e9\u5408\u9002\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565<\/h3>\n<p>\u524d\u6587\u5df2\u7ecf\u4ecb\u7ecd\u4e86\u8d1f\u8f7d\u5747\u8861\u5bf9\u5ba2\u6237\u7aef\u7684\u5f71\u54cd\u53cd\u6620\u5728\u5bf9 ProcessQueue \u7684\u53d8\u66f4\u4e0a\uff0c\u6bcf\u6b21\u9700\u8981\u53d8\u66f4\u7684 ProcessQueue \u7684\u6570\u91cf\u548c\u53d7\u5230\u5f71\u54cd\u7684\u5ba2\u6237\u7aef\u6570\u91cf\u662f\u7531\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u51b3\u5b9a\u7684<\/p>\n<p>\u5982\u679c\u6211\u4eec\u6709 4 \u4e2a\u5ba2\u6237\u7aef\uff0c24 \u4e2a\u961f\u5217\uff0c\u5f53\u7b2c\u4e8c\u4e2a\u5ba2\u6237\u7aef\u4e0b\u7ebf\u65f6\uff1a<\/p>\n<p>\u4ee5\u9ed8\u8ba4\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\uff08AllocateMessageQueueAveragely\uff09\u4e3a\u4f8b\uff0c\u91cd\u5efa ProcessQueue \u7684\u961f\u5217\u6570\u91cf\u4e3a 8<br \/>\n\u9ed8\u8ba4\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u80fd\u5c06\u961f\u5217\u5c3d\u91cf\u5747\u8861\u7684\u5206\u914d\u5230\u6bcf\u4e2a\u5ba2\u6237\u7aef\uff0c\u4f46\u662f\u6bcf\u6b21\u8d1f\u8f7d\u5747\u8861\u91cd\u5efa ProcessQueue \u6570\u91cf\u8f83\u591a\uff0c\u5c24\u5176\u662f\u5728\u5ba2\u6237\u7aef\u6570\u91cf\u5f88\u591a\u7684\u573a\u666f<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5ba2\u6237\u7aef<\/th>\n<th>\u961f\u5217\u5206\u914d\u53d8\u5316<\/th>\n<th>\u961f\u5217\u6570\u53d8\u5316<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Client1<\/td>\n<td>1~6 -&gt; 1~8<\/td>\n<td>6 -&gt; 8<\/td>\n<\/tr>\n<tr>\n<td>Client2<\/td>\n<td>7~12 -&gt; -<\/td>\n<td>6 -&gt; 0<\/td>\n<\/tr>\n<tr>\n<td>Client3<\/td>\n<td>13~18 -&gt; 9~16<\/td>\n<td>6 -&gt; 8<\/td>\n<\/tr>\n<tr>\n<td>Client4<\/td>\n<td>19~24 -&gt; 17~24<\/td>\n<td>6 -&gt; 8<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u4ee5\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\uff08AllocateMessageQueueConsistentHash\uff09\u4e3a\u4f8b\uff0c\u91cd\u5efa ProcessQueue \u7684\u961f\u5217\u6570\u91cf\u4e3a 6\uff08\u4e0d\u8003\u8651\u865a\u62df\u8282\u70b9\uff09<br \/>\n\u57fa\u4e8e\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u6bcf\u6b21\u8d1f\u8f7d\u5747\u8861\u4f1a\u91cd\u5efa\u5c3d\u53ef\u80fd\u5c11\u7684 ProcessQueue \u6570\u91cf\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u51fa\u73b0\u8d1f\u8f7d\u4e0d\u5747\u7684\u60c5\u51b5<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5ba2\u6237\u7aef<\/th>\n<th>\u961f\u5217\u5206\u914d\u53d8\u5316<\/th>\n<th>\u961f\u5217\u6570\u53d8\u5316<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Client1<\/td>\n<td>1~6 -&gt; 1~9<\/td>\n<td>6 -&gt; 9<\/td>\n<\/tr>\n<tr>\n<td>Client2<\/td>\n<td>7~12 -&gt; -<\/td>\n<td>6 -&gt; 0<\/td>\n<\/tr>\n<tr>\n<td>Client3<\/td>\n<td>13~18 -&gt; 10~18<\/td>\n<td>6 -&gt; 9<\/td>\n<\/tr>\n<tr>\n<td>Client4<\/td>\n<td>19~24 -&gt; 19~24<\/td>\n<td>6 -&gt; 8<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u4ee5\u4e0a\u4e24\u4e2a\u793a\u4f8b\u662f\u5bf9\u7b80\u5355\u60c5\u51b5\u7684\u6a21\u62df\uff0c\u5728\u751f\u4ea7\u4e2d\u9700\u8981\u6839\u636e\u9700\u8981\u9009\u62e9\u5408\u9002\u7684\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\n<\/div>\n<p><\/p>\n<h3 id=\"\u5ba2\u6237\u7aef\u53c2\u6570\u4fdd\u6301\u4e00\u81f4\">\u5ba2\u6237\u7aef\u53c2\u6570\u4fdd\u6301\u4e00\u81f4<\/h3>\n<p>RocketMQ \u7684\u8d1f\u8f7d\u5747\u8861\u662f\u6bcf\u4e2a\u5ba2\u6237\u7aef\u72ec\u7acb\u8fdb\u884c\u8ba1\u7b97\uff0c\u6240\u4ee5\u52a1\u5fc5\u8981\u4fdd\u8bc1\u6bcf\u4e2a\u5ba2\u6237\u7aef\u7684\u8d1f\u8f7d\u5747\u8861\u7b97\u6cd5\u548c\u8ba2\u9605\u8bed\u53e5\u4e00\u81f4<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock error\">\n\u8d1f\u8f7d\u5747\u8861\u7b56\u7565\u4e0d\u4e00\u81f4\u4f1a\u5bfc\u81f4\u591a\u4e2a\u5ba2\u6237\u7aef\u5206\u914d\u5230\u76f8\u540c\u961f\u5217\u6216\u6709\u5ba2\u6237\u7aef\u5206\u4e0d\u5230\u961f\u5217<br \/>\n\u8ba2\u9605\u8bed\u53e5\u4e0d\u4e00\u81f4\u4f1a\u5bfc\u81f4\u6709\u6d88\u606f\u672a\u80fd\u6d88\u8d39\n<\/div>\n<p><\/p>"},{"title":"Spring + Kotlin ORM \u6846\u67b6 Exposed \u6559\u7a0b","link":"https:\/\/blog.lv5.moe\/p\/guide-to-spring-and-kotlin-orm-framework-exposed","pubDate":"Sat, 19 Mar 2022 16:34:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/guide-to-spring-and-kotlin-orm-framework-exposed","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/guide-to-spring-and-kotlin-orm-framework-exposed\/exposed_logo.jpg\" alt=\"Featured image of post Spring + Kotlin ORM \u6846\u67b6 Exposed \u6559\u7a0b\" \/><p>\u672c\u6559\u7a0b\u5305\u62ec Kotlin ORM \u6846\u67b6 Exposed \u7684\u4f7f\u7528\u65b9\u6cd5\u548c\u4e00\u4e9b\u8fdb\u9636\u6280\u5de7\uff0c\u5e76\u4ecb\u7ecd Exposed \u4e0e Spring \u96c6\u6210\u7684\u65b9\u6cd5\u4ee5\u53ca\u535a\u4e3b\u8e29\u8fc7\u7684\u4e00\u4e9b\u5751<\/p>\n<h2 id=\"exposed-\u4ecb\u7ecd\">Exposed \u4ecb\u7ecd<\/h2>\n<p><a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\" target=\"_blank\" rel=\"noopener\"\n>Exposed<\/a> \u662f JetBrains \u5b98\u65b9\u51fa\u54c1\u7684 Kotlin ORM \u6846\u67b6\uff0c\u6709\u5982\u4e0b\u4f18\u70b9\uff1a<\/p>\n<ol>\n<li>\u652f\u6301\u591a\u79cd\u6570\u636e\u5e93\uff1aH2\u3001MySQL\u3001PostgreSQL\u3001SQL Server\u3001SQLite \u7b49<\/li>\n<li>\u63d0\u4f9b\u4e24\u5957 API\uff1aSQL DSL \u548c DAO API\uff08\u4e0d\u77e5\u9053\u4ec0\u4e48\u662f DSL \u53ef\u4ee5\u9605\u8bfb\u6211\u7684\u4e4b\u524d\u7684\u6587\u7ae0\uff1a<a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl\" >Kotlin DSL \u7b80\u4ecb<\/a>\uff09<\/li>\n<li>JetBrains \u5b98\u65b9\u51fa\u54c1\uff0c\u6587\u6863\u5b8c\u5584\uff0c\u6613\u4e8e\u4f7f\u7528<\/li>\n<\/ol>\n<h3 id=\"\u57fa\u672c\u6982\u5ff5\">\u57fa\u672c\u6982\u5ff5<\/h3>\n<h4 id=\"\u8fde\u63a5\u6570\u636e\u5e93\">\u8fde\u63a5\u6570\u636e\u5e93<\/h4>\n<p>\u9996\u5148\u9700\u8981\u5f15\u5165\u4f9d\u8d56\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-xml\" data-lang=\"xml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;groupId&gt;<\/span>org.jetbrains.exposed<span class=\"nt\">&lt;\/groupId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;artifactId&gt;<\/span>exposed-core<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;version&gt;<\/span>0.37.3<span class=\"nt\">&lt;\/version&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;\/dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;groupId&gt;<\/span>org.jetbrains.exposed<span class=\"nt\">&lt;\/groupId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;artifactId&gt;<\/span>exposed-dao<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;version&gt;<\/span>0.37.3<span class=\"nt\">&lt;\/version&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;\/dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;groupId&gt;<\/span>org.jetbrains.exposed<span class=\"nt\">&lt;\/groupId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;artifactId&gt;<\/span>exposed-jdbc<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;version&gt;<\/span>0.37.3<span class=\"nt\">&lt;\/version&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;\/dependency&gt;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u5efa\u7acb\u6570\u636e\u5e93\u8fde\u63a5\uff1a<br \/>\n\u5173\u4e8e\u6570\u636e\u5e93\u548c\u6570\u636e\u6e90\u7684\u66f4\u591a\u8bf4\u660e\u67e5\u770b<a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\/wiki\/DataBase-and-DataSource\" target=\"_blank\" rel=\"noopener\"\n>\u5b98\u65b9 WIKI<\/a><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">Database<\/span><span class=\"p\">.<\/span><span class=\"n\">connect<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;jdbc:h2:mem:test&#34;<\/span><span class=\"p\">,<\/span> <span class=\"n\">driver<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;org.h2.Driver&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6700\u540e\u5f00\u542f\u4e8b\u52a1\u64cd\u4f5c\u6570\u636e\u5e93\uff1a<br \/>\n\u4e0d\u8bba\u662f SQL DSL \u8fd8\u662f DAO API \u90fd\u9700\u8981\u5728 <code>transaction<\/code> \u5757\u4e2d\u6267\u884c<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">addLogger<\/span><span class=\"p\">(<\/span><span class=\"n\">StdOutSqlLogger<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ Do something\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">commit<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ Do something\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">rollback<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u4e8b\u52a1\u652f\u6301\u8fd4\u56de\u7ed3\u679c\uff1a<br \/>\nBlob\u3001text \u4ee5\u53ca\u4e00\u5bf9\u591a\/\u591a\u5bf9\u4e00\u7684\u5b57\u6bb5\u4e0d\u80fd\u5728\u4e8b\u52a1\u5916\u4f7f\u7528\uff0c\u66f4\u591a\u8bf4\u660e\u67e5\u770b<a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\/wiki\/Transactions\" target=\"_blank\" rel=\"noopener\"\n>\u5b98\u65b9 WIKI<\/a><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span> <span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"tabledao\">Table\/DAO<\/h4>\n<p>\u5efa\u8868\uff1a<br \/>\n\u5982\u4e0b\u7684 Queries \u7c7b\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a query \u7684\u8868\uff0c\u5e76\u6dfb\u52a0\u4e86 4 \u4e2a\u5b57\u6bb5<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">object<\/span> <span class=\"nc\">Queries<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntIdTable<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;query&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">title<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;title&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">1024<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;userId&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">256<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">type<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;type&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">256<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">createTime<\/span> <span class=\"p\">=<\/span> <span class=\"n\">timestamp<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;createTime&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>Exposed \u4e0d\u4f1a\u81ea\u52a8\u751f\u6210 migration\uff0c\u4f46\u662f\u53ef\u4ee5\u4f7f\u7528 <code>SchemaUtils#create<\/code> \u6765\u5728\u6570\u636e\u5e93\u4e2d\u8fd0\u884c\u5efa\u8868\u8bed\u53e5<br \/>\n\u5b98\u65b9\u63d0\u4f9b\u4e00\u4e2a gradle \u63d2\u4ef6\u6765\u6839\u636e\u6570\u636e\u5e93\u7ed3\u6784\u751f\u6210 Table \u4ee3\u7801\uff1a<a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/exposed-intellij-plugin\" target=\"_blank\" rel=\"noopener\"\n>exposed-intellij-plugin<\/a><\/p>\n<p>\u521b\u5efa\u5b9e\u4f53\u7c7b\uff1a<br \/>\n\u5982\u679c\u8981\u4f7f\u7528 Exposed \u7684 DAO API\uff0c\u9700\u8981\u521b\u5efa\u8868\u5bf9\u5e94\u7684\u5b9e\u4f53\uff08Queries -&gt; QueryEntity\uff09<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">QueryEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Int<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">companion<\/span> <span class=\"k\">object<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntityClass<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">QueryEntity<\/span><span class=\"p\">&gt;(<\/span><span class=\"n\">Queries<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">title<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">title<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">userId<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">userId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">type<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">type<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">createTime<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">createTime<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"crud\">CRUD<\/h4>\n<p>\u8fd9\u91cc\u7ed9\u51fa\u4e24\u79cd API \u7684\u7b80\u5355\u793a\u4f8b\uff1a<\/p>\n<p>SQL DSL\uff1a<br \/>\n<a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\/wiki\/DSL\" target=\"_blank\" rel=\"noopener\"\n>\u6587\u6863<\/a><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">insert<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">title<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;title&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">userId<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;123&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">type<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;type&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">createTime<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Instant<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">select<\/span> <span class=\"p\">{<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span> <span class=\"n\">eq<\/span> <span class=\"m\">1<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">update<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">title<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;titleUpdate&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">userId<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;456&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">type<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;typeUpdate&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">createTime<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Instant<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">deleteWhere<\/span> <span class=\"p\">{<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">id<\/span> <span class=\"n\">eq<\/span> <span class=\"m\">1<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>DAO API\uff1a<br \/>\n<a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\/wiki\/DAO\" target=\"_blank\" rel=\"noopener\"\n>\u6587\u6863<\/a><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">new<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;title&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;123&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">type<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;type&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">createTime<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Instant<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">result<\/span><span class=\"o\">?.<\/span><span class=\"n\">title<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;titleUpdate&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">result<\/span><span class=\"o\">?.<\/span><span class=\"n\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;456&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">result<\/span><span class=\"o\">?.<\/span><span class=\"n\">type<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;titleUpdate&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">result<\/span><span class=\"o\">?.<\/span><span class=\"n\">createTime<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Instant<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">result<\/span><span class=\"o\">?.<\/span><span class=\"n\">delete<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u8fdb\u9636\u4f7f\u7528\">\u8fdb\u9636\u4f7f\u7528<\/h3>\n<h4 id=\"\u7d22\u5f15\">\u7d22\u5f15<\/h4>\n<p>Exposed \u652f\u6301\u521b\u5efa\u5355\u5217\/\u591a\u5217\u7d22\u5f15\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">object<\/span> <span class=\"nc\">Queries<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntIdTable<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;query&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;userId&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">256<\/span><span class=\"p\">).<\/span><span class=\"n\">index<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;userId&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">256<\/span><span class=\"p\">).<\/span><span class=\"n\">uniqueIndex<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">userId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">varchar<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;userId&#34;<\/span><span class=\"p\">,<\/span> <span class=\"m\">256<\/span><span class=\"p\">).<\/span><span class=\"n\">index<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;index_userId_unique&#34;<\/span><span class=\"p\">,<\/span> <span class=\"k\">true<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">index<\/span> <span class=\"p\">=<\/span> <span class=\"n\">index<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;index_title_userId_unique&#34;<\/span><span class=\"p\">,<\/span><span class=\"k\">true<\/span><span class=\"p\">,<\/span> <span class=\"n\">title<\/span><span class=\"p\">,<\/span> <span class=\"n\">userId<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"\u4e00\u5bf9\u591a\u591a\u5bf9\u4e00\">\u4e00\u5bf9\u591a\/\u591a\u5bf9\u4e00<\/h4>\n<p>\u9996\u5148\u521b\u5efa\u5916\u952e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">object<\/span> <span class=\"nc\">Histories<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntIdTable<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;history&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">queryId<\/span> <span class=\"p\">=<\/span> <span class=\"n\">reference<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;query_id&#34;<\/span><span class=\"p\">,<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">,<\/span> <span class=\"n\">onDelete<\/span> <span class=\"p\">=<\/span> <span class=\"n\">ReferenceOption<\/span><span class=\"p\">.<\/span><span class=\"n\">CASCADE<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u5728\u5b9e\u4f53\u7c7b\u4e0a\u6dfb\u52a0\u76f8\u5e94\u7684\u5b57\u6bb5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">QueryEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Int<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u4e00\u5bf9\u591a\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">val<\/span> <span class=\"py\">histories<\/span> <span class=\"k\">by<\/span> <span class=\"n\">HistoryEntity<\/span> <span class=\"n\">referrersOn<\/span> <span class=\"n\">Histories<\/span><span class=\"p\">.<\/span><span class=\"n\">queryId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">HistoryEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Int<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u591a\u5bf9\u4e00\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">var<\/span> <span class=\"py\">query<\/span> <span class=\"k\">by<\/span> <span class=\"n\">QueryEntity<\/span> <span class=\"n\">referencedOn<\/span> <span class=\"n\">Histories<\/span><span class=\"p\">.<\/span><span class=\"n\">queryId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5728\u67e5\u8be2\u4e2d\u5373\u53ef\u76f4\u63a5\u8bbf\u95ee\u5bf9\u5e94\u5b57\u6bb5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u4f7f\u7528 load \u63d0\u524d\u52a0\u8f7d histories \u5b57\u6bb5\uff0c\u907f\u514d N+1 \u95ee\u9898\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">findById<\/span><span class=\"p\">(<\/span><span class=\"m\">1<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">?.<\/span><span class=\"n\">load<\/span><span class=\"p\">(<\/span><span class=\"n\">QueryEntity<\/span><span class=\"o\">::<\/span><span class=\"n\">histories<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">?.<\/span><span class=\"n\">histories<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">?.<\/span><span class=\"n\">forEach<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ do something\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h4 id=\"upsert\">upsert<\/h4>\n<p>Exposed \u5e76\u6ca1\u6709\u63d0\u4f9b\u5f00\u7bb1\u5373\u7528\u7684 upsert \u529f\u80fd\uff08\u7c7b\u4f3c MySQL \u7684 ON DUPLICATE KEY UPDATE\uff09\uff0c\u9700\u8981\u81ea\u5df1\u62d3\u5c55\uff08\u8be6\u89c1\u8fd9\u4e2a <a class=\"link\" href=\"https:\/\/github.com\/JetBrains\/Exposed\/issues\/167\" target=\"_blank\" rel=\"noopener\"\n>Issue<\/a>\uff09<\/p>\n<p>\u8fd9\u91cc\u63a8\u8350\u4e00\u4e2a\u5e93\u5e2e\u6211\u4eec\u5b9e\u73b0\u4e86 upsert\uff1a<a class=\"link\" href=\"https:\/\/github.com\/reposilite-playground\/exposed-upsert\" target=\"_blank\" rel=\"noopener\"\n>exposed-upsert<\/a><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u4e5f\u53ef\u4ee5\u4f7f\u7528 conflictIndex \u6307\u5b9a\u81ea\u884c\u521b\u5efa\u7684\u552f\u4e00\u7d22\u5f15\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">upsert<\/span><span class=\"p\">(<\/span><span class=\"n\">conflictColumn<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">userId<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">insertBody<\/span> <span class=\"p\">=<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">title<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">queryData<\/span><span class=\"p\">.<\/span><span class=\"n\">title<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">userId<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">queryData<\/span><span class=\"p\">.<\/span><span class=\"n\">userId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">type<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">queryData<\/span><span class=\"p\">.<\/span><span class=\"n\">type<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">createTime<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Instant<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">},<\/span> <span class=\"n\">updateBody<\/span> <span class=\"p\">=<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">title<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">queryData<\/span><span class=\"p\">.<\/span><span class=\"n\">title<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">it<\/span><span class=\"p\">[<\/span><span class=\"n\">type<\/span><span class=\"p\">]<\/span> <span class=\"p\">=<\/span> <span class=\"n\">queryData<\/span><span class=\"p\">.<\/span><span class=\"n\">type<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"exposed-\u4e0e-spring-\u96c6\u6210\">Exposed \u4e0e Spring \u96c6\u6210<\/h2>\n<p>\u5b98\u65b9\u63d0\u4f9b Exposed Spring Boot Starter\uff0c\u7528 Exposed \u66ff\u6362 Hibernate<\/p>\n<h3 id=\"\u914d\u7f6e\">\u914d\u7f6e<\/h3>\n<p>\u5f15\u5165\u4f9d\u8d56\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-xml\" data-lang=\"xml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;dependencies&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;groupId&gt;<\/span>org.jetbrains.exposed<span class=\"nt\">&lt;\/groupId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;artifactId&gt;<\/span>exposed-spring-boot-starter<span class=\"nt\">&lt;\/artifactId&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;version&gt;<\/span>0.37.3<span class=\"nt\">&lt;\/version&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&lt;\/dependency&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nt\">&lt;\/dependencies&gt;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u914d\u7f6e\u6570\u636e\u5e93\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-yaml\" data-lang=\"yaml\"><span class=\"line\"><span class=\"cl\"><span class=\"nt\">spring<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">datasource<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">url<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">jdbc:h2:mem:testdb<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">driverClassName<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"l\">org.h2.Driver<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">exposed<\/span><span class=\"p\">:<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"c\"># \u81ea\u52a8\u5728\u6570\u636e\u5e93\u4e2d\u5efa\u8868<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"> <\/span><span class=\"nt\">generate-ddl<\/span><span class=\"p\">:<\/span><span class=\"w\"> <\/span><span class=\"kc\">true<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><h3 id=\"transaction\">transaction<\/h3>\n<p>Exposed \u7684\u4e24\u79cd API \u90fd\u9700\u8981\u5728 <code>transaction<\/code> \u5757\u4e2d\u6267\u884c\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">transaction<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">all<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5728 spring \u4e2d\u53ef\u4ee5\u7528 Transactional \u6ce8\u89e3\u4ee3\u66ff transaction \u5757\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@Transactional<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">fun<\/span> <span class=\"nf\">all<\/span><span class=\"p\">():<\/span> <span class=\"n\">List<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">QueryEntity<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"n\">QueryEntity<\/span><span class=\"p\">.<\/span><span class=\"n\">all<\/span><span class=\"p\">().<\/span><span class=\"n\">toList<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u9700\u8981\u8c03\u7528 rollback\u3001commit \u7b49\u65b9\u6cd5\u9700\u8981\u4f7f\u7528 <code>TransactionManager#current<\/code> \u83b7\u53d6\u5f53\u524d Transaction \u5b9e\u4f8b<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@Transactional<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">fun<\/span> <span class=\"nf\">rollback<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ Do something\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">TransactionManager<\/span><span class=\"p\">.<\/span><span class=\"n\">current<\/span><span class=\"p\">().<\/span><span class=\"n\">rollback<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"json-\u8f6c\u6362\">json \u8f6c\u6362<\/h3>\n<p>\u8fd9\u91cc\u4ee5 spring \u9ed8\u8ba4\u4f7f\u7528\u7684 json \u5e93 jackson \u4e3a\u4f8b\uff0cgson \u6216 fastjson \u539f\u7406\u4e0a\u662f\u4e00\u6837\u7684<\/p>\n<p>\u9996\u5148\u56de\u987e\u4e0b\u6211\u4eec\u4e4b\u524d\u521b\u5efa\u7684\u5b9e\u4f53\u7c7b QueryEntity\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">QueryEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Int<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">companion<\/span> <span class=\"k\">object<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntityClass<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">QueryEntity<\/span><span class=\"p\">&gt;(<\/span><span class=\"n\">Queries<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">title<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">title<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">userId<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">userId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">type<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">type<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">var<\/span> <span class=\"py\">createTime<\/span> <span class=\"k\">by<\/span> <span class=\"n\">Queries<\/span><span class=\"p\">.<\/span><span class=\"n\">createTime<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">histories<\/span> <span class=\"k\">by<\/span> <span class=\"n\">HistoryEntity<\/span> <span class=\"n\">referrersOn<\/span> <span class=\"n\">Histories<\/span><span class=\"p\">.<\/span><span class=\"n\">queryId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0\u5b9e\u4f53\u7c7b QueryEntity \u7ee7\u627f\u81ea IntEntity\uff0c\u5e8f\u5217\u5316\/\u53cd\u5e8f\u5217\u5316\u65f6\u6211\u4eec\u53ea\u9700\u8981\u975e IntEntity \u7c7b\u7684\u5b57\u6bb5\uff0c\u800c IntEntity \u53c8\u7ee7\u627f\u81ea Entity\uff0c\u6211\u7684\u505a\u6cd5\u662f\u8ba9 jackson \u5ffd\u7565\u6240\u6709\u5c5e\u4e8e Entity \u6216 IntEntity \u7c7b\u7684\u5b57\u6bb5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@Configuration<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">JacksonConfig<\/span> <span class=\"p\">:<\/span> <span class=\"n\">Jackson2ObjectMapperBuilderCustomizer<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">customize<\/span><span class=\"p\">(<\/span><span class=\"n\">jacksonObjectMapperBuilder<\/span><span class=\"p\">:<\/span> <span class=\"n\">Jackson2ObjectMapperBuilder<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">jacksonObjectMapperBuilder<\/span><span class=\"p\">.<\/span><span class=\"n\">modulesToInstall<\/span><span class=\"p\">(<\/span><span class=\"k\">object<\/span> <span class=\"err\">:<\/span><span class=\"nc\">Module<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">version<\/span><span class=\"p\">():<\/span> <span class=\"n\">Version<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Version<\/span><span class=\"p\">(<\/span><span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"m\">0<\/span><span class=\"p\">,<\/span><span class=\"s2\">&#34;&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">getModuleName<\/span><span class=\"p\">():<\/span> <span class=\"n\">String<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">setupModule<\/span><span class=\"p\">(<\/span><span class=\"n\">context<\/span><span class=\"p\">:<\/span> <span class=\"n\">SetupContext<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">context<\/span><span class=\"p\">.<\/span><span class=\"n\">insertAnnotationIntrospector<\/span><span class=\"p\">(<\/span><span class=\"k\">object<\/span> <span class=\"err\">: <\/span><span class=\"nc\">JacksonAnnotationIntrospector<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">hasIgnoreMarker<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">:<\/span> <span class=\"n\">AnnotatedMember<\/span><span class=\"p\">):<\/span> <span class=\"n\">Boolean<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">declaringClass<\/span> <span class=\"o\">==<\/span> <span class=\"n\">IntEntity<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">||<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">declaringClass<\/span> <span class=\"o\">==<\/span> <span class=\"n\">Entity<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">||<\/span> <span class=\"k\">super<\/span><span class=\"p\">.<\/span><span class=\"n\">hasIgnoreMarker<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u4e0d\u80fd\u76f4\u63a5\u4f7f\u7528 <code>Jackson2ObjectMapperBuilder#annotationIntrospector<\/code> \u6ce8\u5165 annotationIntrospector\uff0c\u5426\u5219\u4f1a\u4f7f KotlinModule \u7684 annotationIntrospector \u5931\u6548\n<\/div>\n<p><\/p>\n<p>\u5982\u679c\u9700\u8981\u5e8f\u5217\u5316 <code>id<\/code> \u5b57\u6bb5\uff0c\u9700\u8981\u5141\u8bb8 id \u548c getId \u5b57\u6bb5\u53c2\u4e0e\u5e8f\u5217\u5316\u3002\u56e0\u4e3a id \u5b57\u6bb5\u4e0d\u662f Int \u6216 String \u7b49\u57fa\u7840\u7c7b\u578b\uff0c\u6240\u4ee5\u6211\u4eec\u8fd8\u9700\u8981\u81ea\u5b9a\u4e49\u5e8f\u5217\u5316\u5668\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@Configuration<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">JacksonConfig<\/span> <span class=\"p\">:<\/span> <span class=\"n\">Jackson2ObjectMapperBuilderCustomizer<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">customize<\/span><span class=\"p\">(<\/span><span class=\"n\">jacksonObjectMapperBuilder<\/span><span class=\"p\">:<\/span> <span class=\"n\">Jackson2ObjectMapperBuilder<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">jacksonObjectMapperBuilder<\/span><span class=\"p\">.<\/span><span class=\"n\">serializerByType<\/span><span class=\"p\">(<\/span><span class=\"n\">EntityID<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">,<\/span> <span class=\"k\">object<\/span><span class=\"p\">:<\/span> <span class=\"n\">JsonSerializer<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">EntityID<\/span><span class=\"p\">&lt;*&gt;&gt;()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">serialize<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;*&gt;?,<\/span> <span class=\"n\">gen<\/span><span class=\"p\">:<\/span> <span class=\"n\">JsonGenerator<\/span><span class=\"p\">,<\/span> <span class=\"n\">serializers<\/span><span class=\"p\">:<\/span> <span class=\"n\">SerializerProvider<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">value<\/span> <span class=\"o\">==<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">gen<\/span><span class=\"p\">.<\/span><span class=\"n\">writeNull<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">value<\/span> <span class=\"k\">is<\/span> <span class=\"n\">Int<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">gen<\/span><span class=\"p\">.<\/span><span class=\"n\">writeNumber<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">value<\/span> <span class=\"k\">as<\/span> <span class=\"n\">Int<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">value<\/span> <span class=\"k\">is<\/span> <span class=\"n\">Long<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">gen<\/span><span class=\"p\">.<\/span><span class=\"n\">writeNumber<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">value<\/span> <span class=\"k\">as<\/span> <span class=\"n\">Long<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">gen<\/span><span class=\"p\">.<\/span><span class=\"n\">writeString<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"n\">toString<\/span><span class=\"p\">())<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">jacksonObjectMapperBuilder<\/span><span class=\"p\">.<\/span><span class=\"n\">modulesToInstall<\/span><span class=\"p\">(<\/span><span class=\"k\">object<\/span> <span class=\"err\">:<\/span><span class=\"nc\">Module<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">version<\/span><span class=\"p\">():<\/span> <span class=\"n\">Version<\/span> <span class=\"p\">=<\/span> <span class=\"n\">Version<\/span><span class=\"p\">(<\/span><span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"m\">0<\/span><span class=\"p\">,<\/span> <span class=\"m\">0<\/span><span class=\"p\">,<\/span><span class=\"s2\">&#34;&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">getModuleName<\/span><span class=\"p\">():<\/span> <span class=\"n\">String<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">setupModule<\/span><span class=\"p\">(<\/span><span class=\"n\">context<\/span><span class=\"p\">:<\/span> <span class=\"n\">SetupContext<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">context<\/span><span class=\"p\">.<\/span><span class=\"n\">insertAnnotationIntrospector<\/span><span class=\"p\">(<\/span><span class=\"k\">object<\/span> <span class=\"err\">: <\/span><span class=\"nc\">JacksonAnnotationIntrospector<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">override<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">hasIgnoreMarker<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">:<\/span> <span class=\"n\">AnnotatedMember<\/span><span class=\"p\">):<\/span> <span class=\"n\">Boolean<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span> <span class=\"o\">!=<\/span> <span class=\"s2\">&#34;id&#34;<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span> <span class=\"o\">!=<\/span> <span class=\"s2\">&#34;getId&#34;<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">declaringClass<\/span> <span class=\"o\">==<\/span> <span class=\"n\">IntEntity<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">||<\/span> <span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span> <span class=\"o\">!=<\/span> <span class=\"s2\">&#34;id&#34;<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span> <span class=\"o\">!=<\/span> <span class=\"s2\">&#34;getId&#34;<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"n\">declaringClass<\/span> <span class=\"o\">==<\/span> <span class=\"n\">Entity<\/span><span class=\"o\">::<\/span><span class=\"k\">class<\/span><span class=\"p\">.<\/span><span class=\"n\">java<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">||<\/span> <span class=\"k\">super<\/span><span class=\"p\">.<\/span><span class=\"n\">hasIgnoreMarker<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u56e0\u4e3a\u59d4\u6258\u5c5e\u6027\u4e0d\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 JsonIgnore\u3001JsonInclude \u7b49\u6ce8\u89e3\uff0c\u9700\u8981\u4f7f\u7528 <code>@get:JsonIgnore<\/code><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-Kotlin\" data-lang=\"Kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">QueryEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">:<\/span> <span class=\"n\">EntityID<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Int<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IntEntity<\/span><span class=\"p\">(<\/span><span class=\"n\">id<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">..<\/span><span class=\"p\">.<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nd\">@get<\/span><span class=\"p\">:<\/span><span class=\"n\">JsonIgnore<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">histories<\/span> <span class=\"k\">by<\/span> <span class=\"n\">HistoryEntity<\/span> <span class=\"n\">referrersOn<\/span> <span class=\"n\">Histories<\/span><span class=\"p\">.<\/span><span class=\"n\">queryId<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"RocketMQ \u6d88\u606f\u5806\u79ef\u7b97\u6cd5\u8be6\u89e3\u4e0e\u4f18\u5316","link":"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag","pubDate":"Thu, 16 Sep 2021 15:39:06 +0800","guid":"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag","description":"<img src=\"https:\/\/blog.lv5.moe\/img\/keqing.jpg\" alt=\"Featured image of post RocketMQ \u6d88\u606f\u5806\u79ef\u7b97\u6cd5\u8be6\u89e3\u4e0e\u4f18\u5316\" \/><h2 id=\"\u80cc\u666f\">\u80cc\u666f<\/h2>\n<p>\u6d88\u606f\u5806\u79ef\u662f\u6d88\u606f\u4e2d\u95f4\u4ef6\u7684\u4e00\u5927\u7279\u8272\uff0c\u4e5f\u662f\u6d88\u606f\u4e2d\u95f4\u4ef6\u7684\u6838\u5fc3\u80fd\u529b\u3002\u4f46\u662f\u6d88\u606f\u5806\u79ef\u4e5f\u662f\u6d88\u8d39\u6ede\u540e\u7684\u4e00\u79cd\u8868\u73b0\u5f62\u5f0f\uff0c\u8fc7\u91cf\u7684\u5806\u79ef\u96be\u514d\u4f1a\u5f71\u54cd\u4e0a\u4e0b\u6e38\u7684\u4e1a\u52a1\u3002\u6240\u4ee5\u5bf9\u6d88\u8d39\u5806\u79ef\u91cf\u548c\u5ef6\u8fdf\u65f6\u95f4\u7684\u76d1\u63a7\u610f\u4e49\u91cd\u5927\uff0c\u672c\u6587\u8be6\u89e3 RocketMQ \u6d88\u8d39\u5806\u79ef\u91cf\u548c\u6d88\u606f\u6d88\u8d39\u5ef6\u65f6\u8fd9\u4e24\u4e2a\u91cd\u8981\u6307\u6807\u7684\u542b\u4e49\u548c\u7b97\u6cd5\u5b9e\u73b0\uff0c\u8bf4\u660e\u5176\u5728\u5bf9\u6d88\u606f\u5ef6\u65f6\u8981\u6c42\u8f83\u9ad8\u548c\u542f\u7528\u6d88\u606f\u8fc7\u6ee4\u7b49\u573a\u666f\u4e2d\u7684\u5c40\u9650\u5e76\u7ed9\u51fa\u4f18\u5316\u65b9\u6cd5<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u672c\u6587\u9002\u7528\u4e8e\u96c6\u7fa4\u6d88\u8d39\u6a21\u5f0f\u4e0b\u4f7f\u7528 DefaultMQPushConsumer \u8fdb\u884c\u6d88\u8d39\u7684\u60c5\u51b5\n<\/div>\n<p><\/p>\n<h2 id=\"\u6d88\u8d39\u4f4d\u70b9\u7684\u7ba1\u7406consumeroffsetpulloffset-\u548c-maxoffset\">\u6d88\u8d39\u4f4d\u70b9\u7684\u7ba1\u7406\uff1aConsumerOffset\u3001PullOffset \u548c MaxOffset<\/h2>\n<p>RocketMQ \u4e2d\u6bcf\u4e2a Topic \u90fd\u4f1a\u521b\u5efa\u82e5\u5e72\u4e2a ConsumerQueue\u3002\u6d88\u8d39\u8005\u8ba2\u9605\u67d0\u4e2a Topic \u5b9e\u9645\u4e0a\u4f1a\u5206\u914d\u5230\u4e00\u4e2a\u6216\u51e0\u4e2a ConsumerQueue\uff0c\u7136\u540e\u6d88\u8d39 ConsumerQueue \u4e0a\u7684\u6d88\u606f\uff0c\u6240\u4ee5 RocketMQ \u5bf9\u6d88\u8d39\u4f4d\u70b9\u7684\u7ba1\u7406\u4e5f\u662f\u57fa\u4e8e ConsumerQueue \u7684<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 244;\nflex-basis: 587px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag\/consumerQueue.png\" data-size=\"746x305\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag\/consumerQueue.png\"\nwidth=\"746\"\nheight=\"305\"\nloading=\"lazy\"\nalt=\"ConsumerQueue\">\n<\/a>\n<figcaption>ConsumerQueue<\/figcaption>\n<\/figure><\/p>\n<p>\u4e0a\u56fe\u4e2d\u5c55\u793a\u4e86\u4e09\u4e2a\u548c\u6d88\u8d39\u8fdb\u5ea6\u6709\u5173\u7684\u4f4d\u70b9\uff1a<\/p>\n<ul>\n<li>ConsumerOffset\uff1a\u6d88\u8d39\u8005\u786e\u8ba4\u6d88\u8d39\u6210\u529f\u7684\u4f4d\u70b9\uff0c\u4e5f\u79f0\u4e3a CommitOffset<\/li>\n<li>PullOffset\uff1a\u6d88\u8d39\u8005\u62c9\u53d6\u6d88\u606f\u7684\u4f4d\u70b9<\/li>\n<li>MaxOffset\uff1a\u6d88\u8d39\u8005\u53ef\u4ee5\u6d88\u8d39\u5230\u7684\u6700\u5927\u4f4d\u70b9<\/li>\n<\/ul>\n<p>\u4e0b\u9762\u8be6\u7ec6\u89e3\u91ca\u8fd9\u4e09\u4e2a\u4f4d\u70b9\u7684\u8ba1\u7b97\u65b9\u6cd5<\/p>\n<h3 id=\"consumeroffset\">ConsumerOffset<\/h3>\n<p>\u6d88\u8d39\u8005\u5728\u6bcf\u6b21\u62c9\u53d6\u6d88\u606f\u7684\u8bf7\u6c42\u4e2d\u90fd\u4f1a\u8bbe\u7f6e\u4e00\u4e2a commitOffset \u5b57\u6bb5\uff08PullMessageRequestHeader#commitOffset\uff09Broker \u6839\u636e\u8fd9\u4e2a\u5b57\u6bb5\u8c03\u7528 ConsumerOffsetManager#commitOffset \u6765\u66f4\u65b0 offsetTable\u3002offsetTable \u7684\u50a8\u5b58\u7ed3\u6784\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-json\" data-lang=\"json\"><span class=\"line\"><span class=\"cl\"><span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&#34;offsetTable&#34;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ topic@consumerGroup\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"nt\">&#34;test-topic@test-group&#34;<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ queueId: consumerOffset\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"nt\">&#34;0&#34;<\/span><span class=\"p\">:<\/span> <span class=\"mi\">88526<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&#34;1&#34;<\/span><span class=\"p\">:<\/span> <span class=\"mi\">88528<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u4e0b\u9762\u6211\u4eec\u6765\u5206\u6790\u4e00\u4e0b\u6d88\u8d39\u8005\u62c9\u53d6\u8bf7\u6c42\u4e2d\u7684 PullMessageRequestHeader#commitOffset \u5b57\u6bb5\u662f\u5982\u4f55\u8ba1\u7b97\u51fa\u6765\u7684\uff1a<\/p>\n<p>PullMessageRequestHeader \u662f\u5728 PullAPIWrapper#pullKernelImpl \u65b9\u6cd5\u4e2d\u6784\u9020\u7684\uff0c\u800c\u8fd9\u4e2a\u65b9\u6cd5\u88ab DefaultMQPushConsumerImpl#pullMessage \u8c03\u7528\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kt\">long<\/span> <span class=\"n\">commitOffsetValue<\/span> <span class=\"o\">=<\/span> <span class=\"n\">0L<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">MessageModel<\/span><span class=\"o\">.<\/span><span class=\"na\">CLUSTERING<\/span> <span class=\"o\">==<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">defaultMQPushConsumer<\/span><span class=\"o\">.<\/span><span class=\"na\">getMessageModel<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">commitOffsetValue<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">offsetStore<\/span><span class=\"o\">.<\/span><span class=\"na\">readOffset<\/span><span class=\"o\">(<\/span><span class=\"n\">pullRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getMessageQueue<\/span><span class=\"o\">(),<\/span> <span class=\"n\">ReadOffsetType<\/span><span class=\"o\">.<\/span><span class=\"na\">READ_FROM_MEMORY<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">commitOffsetValue<\/span> <span class=\"o\">&gt;<\/span> <span class=\"n\">0<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">commitOffsetEnable<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">true<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">pullAPIWrapper<\/span><span class=\"o\">.<\/span><span class=\"na\">pullKernelImpl<\/span><span class=\"o\">(<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">pullRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getMessageQueue<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">subExpression<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">subscriptionData<\/span><span class=\"o\">.<\/span><span class=\"na\">getExpressionType<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">subscriptionData<\/span><span class=\"o\">.<\/span><span class=\"na\">getSubVersion<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">pullRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getNextOffset<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">defaultMQPushConsumer<\/span><span class=\"o\">.<\/span><span class=\"na\">getPullBatchSize<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">sysFlag<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">commitOffsetValue<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">BROKER_SUSPEND_MAX_TIME_MILLIS<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">CONSUMER_TIMEOUT_MILLIS_WHEN_SUSPEND<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">CommunicationMode<\/span><span class=\"o\">.<\/span><span class=\"na\">ASYNC<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">pullCallback<\/span><span class=\"o\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">subProperties<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6d88\u8d39\u8005\u5728\u5185\u5b58\u4e2d\u7ef4\u62a4\u4e86\u4e00\u4e2a offsetStore\uff0c\u6bcf\u6b21\u62c9\u53d6\u6d88\u606f\u65f6\u4ece offsetStore \u4e2d\u8bfb\u53d6 commitOffset \u53d1\u9001\u7ed9 Broker<\/p>\n<p>\u90a3\u4e48\u95ee\u9898\u5c31\u53d8\u6210\u4e86 offsetStore \u662f\u5982\u4f55\u7ef4\u62a4\u4f4d\u70b9\u4fe1\u606f\u7684\uff1a\u96c6\u7fa4\u6a21\u5f0f\u4e0b offsetStore \u7684\u5b9e\u73b0\u662f RemoteBrokerOffsetStore\uff0c\u6d88\u8d39\u8005\u5904\u7406\u6d88\u8d39\u7ed3\u679c\u65f6 ConsumeMessageConcurrentlyService#processConsumeResult \u4f1a\u8c03\u7528 RemoteBrokerOffsetStore#updateOffset \u65b9\u6cd5\u66f4\u65b0\u4f4d\u70b9\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kt\">long<\/span> <span class=\"n\">offset<\/span> <span class=\"o\">=<\/span> <span class=\"n\">consumeRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getProcessQueue<\/span><span class=\"o\">().<\/span><span class=\"na\">removeMessage<\/span><span class=\"o\">(<\/span><span class=\"n\">consumeRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getMsgs<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">offset<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"n\">0<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"o\">!<\/span><span class=\"n\">consumeRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getProcessQueue<\/span><span class=\"o\">().<\/span><span class=\"na\">isDropped<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">defaultMQPushConsumerImpl<\/span><span class=\"o\">.<\/span><span class=\"na\">getOffsetStore<\/span><span class=\"o\">().<\/span><span class=\"na\">updateOffset<\/span><span class=\"o\">(<\/span><span class=\"n\">consumeRequest<\/span><span class=\"o\">.<\/span><span class=\"na\">getMessageQueue<\/span><span class=\"o\">(),<\/span> <span class=\"n\">offset<\/span><span class=\"o\">,<\/span> <span class=\"kc\">true<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5206\u6790\u4e0a\u9762\u4ee3\u7801\u53ef\u4ee5\u770b\u51fa\u66f4\u65b0\u7684\u4f4d\u70b9\u901a\u8fc7\u8c03\u7528 ProcessQueue#removeMessage \u83b7\u53d6\u3002ProcessQueue \u6301\u6709\u4e00\u4e2a TreeMap \u4f5c\u4e3a\u6d88\u606f\u672c\u5730\u7f13\u5b58\uff0c\u6d88\u8d39\u8005\u6bcf\u6b21\u62c9\u53d6\u7684\u6d88\u606f\u90fd\u4f1a\u5148\u7f13\u5b58\u5728 ProcessQueue \u4e2d\uff0c\u5f53\u6d88\u8d39\u5b8c\u6210\u65f6\u518d\u4ece ProcessQueue \u4e2d\u79fb\u9664\u5bf9\u5e94\u7684\u6d88\u606f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"cm\">\/**\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\">* message list, contains message in waiting &amp; consuming list\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\">*\/<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kd\">private<\/span> <span class=\"kd\">final<\/span> <span class=\"n\">TreeMap<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">MessageExt<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">msgTreeMap<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"n\">TreeMap<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Long<\/span><span class=\"o\">,<\/span> <span class=\"n\">MessageExt<\/span><span class=\"o\">&gt;();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kd\">public<\/span> <span class=\"kt\">long<\/span> <span class=\"nf\">removeMessage<\/span><span class=\"o\">(<\/span><span class=\"kd\">final<\/span> <span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">MessageExt<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">msgs<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ \u7701\u7565\u6d88\u606f\u5220\u9664\u8fc7\u7a0b\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"k\">return<\/span> <span class=\"n\">msgTreeMap<\/span><span class=\"o\">.<\/span><span class=\"na\">isEmpty<\/span><span class=\"o\">()<\/span> <span class=\"o\">?<\/span> <span class=\"o\">(<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">queueOffsetMax<\/span> <span class=\"o\">+<\/span> <span class=\"n\">1<\/span><span class=\"o\">)<\/span> <span class=\"o\">:<\/span> <span class=\"n\">msgTreeMap<\/span><span class=\"o\">.<\/span><span class=\"na\">firstKey<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>ProcessQueue#removeMessage \u7684\u8fd4\u56de\u503c\u662f\u5f53\u524d\u7f13\u5b58\u7684\u6d88\u606f\u4e2d\u6700\u5c0f\u7684\u4f4d\u70b9\uff0c\u4e5f\u5c31\u662f\u8bf4\u6d88\u8d39\u8005\u6bcf\u6b21\u66f4\u65b0\u7684 commitOffset \u662f<strong>\u5f53\u524d\u8fd8\u672a\u6d88\u8d39\u7684\u7b2c\u4e00\u4e2a\u6d88\u606f\u7684\u4f4d\u70b9<\/strong>\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 389;\nflex-basis: 935px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag\/msgTreeMap.png\" data-size=\"748x192\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/explanation-and-optimization-of-apache-rocketmq-lag\/msgTreeMap.png\"\nwidth=\"748\"\nheight=\"192\"\nloading=\"lazy\"\nalt=\"ProcessQueue#msgTreeMap\">\n<\/a>\n<figcaption>ProcessQueue#msgTreeMap<\/figcaption>\n<\/figure><\/p>\n<p>\u5982\u4e0a\u56fe\u6240\u793a\u7684\u60c5\u51b5\u4e0b\u66f4\u65b0\u7684\u4f4d\u70b9\u5e94\u8be5\u4e3a 1 \u800c\u4e0d\u662f 6<\/p>\n<h3 id=\"pulloffset\">PullOffset<\/h3>\n<p>Broker \u5728\u56de\u590d\u6d88\u8d39\u8005\u62c9\u53d6\u6d88\u606f\u7684\u54cd\u5e94\u4e2d\u6709 nextBeginOffset \u5b57\u6bb5\uff08PullResult#nextBeginOffset\uff09\u8fd9\u4e2a\u5b57\u6bb5\u4e5f\u5c31\u662f PullOffset<\/p>\n<p>\u5206\u6790 PullMessageProcessor#processRequest \u53ef\u4ee5\u53d1\u73b0 nextBeginOffset \u5b57\u6bb5\u662f\u4ece DefaultMessageStore#getMessage \u65b9\u6cd5\u7684\u8fd4\u56de\u503c\u4e2d\u63d0\u53d6\u7684\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">getMessageResult<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">brokerController<\/span><span class=\"o\">.<\/span><span class=\"na\">getMessageStore<\/span><span class=\"o\">().<\/span><span class=\"na\">getMessage<\/span><span class=\"o\">(<\/span><span class=\"n\">requestHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">getConsumerGroup<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">requestHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">getTopic<\/span><span class=\"o\">(),<\/span> <span class=\"n\">requestHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">getQueueId<\/span><span class=\"o\">(),<\/span> <span class=\"n\">requestHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">getQueueOffset<\/span><span class=\"o\">(),<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">requestHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">getMaxMsgNums<\/span><span class=\"o\">(),<\/span> <span class=\"n\">messageFilter<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">responseHeader<\/span><span class=\"o\">.<\/span><span class=\"na\">setNextBeginOffset<\/span><span class=\"o\">(<\/span><span class=\"n\">getMessageResult<\/span><span class=\"o\">.<\/span><span class=\"na\">getNextBeginOffset<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5206\u6790 DefaultMessageStore#getMessage \u65b9\u6cd5\u53d1\u73b0 nextBeginOffset \u662f\u5f53\u524d\u62c9\u53d6\u5230\u7684\u6d88\u606f\u7684\u4e0b\u4e00\u6761\u6d88\u606f\u7684\u4f4d\u70b9\uff0c\u8fd9\u6bb5\u6e90\u7801\u592a\u590d\u6742\u5c31\u4e0d\u8d34\u51fa\u6765\u4e86<\/p>\n<h3 id=\"maxoffset\">MaxOffset<\/h3>\n<p>RocketMQ \u7684\u6d88\u606f\u662f\u5148\u50a8\u5b58\u5728 CommitLog \u4e2d\u7136\u540e\u7531 ReputMessageService \u5f02\u6b65\u6784\u5efa ConsumerQueue \u548c IndexFile\uff0c\u6700\u7ec8\u8c03\u7528 ConsumeQueue#putMessagePositionInfo \u5199\u5165\u78c1\u76d8<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">flip<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">limit<\/span><span class=\"o\">(<\/span><span class=\"n\">CQ_STORE_UNIT_SIZE<\/span><span class=\"o\">);<\/span> <span class=\"c1\">\/\/ CQ_STORE_UNIT_SIZE = 20\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">putLong<\/span><span class=\"o\">(<\/span><span class=\"n\">offset<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">putInt<\/span><span class=\"o\">(<\/span><span class=\"n\">size<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">putLong<\/span><span class=\"o\">(<\/span><span class=\"n\">tagsCode<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">MappedFile<\/span> <span class=\"n\">mappedFile<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">mappedFileQueue<\/span><span class=\"o\">.<\/span><span class=\"na\">getLastMappedFile<\/span><span class=\"o\">(<\/span><span class=\"n\">expectLogicOffset<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">mappedFile<\/span> <span class=\"o\">!=<\/span> <span class=\"kc\">null<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"n\">mappedFile<\/span><span class=\"o\">.<\/span><span class=\"na\">appendMessage<\/span><span class=\"o\">(<\/span><span class=\"k\">this<\/span><span class=\"o\">.<\/span><span class=\"na\">byteBufferIndex<\/span><span class=\"o\">.<\/span><span class=\"na\">array<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u53ef\u4ee5\u53d1\u73b0 ConsumeQueue \u7684\u6bcf\u4e2a item \u90fd\u662f\u56fa\u5b9a\u957f\u5ea6 20 \u5b57\u8282\u3002\u6240\u4ee5 MaxOffset \u7684\u8ba1\u7b97\u5c31\u5f88\u7b80\u5355\u4e86\uff0c\u7528 ConsumeQueue \u6587\u4ef6\u5927\u5c0f\u9664\u4ee5 20 \u5373\u53ef<\/p>\n<h2 id=\"\u6d88\u8d39\u5806\u79ef\u7b97\u6cd5\">\u6d88\u8d39\u5806\u79ef\u7b97\u6cd5<\/h2>\n<p>\u6709\u4e86\u4e0a\u8ff0\u4f4d\u70b9\u5c31\u53ef\u4ee5\u5f88\u5bb9\u6613\u7684\u7b97\u51fa\u4e09\u79cd\u6d88\u606f\u5806\u79ef\u91cf\uff1a<\/p>\n<div>\n$$\n\\begin{aligned}\n\u672a\u786e\u8ba4\u7684\u6d88\u606f\u91cf\uff1aConsumerLag &= &MaxOffset\\ -\\ &ConsumerOffset \\\\\n\u6b63\u5728\u6d88\u8d39\u7684\u6d88\u606f\u91cf\uff1aInflightMessageCount &= &PullOffset\\ -\\ &ConsumerOffset \\\\\n\u7b49\u5f85\u62c9\u53d6\u7684\u6d88\u606f\u91cf\uff1aAvailableMessageCount &= &MaxOffset\\ -\\ &PullOffset\n\\end{aligned}\n$$\n<\/div>\n<p>RocketMQ \u4e2d\u9ed8\u8ba4\u7684\u6d88\u8d39\u5806\u79ef\u662f\u4e0a\u5f0f\u4e2d\u7684 ConsumerLag<\/p>\n<p>\u6d88\u606f\u5ef6\u65f6\u7684\u7b97\u6cd5\u7c7b\u4f3c\uff0c\u5c06\u4e0a\u5f0f\u4e2d\u7684 offset \u6362\u6210\u5bf9\u5e94\u4f4d\u70b9\u6d88\u606f\u7684\u65f6\u95f4\u5373\u53ef<\/p>\n<h2 id=\"\u5806\u79ef\u8ba1\u7b97\u4f18\u5316\">\u5806\u79ef\u8ba1\u7b97\u4f18\u5316<\/h2>\n<h3 id=\"\u6d88\u606f\u5ef6\u65f6\u8981\u6c42\u8f83\u9ad8\u7684\u573a\u666f\">\u6d88\u606f\u5ef6\u65f6\u8981\u6c42\u8f83\u9ad8\u7684\u573a\u666f<\/h3>\n<p>\u901a\u8fc7\u5bf9 ConsumerOffset \u8ba1\u7b97\u65b9\u6cd5\u7684\u5206\u6790\u53ef\u4ee5\u770b\u51fa ConsumerOffset \u7684\u66f4\u65b0\u662f\u5b58\u5728\u5ef6\u8fdf\u7684\uff0c\u8fd9\u4e2a\u5ef6\u8fdf\u5206\u4e3a\u4e24\u4e2a\u65b9\u9762\uff1a<\/p>\n<ol>\n<li>\u62c9\u53d6\u5ef6\u65f6\uff1aConsumerOffset \u5728\u6bcf\u6b21\u62c9\u53d6\u65b0\u6d88\u606f\u65f6\u66f4\u65b0\uff0c\u800c RocketMQ \u662f\u4f7f\u7528\u957f\u8f6e\u8be2\u65b9\u5f0f\u66f4\u65b0\u6d88\u606f\uff0c\u6bcf\u6b21\u957f\u8f6e\u8be2\u7684\u9ed8\u8ba4\u8d85\u65f6\u65f6\u95f4\u662f 30s\u3002\u4e5f\u5c31\u662f\u8bf4\u5982\u679c\u6ca1\u6709\u8db3\u591f\u6570\u91cf\u7684\u6d88\u606f\u4ea7\u751f\uff0cConsumerOffset \u8981 30s \u624d\u80fd\u66f4\u65b0\u4e00\u6b21<\/li>\n<li>\u6d88\u8d39\u5ef6\u65f6\uff1a\u6d88\u8d39\u8005\u6bcf\u6b21\u63d0\u4ea4\u7684 commitOffset \u5b57\u6bb5\u662f\u5f53\u524d\u8fd8\u672a\u6d88\u8d39\u7684\u7b2c\u4e00\u4e2a\u6d88\u606f\u7684\u4f4d\u70b9\u800c\u4e0d\u662f\u6700\u540e\u4e00\u4e2a\u6d88\u8d39\u6210\u529f\u7684\u6d88\u606f\u7684\u4f4d\u70b9\u3002\u4e4b\u524d\u7684\u6d88\u606f\u672a\u80fd\u7ed3\u675f\u6d88\u8d39\u7684\u60c5\u51b5\u4e0b\u540e\u9762\u5df2\u7ecf\u6d88\u8d39\u5b8c\u7684\u6d88\u606f\u4f4d\u70b9\u5c31\u8fdf\u8fdf\u5f97\u4e0d\u5230\u66f4\u65b0<\/li>\n<\/ol>\n<p>\u6240\u4ee5\u5728\u6d88\u606f\u6570\u91cf\u5f88\u5c11\u4f46\u662f\u6d88\u8d39\u901f\u5ea6\u5f88\u6162\u7684\u573a\u666f\u4e0b\u7531 ConsumerOffset \u8ba1\u7b97\u51fa\u6765\u7684\u6d88\u606f\u7684\u5806\u79ef\u91cf\u548c\u5ef6\u8fdf\u65f6\u95f4\u7684\u6307\u6807\u5c31\u4f1a\u865a\u9ad8\uff0c\u4f46\u662f\u5b9e\u9645\u4e0a\u8fd9\u4e9b\u6d88\u606f\u5df2\u7ecf\u88ab\u6d88\u8d39\u8005\u62c9\u53d6\u5230\u5e76\u8fdb\u884c\u5904\u7406\u4e86\u3002\u8fd9\u65f6\u5c31\u5e94\u8be5\u4f7f\u7528 PullOffset \u6765\u8ba1\u7b97\u5806\u79ef\u91cf<\/p>\n<h3 id=\"\u5f00\u542f\u6d88\u606f\u8fc7\u6ee4\u65f6\u7684\u5806\u79ef\u8ba1\u7b97\">\u5f00\u542f\u6d88\u606f\u8fc7\u6ee4\u65f6\u7684\u5806\u79ef\u8ba1\u7b97<\/h3>\n<p>\u56e0\u4e3a\u5806\u79ef\u91cf\u662f\u901a\u8fc7\u4f4d\u70b9\u76f4\u63a5\u8ba1\u7b97\u5f97\u6765\u7684\uff0c\u5728\u6d88\u8d39\u8005\u5f00\u542f\u6d88\u606f\u8fc7\u6ee4\u65f6\u8fd9\u79cd\u7b97\u6cd5\u4e0d\u80fd\u6b63\u786e\u5904\u7406\u5c06\u88ab\u8fc7\u6ee4\u6389\u7684\u6d88\u606f\uff0c\u6240\u4ee5\u4f1a\u5bfc\u81f4\u5806\u79ef\u91cf\u504f\u9ad8\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e0b\u5f53\u524d topic \u4e2d\u547d\u4e2d\u8fc7\u6ee4\u89c4\u5219\u7684\u6d88\u606f\u5360\u603b\u6d88\u606f\u7684\u6bd4\u4f8b\uff0c\u7136\u540e\u7528\u8fd9\u4e2a\u6bd4\u4f8b\u4e58\u4ee5\u5806\u79ef\u91cf\u6765\u4f30\u8ba1\u4e00\u4e0b\u771f\u5b9e\u7684\u5806\u79ef\u91cf<\/p>"},{"title":"Cloudflare or Vercel \u2014\u2014 \u7f51\u7ad9\u6258\u7ba1\u4e0e\u51fd\u6570\u8ba1\u7b97\u670d\u52a1\u9009\u62e9","link":"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection","pubDate":"Sun, 22 Aug 2021 15:08:44 +0800","guid":"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection\/cover.svg\" alt=\"Featured image of post Cloudflare or Vercel \u2014\u2014 \u7f51\u7ad9\u6258\u7ba1\u4e0e\u51fd\u6570\u8ba1\u7b97\u670d\u52a1\u9009\u62e9\" \/><p>\u5728\u4e0a\u4e00\u7bc7\u6587\u7ae0 <a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/selection-and-migration-from-typecho-to-hugo\" >\u4ece Typecho \u5230 Hugo \u7684\u9009\u62e9\u4e0e\u8fc1\u79fb<\/a> \u4e2d\u63d0\u5230\u4e86 Hugo \u5f88\u9002\u5408\u4f7f\u7528 Serverless \u7684\u65b9\u5f0f\u90e8\u7f72\u5e76\u62d3\u5c55\u529f\u80fd\u3002\u672c\u6587\u5c31\u901a\u8fc7\u535a\u4e3b Cloudflare \u548c Vercel \u7684\u4f7f\u7528\u7ecf\u9a8c\u5bf9\u4ed6\u4eec\u7684\u7f51\u7ad9\u6258\u7ba1\uff08Cloudflare pages vs Vercel\uff09\u548c\u51fd\u6570\u8ba1\u7b97\uff08Cloudflare workers vs Vercel function\uff09\u670d\u52a1\u8fdb\u884c\u7b80\u5355\u7684\u4ecb\u7ecd\u548c\u5bf9\u6bd4<\/p>\n<h2 id=\"\u7f51\u7ad9\u6258\u7ba1\">\u7f51\u7ad9\u6258\u7ba1<\/h2>\n<p>Cloudflare pages \u548c Vercel \u90fd\u662f\u5341\u5206\u5f3a\u5927\u7684\u7f51\u7ad9\u6258\u7ba1\u670d\u52a1\uff0c\u63d0\u4f9b\u4ee5\u4e0b\u57fa\u672c\u7279\u6027\uff1a<\/p>\n<ul>\n<li>\u652f\u6301\u4ece Github\u3001GitLab \u7b49\u5bfc\u5165\u4ee3\u7801<\/li>\n<li>\u652f\u6301\u591a\u79cd\u9884\u8bbe\u6846\u67b6\u81ea\u52a8\u6784\u5efa\uff0c\u6ca1\u6709\u9884\u7f6e\u7684\u6846\u67b6\u53ef\u4ee5\u624b\u52a8\u63d0\u4f9b\u6784\u5efa\u547d\u4ee4\u548c\u8f93\u51fa\u8def\u5f84<\/li>\n<li>\u652f\u6301\u7ed1\u5b9a\u81ea\u5b9a\u4e49\u57df\u540d<\/li>\n<li>\u652f\u6301 CDN<\/li>\n<li>\u652f\u6301\u751f\u6210\u9884\u89c8\u7248\u672c<\/li>\n<\/ul>\n<h3 id=\"cloudflare-pages\">Cloudflare pages<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<ul>\n<li>\u96c6\u6210 Cloudflare Access\uff0c\u53ef\u4ee5\u81ea\u5b9a\u4e49\u8bbf\u95ee\u7b56\u7565<\/li>\n<li>\u96c6\u6210 Cloudflare Web Analytics\uff0c\u63d0\u4f9b\u5f00\u7bb1\u5373\u7528\u7684\u8bbf\u95ee\u7edf\u8ba1<\/li>\n<li>\u5176\u4ed6 Cloudflare \u63d0\u4f9b\u7684\u529f\u80fd\uff0c\u8be6\u60c5\u53ef\u4ee5\u53c2\u8003\u6211\u4e4b\u524d\u5199\u8fc7\u7684\u4e00\u7bc7\u6587\u7ae0\uff1a<a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\" >\u4e2a\u4eba\u7f51\u7ad9 CDN \u9009\u7528\u6307\u5317<\/a><\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p>Cloudflare pages \u63d0\u4f9b\u7684\u529f\u80fd\u7b80\u5355\u4f46\u662f\u4e00\u822c\u60c5\u51b5\u4e0b\u5df2\u7ecf\u8db3\u591f\u4e86\uff0c\u5b83\u7684\u4e3b\u8981\u4f18\u70b9\u662f\u53ef\u4ee5\u548c Cloudflare \u7684\u5176\u4ed6\u670d\u52a1\u7ed3\u5408\u4f7f\u7528\uff0c\u5982 DNS\u3001CDN\u3001WAF\u3001Apps \u7b49<\/p>\n<h3 id=\"vercel\">Vercel<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<ul>\n<li>\u4e30\u5bcc\u7684\u53ef\u914d\u7f6e\u9879\uff1a\u53ef\u4ee5\u901a\u8fc7\u914d\u7f6e\u6587\u4ef6\u4fee\u6539\u7f13\u5b58\u89c4\u5219\u3001\u54cd\u5e94\u5934\u3001url \u683c\u5f0f\u7b49\uff0c\u751a\u81f3\u914d\u7f6e\u8def\u7531\u89c4\u5219\uff08\u7c7b\u4f3c Nginx \u7684 redirect \u548c rewrite\uff09<\/li>\n<li>\u63d0\u4f9b\u591a\u79cd\u63d2\u4ef6\uff1aSlack\u3001MongoDB\u3001Logtail \u7b49<\/li>\n<li>\u96c6\u6210 Analytics\uff0c\u4f46\u662f\u4ec5\u652f\u6301 Next.js\u3001Nuxt.js\u3001Gatsby<\/li>\n<li>\u9884\u89c8\u6784\u5efa\u7ed3\u679c\uff1a\u63d0\u4f9b\u6587\u4ef6\u7ba1\u7406\u5668\u67e5\u770b\u6784\u5efa\u51fa\u7684\u6587\u4ef6<\/li>\n<li>\u63d0\u4f9b\u6613\u8bfb\u6613\u8bb0\u7684\u57df\u540d\uff1a\u683c\u5f0f\u7c7b\u4f3c\u8fd9\u6837\uff1aprojectname-git-branch-username.vercel.app\uff0c\u5728\u8c03\u8bd5\u7684\u65f6\u5019\u5f88\u65b9\u4fbf<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p>Vercel \u63d0\u4f9b\u7684\u529f\u80fd\u8981\u6bd4 Cloudflare \u4e30\u5bcc\u4e00\u4e9b\uff0c\u4f46\u662f\u5b83\u6700\u5438\u5f15\u6211\u7684\u5730\u65b9\u662f\u5b83\u5728\u56fd\u5185\u7684\u8bbf\u95ee\u901f\u5ea6\uff0c\u4e0b\u9762\u653e\u4e00\u4e0b\u6211\u7684\u535a\u5ba2\u5728 Cloudflare pages \u548c Vercel \u7684\u8bbf\u95ee\u901f\u5ea6\u5bf9\u6bd4\u56fe\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 320;\nflex-basis: 768px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection\/cf-pages-speed.png\" data-size=\"1272x397\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection\/cf-pages-speed.png\"\nwidth=\"1272\"\nheight=\"397\"\nloading=\"lazy\"\nalt=\"Cloudflare pages \u901f\u5ea6\u6d4b\u8bd5\">\n<\/a>\n<figcaption>Cloudflare pages \u901f\u5ea6\u6d4b\u8bd5<\/figcaption>\n<\/figure><br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 308;\nflex-basis: 739px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection\/vercel-speed.png\" data-size=\"1233x400\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/website-hosting-and-function-computing-service-selection\/vercel-speed.png\"\nwidth=\"1233\"\nheight=\"400\"\nloading=\"lazy\"\nalt=\"Vercel \u901f\u5ea6\u6d4b\u8bd5\">\n<\/a>\n<figcaption>Vercel \u901f\u5ea6\u6d4b\u8bd5<\/figcaption>\n<\/figure><\/p>\n<p>\u53ef\u4ee5\u770b\u51fa Vercel \u8981\u8fdc\u6bd4 Cloudflare pages \u5feb\uff0c\u751a\u81f3 Vercel \u6700\u6162\u7684\u54cd\u5e94\u65f6\u95f4\u6bd4 Cloudflare pages \u5e73\u5747\u54cd\u5e94\u65f6\u95f4\u8fd8\u77ed\u3002\u3002\u3002<\/p>\n<p>\u53e6\u5916 Vercel \u652f\u6301\u914d\u7f6e\u65e0\u9650\u91cf\u7684\u8def\u7531\u89c4\u5219\uff0c\u76f8\u6bd4\u4e4b\u4e0b Cloudflare pages \u514d\u8d39\u7248\u53ea\u652f\u6301 5 \u6761<\/p>\n<h2 id=\"\u51fd\u6570\u8ba1\u7b97\">\u51fd\u6570\u8ba1\u7b97<\/h2>\n<h3 id=\"cloudflare-workers\">Cloudflare workers<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<ul>\n<li>\u63d0\u4f9b\u5728\u7ebf\u7f16\u8f91\u5668\uff0c\u53ef\u4ee5\u65b9\u4fbf\u7684\u8c03\u8bd5\u4ee3\u7801<\/li>\n<li>\u6dfb\u52a0\u65b0\u7684 worker \u65e0\u9700\u91cd\u65b0\u90e8\u7f72\u7f51\u7ad9<\/li>\n<li>\u63d0\u4f9b\u8be6\u7ec6\u7684\u7528\u91cf\u3001\u6027\u80fd\u7edf\u8ba1<\/li>\n<li>\u652f\u6301 cron \u89e6\u53d1\u5668<\/li>\n<li>\u63d0\u4f9b\u5f00\u7bb1\u5373\u7528\u7684 KV \u5b58\u50a8<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock error\">\n<ul>\n<li>\u53ea\u652f\u6301 js<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p>\u5982\u679c\u4f60\u53ea\u4f7f\u7528 js \u7684\u8bdd Cloudflare workers \u6bd4 Vercel function \u8981\u65b9\u4fbf\u548c\u597d\u7528\u5f88\u591a<\/p>\n<h3 id=\"vercel-function\">Vercel function<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<ul>\n<li>\u652f\u6301\u591a\u79cd\u8bed\u8a00\uff1anodejs\u3001php\u3001python\u3001ruby\u3001go<\/li>\n<li>\u652f\u6301\u5305\u7ba1\u7406\u5de5\u5177\u5f15\u5165\u7b2c\u4e09\u65b9\u5e93\uff0c\u5982 go mod<\/li>\n<li>\u63d0\u4f9b\u5b9e\u65f6 log \u67e5\u770b<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock error\">\n<ul>\n<li>\u5fc5\u987b\u91cd\u65b0\u90e8\u7f72\u6574\u4e2a\u7f51\u7ad9\u624d\u80fd\u53d1\u5e03\u5bf9 function \u7684\u65b0\u589e\u6216\u4fee\u6539<\/li>\n<li>\u4e0d\u63d0\u4f9b\u5728\u7ebf\u7f16\u8f91\u5668\uff0c\u53ea\u80fd\u90e8\u7f72\u597d\u540e\u901a\u8fc7 log \u8c03\u8bd5<\/li>\n<li>\u5b58\u50a8\u529f\u80fd\u9700\u8981\u7b2c\u4e09\u65b9\u670d\u52a1\u652f\u6301<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p>Vercel function \u5728\u5bf9\u8bed\u8a00\u7684\u652f\u6301\u4e0a\u8981\u5f3a\u5927\u5f88\u591a\uff0c\u501f\u52a9\u4e8e\u5bf9\u7b2c\u4e09\u65b9\u6570\u636e\u5e93\u7684\u96c6\u6210\u4f60\u751a\u81f3\u53ef\u4ee5\u90e8\u7f72 Typecho \u6216 WordPress\u3002\u7f3a\u70b9\u662f Vercel function \u4e0e\u7f51\u7ad9\u6258\u7ba1\u529f\u80fd\u5f3a\u8026\u5408\uff0c\u5fc5\u987b\u91cd\u65b0\u90e8\u7f72\u6574\u4e2a\u7f51\u7ad9\u624d\u80fd\u53d1\u5e03\u5bf9 function \u7684\u65b0\u589e\u6216\u4fee\u6539\uff0c\u5e76\u4e14 function \u4e0d\u80fd\u4f7f\u7528\u72ec\u7acb\u7684\u57df\u540d<\/p>"},{"title":"\u4ece Typecho \u5230 Hugo \u7684\u9009\u62e9\u4e0e\u8fc1\u79fb","link":"https:\/\/blog.lv5.moe\/p\/selection-and-migration-from-typecho-to-hugo","pubDate":"Fri, 20 Aug 2021 17:03:40 +0800","guid":"https:\/\/blog.lv5.moe\/p\/selection-and-migration-from-typecho-to-hugo","description":"<p>\u672c\u7ad9\u6700\u8fd1\u4ece Typecho \u8fc1\u79fb\u5230 Hugo\uff0c\u5199\u8fd9\u7bc7\u6587\u7ae0\u5206\u6790\u4e00\u4e0b Typecho \u548c Hugo \u5404\u81ea\u7684\u4f18\u7f3a\u70b9\uff0c\u7ed9\u8bfb\u8005\u5728\u8fd9\u4e24\u8005\u4e4b\u95f4\u9009\u62e9\u63d0\u4f9b\u53c2\u8003\u3002\u6700\u540e\u8bb0\u5f55\u4e00\u4e0b\u6211\u7684\u8fc1\u79fb\u8fc7\u7a0b\u4f9b\u540e\u6765\u8005\u53c2\u8003\uff1aTypecho \u5728\u670d\u52a1\u5668\u5df2\u7ecf\u6302\u6389\u7684\u60c5\u51b5\u4e0b\u5982\u4f55\u6062\u590d\u6240\u6709\u7684\u6587\u7ae0\uff0c\u7136\u540e\u4fdd\u5b58\u4e3a Hugo \u7684\u6587\u4ef6\u7ec4\u7ec7\u65b9\u5f0f<\/p>\n<h2 id=\"hugo-\u4e0e-typecho-\u6bd4\u8f83\">Hugo \u4e0e Typecho \u6bd4\u8f83<\/h2>\n<h3 id=\"hugo\">Hugo<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<p>\u4f18\u70b9\uff1a<\/p>\n<ul>\n<li>\u9759\u6001\u535a\u5ba2\u751f\u6210\u5668\uff1a\u751f\u6210\u9759\u6001 HTML\uff0c\u6027\u80fd\u597d\uff0c\u90e8\u7f72\u65b9\u4fbf\uff0c\u5f88\u591a serverless \u670d\u52a1\u5546\u652f\u6301\u4e00\u952e\u90e8\u7f72 Hugo<\/li>\n<li>\u4f7f\u7528\u6a21\u677f\u8bed\u6cd5\u548c shortcodes \u5b9e\u73b0\u7075\u6d3b\u7684\u5185\u5bb9\u7ec4\u88c5<\/li>\n<li>\u4f7f\u7528 Hugo pipeline \u81ea\u52a8\u5316\u5904\u7406\u8d44\u6e90\u6587\u4ef6\uff1aSCSS \u751f\u6210 CSS\u3001minify js\u3001\u538b\u7f29\u6216\u751f\u6210\u4e0d\u540c\u5c3a\u5bf8\u7684\u56fe\u7247<\/li>\n<li>\u63d0\u4f9b\u4e00\u7cfb\u5217\u73b0\u4ee3\u5316\u529f\u80fd\uff1a \u8f93\u51fa JSON \u6216 AMP \u9875\u9762\u3001\u62d3\u5c55\u7684 Markdown \u8bed\u6cd5\u3001\u63a5\u5165 Google Analytics\u3001i18n \u7b49<\/li>\n<li>\u6587\u6863\u5b8c\u5584\uff0c\u793e\u533a\u6d3b\u8dc3<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock error\">\n<p>\u7f3a\u70b9\uff1a<\/p>\n<ul>\n<li>DIY \u95e8\u69db\u6bd4\u8f83\u9ad8\uff0c\u5b66\u4e60\u66f2\u7ebf\u6bd4\u8f83\u9661\u5ced<\/li>\n<li>\u4e3b\u9898\u6570\u91cf\u6bd4\u8f83\u5c11\uff0c\u5927\u591a\u90fd\u662f\u82f1\u6587\u4e3b\u9898\uff0c\u5e76\u4e14\u4e3b\u9898\u63d0\u4f9b\u7684\u529f\u80fd\u6216\u53ef\u4ee5\u81ea\u5b9a\u4e49\u7684\u9009\u9879\u6bd4\u8f83\u5c11<\/li>\n<li>\u5f88\u96be\u5b9e\u73b0\u4e00\u4e9b\u62d3\u5c55\u529f\u80fd\uff0c\u6bd4\u5982\u535a\u4e3b\u5f00\u53d1\u7684\u51e0\u6b3e Typecho \u63d2\u4ef6\u5c31\u5f88\u96be\u5728 Hugo \u4e0a\u5b9e\u73b0\u7c7b\u4f3c\u7684\u529f\u80fd<\/li>\n<li>\u6ca1\u6709\u8bc4\u8bba\u7cfb\u7edf\u3002\u867d\u7136\u652f\u6301\u96c6\u6210 disqus\uff0c\u4f46\u662f\u7531\u4e8e\u4f17\u6240\u5468\u77e5\u7684\u539f\u56e0 disqus \u5728\u4e2d\u56fd\u4e0d\u80fd\u8bbf\u95ee<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<h3 id=\"typecho\">Typecho<\/h3>\n<p><\/p>\n<div class=\"tip inlineBlock success\">\n<p>\u4f18\u70b9\uff1a<\/p>\n<ul>\n<li>\u4e3b\u9898\u4e30\u5bcc\uff1a\u6709\u5f88\u591a\u6f02\u4eae\u7684\u4e2d\u6587\u4e3b\u9898\uff0c\u5e76\u4e14\u63d0\u4f9b\u5f88\u591a DIY \u9009\u9879<\/li>\n<li>\u63d2\u4ef6\u4e30\u5bcc\uff1a\u6709\u7b2c\u4e09\u65b9\u63d2\u4ef6\u5e02\u573a\uff0c \u63d0\u4f9b\u4e30\u5bcc\u7684\u62d3\u5c55\u529f\u80fd<\/li>\n<li>\u65b0\u624b\u53cb\u597d\uff1a\u4e2d\u6587\u793e\u533a\u4e2d\u6559\u7a0b\u5f88\u591a\uff0c\u51fa\u95ee\u9898\u4e5f\u6709\u5f88\u591a\u5927\u4f6c\u53ef\u4ee5\u8bf7\u6559<\/li>\n<li>\u63d0\u4f9b\u7ba1\u7406\u540e\u53f0\uff0c\u652f\u6301\u6ce8\u518c\u7528\u6237\u3001\u53d1\u5e03\u6587\u7ae0\u7b49<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock error\">\n<p>\u7f3a\u70b9\uff1a<\/p>\n<ul>\n<li>\u65e9\u5df2\u505c\u6b62\u529f\u80fd\u66f4\u65b0\uff0c\u53ea\u8fdb\u884c\u7ef4\u62a4<\/li>\n<li>Typecho \u662f\u57fa\u4e8e php \u7684\u52a8\u6001\u535a\u5ba2\u7cfb\u7edf\uff0c\u6027\u80fd\u4e0d\u5982\u9759\u6001\u535a\u5ba2<\/li>\n<li>\u90e8\u7f72\u6bd4\u8f83\u9ebb\u70e6\uff0c\u9700\u8981\u90e8\u7f72 web server\u3001php\u3001database\uff0c\u5f88\u96be\u4f7f\u7528 serverless \u7684\u65b9\u5f0f\u90e8\u7f72<\/li>\n<\/ul>\n<\/div>\n<p><\/p>\n<h3 id=\"typecho-\u4e0e-hugo-\u9009\u62e9\u6211\u4e4b\u89c1\">Typecho \u4e0e Hugo \u9009\u62e9\u6211\u4e4b\u89c1<\/h3>\n<p>\u535a\u4e3b\u4ece Typecho \u8fc1\u79fb\u5230 Hugo \u7684\u4e3b\u8981\u52a8\u529b\u662f\u4e4b\u524d\u767d\u5ad6\u7684\u670d\u52a1\u5668\u5230\u671f\u4e86\u3002\u3002\u3002\u76f8\u6bd4\u4e8e Typecho \u7528\u7684 php \u6211\u5bf9 Hugo \u7684 go \u8bed\u8a00\u66f4\u719f\u6089\u4e00\u4e9b\uff0c\u800c\u4e14 Hugo \u5b8c\u5584\u7684\u6587\u6863\u66f4\u662f\u6781\u5927\u7a0b\u5ea6\u4e0a\u65b9\u4fbf\u4e8e\u6211\u7684 DIY \u5927\u4e1a\u3002<\/p>\n<p>Hugo \u4f5c\u4e3a\u4e00\u4e2a\u9759\u6001\u535a\u5ba2\u7cfb\u7edf\u6700\u4e3b\u8981\u7684\u7f3a\u70b9( <del>\u4f18\u70b9<\/del> )\u662f\u6ca1\u6709( <del>\u4e0d\u9700\u8981<\/del> )\u540e\u7aef\uff0c\u4f46\u662f\u8fd9\u53ef\u4ee5\u901a\u8fc7\u5404\u5bb6\u4e91\u5382\u5546\u7684\u51fd\u6570\u8ba1\u7b97\u6765\u5f25\u8865\u3002\u51fd\u6570\u8ba1\u7b97+\u4e91\u4e0a\u6258\u7ba1\u7684\u6570\u636e\u5e93\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4e00\u5207\u4f60\u60f3\u5b9e\u73b0\u7684\u63d2\u4ef6\u529f\u80fd\uff0c\u672c\u6587\u8bc4\u8bba\u7cfb\u7edf\u7684 api \u5c31\u4f7f\u7528\u4e86 Vercel \u63d0\u4f9b\u7684 function \u670d\u52a1\u3002\u5f53\u7136\uff0c\u4ee5\u4e0a\u6784\u60f3\u9700\u8981\u4f60\u5177\u5907\u4e00\u5b9a\u7684\u7f16\u7a0b\u77e5\u8bc6\uff0c\u8fd9\u6050\u6015\u4e0d\u662f\u7b80\u5355\u7684\u7167\u732b\u753b\u864e\u53ef\u4ee5\u5feb\u901f\u638c\u63e1\u7684\u3002<\/p>\n<p>\u535a\u4e3b\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e9b Hugo \u548c Typecho \u7684\u9009\u62e9\u5efa\u8bae\u4f9b\u8bfb\u8005\u53c2\u8003\uff1a<\/p>\n<ul>\n<li>\u5982\u679c\u4f60\u5bf9\u9759\u6001\u535a\u5ba2\u751f\u6210\u5668\u6709\u5f3a\u9700\u6c42\uff0c\u90a3\u6211\u4f30\u8ba1\u4f60\u4e5f\u4e0d\u4f1a\u8bfb\u5230\u8fd9 qwq<br \/>\n<\/br><\/li>\n<li>\u5982\u679c\u4f60\u6709\u7f16\u7a0b\u80cc\u666f\uff0c\u719f\u6089\u4e91\u670d\u52a1\uff0c\u5d07\u5c1a GitOps\uff0c\u90a3\u4e48\u9009\u62e9 Hugo<\/li>\n<li>\u5982\u679c\u4f60\u60f3 DIY \u5e76\u4e14\u539f\u610f\u6298\u817e\uff0c\u53cd\u590d\u8c03\u8bd5\u5404\u79cd\u9519\u8bef\u5e76\u4e50\u6b64\u4e0d\u75b2\uff0c\u90a3\u4e48\u9009\u62e9 Hugo<\/li>\n<li>\u5982\u679c\u4f60\u8ffd\u6c42\u6781\u503c\u7684\u8bbf\u95ee\u901f\u5ea6\/\u6ca1\u6709\u4e5f\u4e0d\u60f3\u6709\u81ea\u5df1\u7684\u670d\u52a1\u5668\/\u6709\u591a\u8bed\u8a00\u7b49\u4f9d\u8d56\u4e8e Hugo \u7279\u6027\u7684\u9700\u6c42\uff0c\u90a3\u4e48\u9009\u62e9 Hugo<br \/>\n<\/br><\/li>\n<li>\u5982\u679c\u4f60\u662f\u5c0f\u767d\u6216\u6709\u4e00\u5b9a\u7684 DIY \u9700\u6c42\u4f46\u662f\u5e76\u4e0d\u60f3\u6298\u817e\uff0c\u90a3\u4e48\u9009\u62e9 Typecho<\/li>\n<li>\u5982\u679c\u4f60\u60f3\u6709\u4e00\u4e2a\u5728\u7ebf\u5199\u4f5c\/\u65b9\u4fbf\u7684\u66f4\u65b0\u6587\u7ae0\u7684\u5e73\u53f0\uff0c\u90a3\u4e48\u9009\u62e9 Typecho<\/li>\n<li>\u5982\u679c\u4f60\u60f3\u4e00\u52b3\u6c38\u9038\u7684\u90e8\u7f72\/\u6709\u4e00\u4e2a\u7528\u6237&amp;\u8bc4\u8bba\u7cfb\u7edf\/\u6709\u6536\u8d39\u7b49\u7279\u6b8a\u7684\u63d2\u4ef6\u9700\u6c42\uff0c\u90a3\u4e48\u9009\u62e9 Typecho<\/li>\n<\/ul>\n<h2 id=\"\u4ece-typecho-\u5230-hugo\">\u4ece Typecho \u5230 Hugo<\/h2>\n<p>\u7f51\u4e0a\u6709\u4e00\u4e9b Typecho \u8fc1\u79fb\u63d2\u4ef6\u53ef\u4ee5\u5c06 Typecho \u7684\u6587\u7ae0\u548c\u9644\u4ef6\u5bfc\u51fa\u4e3a Hugo \u7684\u6587\u4ef6\u7ec4\u7ec7\u65b9\u5f0f\uff0c\u4f46\u662f\u6211\u7684\u670d\u52a1\u5668\u5df2\u7ecf\u6302\u6389\u4e86\u6ca1\u6cd5\u7528\u8fd9\u4e9b\u63d2\u4ef6\uff0c\u53ea\u80fd\u8fdb\u884c\u624b\u52a8\u8fc1\u79fb<\/p>\n<h3 id=\"\u8fc1\u79fb\u6587\u7ae0\">\u8fc1\u79fb\u6587\u7ae0<\/h3>\n<p>\u76f4\u63a5\u4ece\u6570\u636e\u5e93\u7684 <code>typecho_contents<\/code> \u8868\u4e2d\u63d0\u53d6\u6587\u7ae0\u6807\u9898\u548c\u5185\u5bb9\u7b49\u4fe1\u606f\uff0c\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e2a\u793a\u4f8b sql \u8bed\u53e5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-sql\" data-lang=\"sql\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">SELECT<\/span><span class=\"w\"> <\/span><span class=\"o\">*<\/span><span class=\"w\"> <\/span><span class=\"k\">FROM<\/span><span class=\"w\"> <\/span><span class=\"n\">blog<\/span><span class=\"p\">.<\/span><span class=\"n\">typecho_contents<\/span><span class=\"w\"> <\/span><span class=\"k\">where<\/span><span class=\"w\"> <\/span><span class=\"k\">type<\/span><span class=\"o\">=<\/span><span class=\"s2\">&#34;post&#34;<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u5199\u4e00\u4e2a\u811a\u672c\u6765\u5c06\u6240\u6709\u6587\u7ae0\u8f93\u51fa\u5230\u4ee5\u5404\u81ea\u6587\u7ae0\u540d\u547d\u540d\u7684\u6587\u4ef6\u4e2d<\/p>\n<h3 id=\"\u8fc1\u79fb\u56fe\u7247\u7b49\u9644\u4ef6\">\u8fc1\u79fb\u56fe\u7247\u7b49\u9644\u4ef6<\/h3>\n<p>\u6211\u7684\u535a\u5ba2\u4f7f\u7528\u4e86\u53c8\u62cd\u4e91\u7684\u5bf9\u8c61\u50a8\u5b58\u6765\u4fdd\u5b58\u56fe\u7247\u7b49\u9644\u4ef6\uff0c\u6240\u4ee5\u53ea\u9700\u8981\u628a\u4ed6\u4eec\u4e0b\u8f7d\u4e0b\u6765\u5c31\u597d\u3002\u6bd4\u8f83\u9ebb\u70e6\u7684\u662f\u4fee\u6539\u8fd9\u4e9b\u56fe\u7247\u5728\u6587\u7ae0\u4e2d\u7684\u94fe\u63a5\uff0c\u5982\u679c\u8981\u624b\u52a8\u4e00\u4e2a\u4e2a\u6539\u592a\u8017\u65f6\u95f4\u3002\u63a8\u8350\u5728 Hugo \u7684 static \u6587\u4ef6\u5939\u4e2d\u65b0\u5efa\u4e00\u4e2a\u548c\u4e4b\u524d\u7684\u56fe\u7247\u76ee\u5f55\u7ed3\u6784\u4e00\u6837\u7684\u6587\u4ef6\u5939\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u4fee\u6539\u94fe\u63a5\u4e86<\/p>\n<h3 id=\"hugo-\u76ee\u5f55\u7ed3\u6784\">Hugo \u76ee\u5f55\u7ed3\u6784<\/h3>\n<p>\u6211\u7684 Hugo \u6587\u4ef6\u5939\u7ed3\u6784\u5982\u56fe\u6240\u793a\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">tree content\/post\n<\/span><\/span><span class=\"line\"><span class=\"cl\">.\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u251c\u2500\u2500 solutions-to-certificate-invalidation-after-android-7\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u2502\u00a0\u00a0 \u251c\u2500\u2500 cal-hash.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u2502\u00a0\u00a0 \u251c\u2500\u2500 index.md\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u2502\u00a0\u00a0 \u251c\u2500\u2500 install-ca-certificate.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u2502\u00a0\u00a0 \u2514\u2500\u2500 ssl-handshake-failed.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u2514\u2500\u2500 web-font-optimization\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> \u251c\u2500\u2500 blog_title.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> \u251c\u2500\u2500 font_type.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> \u251c\u2500\u2500 index.md\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> \u251c\u2500\u2500 sign.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> \u2514\u2500\u2500 woff2_support.jpg\n<\/span><\/span><\/code><\/pre><\/div><p>\u6bcf\u4e2a\u6587\u7ae0\u65b0\u5efa\u4e00\u4e2a\u4ee5\u6587\u7ae0\u7684 slug \u547d\u540d\u7684\u6587\u4ef6\u5939\uff0c\u5c06\u6587\u7ae0\u7528\u5230\u7684\u56fe\u7247\u5305\u62ec\u6587\u7ae0\u5934\u56fe\u90fd\u653e\u5728\u8fd9\u4e2a\u6587\u4ef6\u5939\u4e0b\u3002\u5728\u4e3b\u9898\u4e2d\u53ef\u4ee5\u7528 <code>.Context.Resources.GetMatch<\/code> \u5f97\u5230\u56fe\u7247\u7684 resource \u5bf9\u8c61\uff0c\u8fd9\u6837\u65e2\u4fbf\u4e8e\u7ba1\u7406\uff0c\u4e5f\u80fd\u5c06\u56fe\u50cf\u4ea4\u7ed9 Hugo \u8fdb\u884c\u5904\u7406\u3002\u6bd4\u5982 ssl-handshake-failed.jpg \u8fd9\u5f20\u56fe\u7247\u5c31\u4f1a\u751f\u6210\u4ee5\u4e0b\u51e0\u4e2a\u7248\u672c\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">ls resources\/_gen\/images\/post\/solutions-to-certificate-invalidation-after-android-7\n<\/span><\/span><span class=\"line\"><span class=\"cl\">...\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ssl-handshake-failed.2a74b1a908dba312f29b1f3f15095116_hu9d2358b8f64836a3db846b7dbcdad0ac_92801_250x150_fill_q75_box_smart1.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ssl-handshake-failed_hu9d2358b8f64836a3db846b7dbcdad0ac_92801_1024x0_resize_q75_box.jpg\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ssl-handshake-failed_hu9d2358b8f64836a3db846b7dbcdad0ac_92801_480x0_resize_q75_box.jpg\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"\u53cd\u7801\u548c\u8865\u7801\u7684\u6570\u5b66\u539f\u7406","link":"https:\/\/blog.lv5.moe\/p\/the-mathematical-principle-of-ones-complement-and-twos-complement","pubDate":"Mon, 16 Aug 2021 19:18:16 +0800","guid":"https:\/\/blog.lv5.moe\/p\/the-mathematical-principle-of-ones-complement-and-twos-complement","description":"<img src=\"https:\/\/blog.lv5.moe\/img\/58255799_p0.jpg\" alt=\"Featured image of post \u53cd\u7801\u548c\u8865\u7801\u7684\u6570\u5b66\u539f\u7406\" \/><p>\u672c\u6587\u4ecb\u7ecd\u4e86\u4f7f\u7528\u53cd\u7801\u548c\u8865\u7801\u7684\u52a0\u6cd5\u4ee3\u66ff\u51cf\u6cd5\uff0c\u5e76\u5206\u6790\u4e86\u8fd9\u6837\u505a\u80cc\u540e\u7684\u6570\u5b66\u539f\u7406<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u672c\u6587\u516c\u5f0f\u8f83\u591a\uff0c\u5efa\u8bae\u4f7f\u7528\u7535\u8111\u6216\u5e73\u677f\u9605\u8bfb\n<\/div>\n<p><\/p>\n<h2 id=\"\u53cd\u7801\u4e0e\u8865\u7801\u7684\u8868\u793a\">\u53cd\u7801\u4e0e\u8865\u7801\u7684\u8868\u793a<\/h2>\n<ol>\n<li>\n<p>\u539f\u7801\u7684\u8868\u793a\u65b9\u6cd5\uff1a<br \/>\n\u7b26\u53f7\u4f4d\u52a0\u4e0a\u5b83\u7684\u7edd\u5bf9\u503c\uff0c\u5373\u7528\u7b2c\u4e00\u4f4d\u8868\u793a\u7b26\u53f7\uff0c\u5176\u4f59\u4f4d\u8868\u793a\u503c\u3002\u5982\u679c\u662f $8$ \u4f4d\u4e8c\u8fdb\u5236\uff1a<\/p>\n<div>\n$$\n\\begin{array}{l}\n[+1] = [00000001]_\u539f \\\\\n[-1] = [10000001]_\u539f\n\\end{array}\n$$\n<\/div>\n<\/li>\n<li>\n<p>\u53cd\u7801\u7684\u8868\u793a\u65b9\u6cd5\uff1a<br \/>\n\u6b63\u6570\u7684\u53cd\u7801\u662f\u5176\u672c\u8eab<br \/>\n\u8d1f\u6570\u7684\u53cd\u7801\u662f\u5728\u5176\u539f\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u7b26\u53f7\u4f4d\u4e0d\u53d8\uff0c\u5176\u4f59\u5404\u4e2a\u4f4d\u53d6\u53cd.<\/p>\n<div>\n$$\n\\begin{array}{l}\n[+1] = [00000001]_\u539f = [00000001]_\u53cd \\\\\n[-1] = [10000001]_\u539f = [11111110]_\u53cd\n\\end{array}\n$$\n<\/div>\n<\/li>\n<li>\n<p>\u8865\u7801\u7684\u8868\u793a\u65b9\u6cd5\uff1a<br \/>\n\u6b63\u6570\u7684\u8865\u7801\u5c31\u662f\u5176\u672c\u8eab<br \/>\n\u8d1f\u6570\u7684\u8865\u7801\u662f\u5728\u5176\u539f\u7801\u7684\u57fa\u7840\u4e0a\uff0c\u7b26\u53f7\u4f4d\u4e0d\u53d8\uff0c\u5176\u4f59\u5404\u4f4d\u53d6\u53cd\uff0c\u6700\u540e $+1$. (\u5373\u5728\u53cd\u7801\u7684\u57fa\u7840\u4e0a $+1$)<\/p>\n<div>\n$$\n\\begin{array}{l}\n[+1] = [00000001]_\u539f = [00000001]_\u53cd = [00000001]_\u8865 \\\\\n[-1] = [10000001]_\u539f = [11111110]_\u53cd = [11111111]_\u8865\n\\end{array}\n$$\n<\/div>\n<\/li>\n<\/ol>\n<h2 id=\"\u53cd\u7801\u548c\u8865\u7801\u7684\u610f\u4e49\">\u53cd\u7801\u548c\u8865\u7801\u7684\u610f\u4e49<\/h2>\n<p>\u6211\u5728\u4e0a\u4e00\u7bc7\u6587\u7ae0<a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/talk-about-negative-number-conversion-and-absolute-value-operation-through-math-abs\" >\u7531 Math.abs \u8c08\u8d1f\u6570\u8f6c\u6362\u4e0e\u7edd\u5bf9\u503c\u8fd0\u7b97<\/a>\u4e2d\u6709\u63d0\u5230\u8865\u7801\u7684\u4f5c\u7528\uff1a<\/p>\n<blockquote>\n<p>\u5bf9\u4e8e\u8ba1\u7b97\u673a\u6765\u8bf4\u52a0\u51cf\u662f\u6700\u57fa\u7840\u7684\u8fd0\u7b97\u8981\u8bbe\u8ba1\u7684\u5c3d\u91cf\u7b80\u5355\uff0c\u800c\u51cf\u6cd5\u76f8\u5f53\u4e8e\u52a0\u4e0a\u4e00\u4e2a\u8d1f\u6570\uff0c\u6240\u4ee5\u5b8c\u5168\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u6765\u4ee3\u66ff\u51cf\u6cd5\u3002\u4f46\u662f\u8fd9\u5c31\u51fa\u73b0\u4e86\u5982\u4f55\u5904\u7406\u7b26\u53f7\u4f4d\u7684\u95ee\u9898\uff0cshort\u3001int\u3001long \u7684\u4f4d\u6570\u4e0d\u540c\u7b26\u53f7\u4f4d\u81ea\u7136\u4e5f\u4e0d\u540c\uff0c\u4e3a\u4e86\u907f\u514d\u8fd0\u7b97\u524d\u8fd8\u9700\u8981\u5224\u65ad\u7b26\u53f7\u4f4d\u7684\u4f4d\u7f6e\uff0c\u524d\u4eba\u63d0\u51fa\u4e86\u5c06\u7b26\u53f7\u4f4d\u4e5f\u5f15\u5165\u8ba1\u7b97\u7684\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u8865\u7801\u3002<\/p>\n<\/blockquote>\n<p>\u786e\u5207\u7684\u8bf4\uff0c\u7528\u53cd\u7801\u5c31\u53ef\u4ee5\u5b9e\u73b0\u52a0\u6cd5\u6765\u4ee3\u66ff\u51cf\u6cd5\uff0c \u5176\u4e2d\u552f\u4e00\u7279\u6b8a\u7684\u662f $0$\uff1a<\/p>\n<div>\n$$\n\\begin{split}\n&1 - 1 \\\\\n&= 1 + (-1) \\\\\n&= [0000 0001]_\u539f + [1000 0001]_\u539f \\\\\n&= [0000 0001]_\u53cd + [1111 1110]_\u53cd \\\\\n&= [1111 1111]_\u53cd \\\\\n&= [1000 0000]_\u539f \\\\\n&-0\n\\end{split}\n$$\n<\/div>\n<p>\u8fd9\u6837\u7b97\u51fa\u6765\u7684\u7ed3\u679c\u662f $-0$\uff0c\u7136\u800c\u5bf9\u4e8e $0$ \u6765\u8bf4\u6b63\u8d1f\u53f7\u662f\u65e0\u610f\u4e49\u7684\uff0c\u5e76\u4e14 $-0$ \u7684\u8868\u793a\u65b9\u6cd5\u4f7f\u5f97 $0$ \u51fa\u73b0\u4e86\u4e24\u4e2a\u7f16\u7801<br \/>\n\u6b64\u5916\uff0c\u7528\u53cd\u7801\u52a0\u6cd5\u4ee3\u66ff\u51cf\u6cd5\u9700\u8981\u5faa\u73af\u8fdb\u4f4d\uff1a<\/p>\n<div>\n$$\n\\begin{split}\n&4 - 2 \\\\\n&= 4 + (-2) \\\\\n&= [0000 0100]_\u539f + [1000 0010]_\u539f \\\\\n&= [0000 0100]_\u53cd + [1111 1101]_\u53cd \\\\\n\\end{split}\n$$\n<\/div>\n<p>\u8fd9\u91cc\u5982\u679c\u6309\u6b63\u5e38\u7684\u4e8c\u8fdb\u5236\u52a0\u6cd5\u8ba1\u7b97 $0000 0100 + 1111 1101$ \u4f1a\u5f97\u51fa $0000 0001$ \u5373 $1$ \u7684\u9519\u8bef\u7ed3\u679c\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u5c06\u6ea2\u51fa\u7684\u8fdb\u4f4d\u518d\u52a0\u5230\u6700\u4f4e\u4f4d\u4e0a\uff0c\u5f97\u5230\u6b63\u786e\u7ed3\u679c $0000 0010$ \u5373 $2$<\/p>\n<p>\u4e3a\u4e86\u89e3\u51b3 $0$ \u6709\u4e24\u4e2a\u7f16\u7801\u5e76\u4e14\u9700\u8981\u5faa\u73af\u8fdb\u4f4d\u7684\u95ee\u9898\uff0c\u51fa\u73b0\u4e86\u8865\u7801:<br \/>\n\u8865\u7801\u7528 $[00000000]_\u8865$ \u8868\u793a 0\uff0c\u800c $[10000000]_\u8865$ \u8868\u793a $-128$\uff0c\u8fd9\u6837\u5c31\u6d88\u9664\u4e86\u6b67\u4e49<\/p>\n<div>\n$$\n\\begin{split}\n&1 - 1 \\\\\n&= 1 + (-1) \\\\\n&= [0000 0001]_\u539f + [1000 0001]_\u539f \\\\\n&= [0000 0001]_\u8865 + [1111 1111]_\u8865 \\\\\n&= [0000 0000]_\u8865 \\\\\n&= [0000 0000]_\u539f \\\\\n&= 0\n\\end{split}\n$$\n<\/div>\n<p>\u7efc\u4e0a\u6240\u8ff0\u53cd\u7801\u548c\u8865\u7801\u7684\u610f\u4e49\u5728\u4e8e\u53ef\u4ee5\u8ba9\u7b26\u53f7\u4f4d\u53c2\u4e0e\u8ba1\u7b97\uff0c\u4ece\u800c\u53ef\u4ee5\u7528\u52a0\u6cd5\u4ee3\u66ff\u51cf\u6cd5\u7684\u6570\u5b66\u539f\u7406\u3002\u63a5\u4e0b\u6765\u6211\u4eec\u63a5\u4e0b\u6765\u6211\u4eec\u63a2\u8ba8\u4e00\u4e0b\u53ef\u4ee5\u8fd9\u6837\u505a\u80cc\u540e\u7684\u6570\u5b66\u539f\u7406<\/p>\n<h2 id=\"\u7528\u53cd\u7801\u548c\u8865\u7801\u7684\u52a0\u6cd5\u4ee3\u66ff\u51cf\u6cd5\u7684\u6570\u5b66\u539f\u7406\">\u7528\u53cd\u7801\u548c\u8865\u7801\u7684\u52a0\u6cd5\u4ee3\u66ff\u51cf\u6cd5\u7684\u6570\u5b66\u539f\u7406<\/h2>\n<p>\u9996\u5148\u6211\u4eec\u6765\u4ecb\u7ecd\u4e24\u4e2a\u6570\u5b66\u6982\u5ff5\uff1a<\/p>\n<h3 id=\"\u53d6\u6a21\u8fd0\u7b97\">\u53d6\u6a21\u8fd0\u7b97<\/h3>\n<p>\u53d6\u6a21\u8fd0\u7b97\u516c\u5f0f\uff1a<\/p>\n<p>$$ x \\bmod y = x - y \\lfloor x \/ y \\rfloor $$<\/p>\n<p>\u4ee5 $ -3 \\bmod 2 $ \u4e3a\u4f8b:<\/p>\n<div>\n$$\n\\begin{split}\n&-3 \\bmod 2 \\\\\n&= -3 - 2 \\times \\lfloor -3\/2 \\rfloor \\\\\n&= -3 - 2 \\times \\lfloor -1.5 \\rfloor \\\\\n&= -3 - 2 \\times (-2) \\\\\n&= -3 + 4 \\\\\n&= 1\n\\end{split}\n$$\n<\/div>\n<p>\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e2a\u53d6\u6a21\u7684\u7b97\u6cd5\u5b9e\u73b0\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">mod<\/span><span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">a<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">b<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"o\">(<\/span><span class=\"n\">a<\/span> <span class=\"o\">%<\/span> <span class=\"n\">b<\/span> <span class=\"o\">+<\/span> <span class=\"n\">b<\/span><span class=\"o\">)<\/span> <span class=\"o\">%<\/span> <span class=\"n\">b<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u540c\u4f59\">\u540c\u4f59<\/h3>\n<p>\u4e24\u4e2a\u6574\u6570 a\uff0cb\uff0c\u82e5\u5b83\u4eec\u9664\u4ee5\u6574\u6570 m \u6240\u5f97\u7684\u4f59\u6570\u76f8\u7b49\uff0c\u5219\u79f0 a\uff0cb \u5bf9\u4e8e\u6a21 m \u540c\u4f59<\/p>\n<p>\u8bb0\u4f5c $ a \\equiv b \\pmod m $\uff0c\u8bfb\u4f5c a \u4e0e b \u5173\u4e8e\u6a21 m \u540c\u4f59<\/p>\n<div>\n$$\n\\begin{split}\n\\left. \\begin{gathered}\n4 \\bmod 12 &= 4 \\\\\n16 \\bmod 12 &= 4\n\\end{gathered} \\right\\}\n\\implies\n4 \\equiv 16 \\pmod{12}\n\\end{split}\n$$\n<\/div>\n<p>\u540c\u4f59\u5177\u6709\u7684\u6027\u8d28\uff1a<\/p>\n<ol>\n<li>\u81ea\u53cd\u6027\uff0c\u5bf9\u79f0\u6027\uff0c\u4f20\u9012\u6027<\/li>\n<\/ol>\n<div>\n$$\n\\begin{align}\n&a \\equiv a \\pmod m \\\\\n&a \\equiv b \\pmod m \\iff b \\equiv a \\pmod m \\\\\n&a \\equiv b \\pmod m \\text{ \u4e14 } b \\equiv c \\pmod m \\implies a \\equiv c \\pmod m \\\\\n\\end{align}\n$$\n<\/div>\n<ol start=\"2\">\n<li>\u7ebf\u6027\u8fd0\u7b97<\/li>\n<\/ol>\n<div>\n$$\n\\begin{split}\na \\equiv b \\pmod m \\text{ \u4e14 } c \\equiv d \\pmod m \\implies\n\\left\\{ \\begin{gathered}\na \\pm c &\\equiv b \\pm d \\pmod m \\\\\na \\times c &\\equiv b \\times d \\pmod m\n\\end{gathered} \\right.\n\\end{split}\n$$\n<\/div>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u540c\u4f59\u7684\u9664\u6cd5\u7684\u6027\u8d28\u4e0e\u52a0\u51cf\u4e58\u6cd5\u4e0d\u540c\uff1a<br \/>\n$$ a \\equiv b \\pmod m \\quad \u4e14 \\quad c \\equiv d \\pmod m \\implies a \\equiv b\\left(\\bmod \\frac{m}{\\operatorname{gcd}(c, m)}\\right) $$\n<\/div>\n<p><\/p>\n<ol start=\"3\">\n<li>\u5e42\u8fd0\u7b97<br \/>\n$$ a \\equiv b \\pmod m \\implies a^{n} \\equiv b^{n} \\pmod m $$<\/li>\n<\/ol>\n<h3 id=\"\u8bc1\u660e\">\u8bc1\u660e<\/h3>\n<p>\u6211\u4eec\u8fd8\u662f\u4ee5 $ 4 - 2 $ \u4e3a\u4f8b\uff0c\u6839\u636e\u540c\u4f59\u6570\u7684\u6027\u8d28\u6211\u4eec\u5f88\u5bb9\u6613\u5f97\u51fa\u8fd9\u6837\u7684\u7ed3\u8bba\uff1a<\/p>\n<div>\n$$\n\\begin{split}\n\\left. \\begin{gathered}\n4 &\\equiv 4 \\pmod{7} \\\\\n-2 &\\equiv 5 \\pmod{7} \\\\\n\\end{gathered} \\right\\}\n\\implies 4 - 2 \\equiv 4 + 5 \\pmod{7}\n\\end{split}\n$$\n<\/div>\n<p>\u4e5f\u5c31\u662f\u8bf4\u6211\u4eec\u8ba1\u7b97 $ 4 - 2 $ \u5c31\u76f8\u5f53\u4e8e\u8ba1\u7b97 $ (4 + 5) \\bmod 7 $<br \/>\n\u5982\u679c\u6211\u4eec\u5c06 $-2$ \u548c $5$ \u6362\u6210\u4e8c\u8fdb\u5236\u4f1a\u53d1\u73b0 $-2$ \u7684\u53cd\u7801\u7684\u6570\u503c\u90e8\u5206\u6b63\u597d\u7b49\u4e8e $5$\uff0c\u4e5f\u5c31\u662f\u8bf4\u8865\u7801\u7684\u8ba1\u7b97\u5b9e\u9645\u4e0a\u662f\u6c42\u5176\u6a21\u6570\u4e3a\u5f53\u524d\u6570\u5236\u7684\u4e0a\u9650\uff08\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\u4e3a $7$\uff09\u7684\u540c\u4f59\u6570<\/p>\n<div>\n$$\n\\begin{split}\n-2 &= [1010]_\u539f = [1101]_\u53cd \\\\\n5 &= [0101]_\u539f = [0101]_\u53cd\n\\end{split}\n$$\n<\/div>\n<p>\u8fd9\u6837\u5faa\u73af\u8fdb\u4f4d\u5c31\u76f8\u5f53\u4e8e\u6ea2\u51fa\u7684\u6570\u5bf9\u5f53\u524d\u6570\u5236\u7684\u4e0a\u9650\uff08\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\u4e3a $7$\uff09\u53d6\u6a21\u540e\u518d\u4e0e\u539f\u7ed3\u679c\u76f8\u52a0<\/p>\n<p>$$ (4 + 5) \\bmod 7 = 8 \\bmod 7 + 1 = 2 $$<\/p>\n<p>\u8fd9\u91cc\u7684 $8$ \u76f8\u5f53\u4e8e\u8fdb\u4f4d<\/p>\n<p>\u800c\u8865\u7801\u7684\u8ba1\u7b97\u76f8\u6bd4\u4e8e\u53cd\u7801\u53ea\u4e0d\u8fc7\u662f\u589e\u52a0\u4e86\u6a21\u7684\u503c\uff1a\u8fd9\u65f6\u6211\u4eec\u8ba1\u7b97 $ 4 - 2 $ \u5c31\u76f8\u5f53\u4e8e\u8ba1\u7b97 $ (4 + 6) \\bmod 8 $<\/p>\n<p>$$ (4 + 6) \\bmod 8 = 8 \\bmod 8 + 2 = 2 $$<\/p>\n<p>\u56e0\u4e3a\u8fdb\u4f4d $ 8 \\bmod 8 = 0 $ \u6240\u4ee5\u4e0d\u9700\u8981\u5faa\u73af\u8fdb\u4f4d<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock \">\n\u53e6\u4e00\u79cd\u6570\u5b66\u63a8\u5bfc\u53ef\u4ee5\u770b\u8fd9\u7bc7\u6587\u7ae0\uff1a<a class=\"link\" href=\"https:\/\/note.sbwcwso.com\/pages\/1dd33b\" target=\"_blank\" rel=\"noopener\"\n>\u53cd\u7801\u4e0e\u8865\u7801\u52a0\u6cd5\u7684\u7406\u89e3<\/a>\n<\/div>\n<p><\/p>"},{"title":"\u7531 Math.abs \u8c08\u8d1f\u6570\u8f6c\u6362\u4e0e\u7edd\u5bf9\u503c\u8fd0\u7b97","link":"https:\/\/blog.lv5.moe\/p\/talk-about-negative-number-conversion-and-absolute-value-operation-through-math-abs","pubDate":"Mon, 16 Aug 2021 15:53:15 +0800","guid":"https:\/\/blog.lv5.moe\/p\/talk-about-negative-number-conversion-and-absolute-value-operation-through-math-abs","description":"<p>\u672c\u6587\u901a\u8fc7\u5206\u6790\u4e00\u4e2a Java \u4e2d <code>Math.abs()<\/code> \u8bef\u7528\u5f15\u53d1\u7684 bug \u4ecb\u7ecd\u4e86\u8ba1\u7b97\u673a\u4e2d\u6570\u7684\u50a8\u5b58\u3001\u8d1f\u6570\u8f6c\u6362\u4e0e\u7edd\u5bf9\u503c\u8fd0\u7b97<\/p>\n<h2 id=\"\u80cc\u666f\">\u80cc\u666f<\/h2>\n<p>\u6700\u8fd1\u9047\u5230\u4e86\u4e00\u4e2a\u5947\u5999\u6df1\u523b\u7684 bug\uff1a\u6211\u4eec\u7684\u7cfb\u7edf\u4e2d\u4f7f\u7528\u4e86\u4e00\u4e2a int \u578b\u7684\u53d8\u91cf\u6765\u8ba1\u6570\uff0c\u8fd9\u4e2a\u8ba1\u6570\u5668\u53d8\u91cf\u7684\u7edd\u5bf9\u503c\u53d6\u6a21\u4f5c\u4e3a\u67d0\u4e2a list \u7684 index\uff0c\u4f46\u662f\u4eca\u5929\u51fa\u73b0\u4e86\u5f02\u5e38 IndexOutOfBoundsException<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u6ee1\u8db3\u67d0\u4e9b\u6761\u4ef6\u8ba1\u6570\u5668\u81ea\u589e\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"kt\">int<\/span> <span class=\"n\">count<\/span> <span class=\"o\">=<\/span> <span class=\"n\">0<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">count<\/span><span class=\"o\">++<\/span><span class=\"err\">\uff1b<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"kt\">int<\/span> <span class=\"n\">index<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Math<\/span><span class=\"o\">.<\/span><span class=\"na\">abs<\/span><span class=\"o\">(<\/span><span class=\"n\">count<\/span><span class=\"o\">)<\/span> <span class=\"o\">%<\/span> <span class=\"n\">list<\/span><span class=\"o\">.<\/span><span class=\"na\">size<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ java.lang.IndexOutOfBoundsException: Index -2147483648 out of bounds for length 1\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"n\">list<\/span><span class=\"o\">.<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"n\">index<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"mathabs-\u9047\u4e0a-integermin_value\">Math.abs \u9047\u4e0a Integer.MIN_VALUE<\/h2>\n<p>\u6211\u4eec\u77e5\u9053 int \u662f\u7528 32 \u4f4d\u4e8c\u8fdb\u5236\u50a8\u5b58\u7684\uff0c\u5176\u4e2d\u6700\u9ad8\u4f4d\u662f\u7b26\u53f7\u4f4d\u3002\u4e0a\u8ff0\u4ee3\u7801\u4e0d\u65ad\u81ea\u589e count \u53d8\u91cf\u6700\u7ec8\u4f1a\u4f7f\u5176\u8d85\u8fc7\u4e0a\u9650\u4ece\u800c\u53cd\u8f6c\u6210\u8d1f\u6570\uff08<code>Integer.MAX_VALUE + 1 == Integer.MIN_VALUE<\/code> \u4f1a\u8fd4\u56de true\uff09 \u6211\u4eec\u9884\u6599\u5230\u4e86\u8fd9\u79cd\u60c5\u51b5\u53d1\u751f\u6240\u4ee5\u4f7f\u7528 <code>Math.abs(count)<\/code> \u6765\u786e\u4fdd\u53d6\u6a21\u7684\u7ed3\u679c\u4e3a\u6b63\u6570\uff0c\u4f46\u662f\u7ed3\u679c\u4e8b\u4e0e\u613f\u8fdd<\/p>\n<p>\u6211\u4eec\u67e5\u770b\u62a5\u9519\u4fe1\u606f\u53d1\u73b0 -2147483648 \u6b63\u597d\u662f Integer.MIN_VALUE\uff0c\u6240\u4ee5\u6211\u4eec\u5148\u8bd5\u4e00\u4e0b <code>Math.abs(Integer.MIN_VALUE)<\/code> \u7ed3\u679c\u5c45\u7136\u662f -2147483648\uff0c\u8fd9\u663e\u7136\u4e0d\u7b26\u5408\u6211\u4eec\u7684\u9884\u671f\uff0c\u8ba9\u6211\u4eec\u5148\u6765\u770b\u4e00\u4e0b <code>Math.abs()<\/code> \u7684\u5b9e\u73b0\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"> <span class=\"cm\">\/**\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * Returns the absolute value of an {@code int} value.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * If the argument is not negative, the argument is returned.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * If the argument is negative, the negation of the argument is returned.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * &lt;p&gt;Note that if the argument is equal to the value of\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * {@link Integer#MIN_VALUE}, the most negative representable\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * {@code int} value, the result is that same value, which is\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * negative.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @param a the argument whose absolute value is to be determined\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> * @return the absolute value of the argument.\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"cm\"> *\/<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nd\">@HotSpotIntrinsicCandidate<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kd\">public<\/span> <span class=\"kd\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">abs<\/span><span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">a<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"o\">(<\/span><span class=\"n\">a<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">0<\/span><span class=\"o\">)<\/span> <span class=\"o\">?<\/span> <span class=\"o\">-<\/span><span class=\"n\">a<\/span> <span class=\"o\">:<\/span> <span class=\"n\">a<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6ce8\u91ca\u4e2d\u8bf4\u660e\u4e86\u5982\u679c a \u662f Integer.MIN_VALUE \u90a3\u4e48\u8fd4\u56de\u503c\u4e5f\u662f\u8d1f\u6570\u3002\u5230\u8fd9\u91cc\u5c31\u7834\u6848\u4e86\uff0c\u53ea\u8981\u628a <code>Math.abs(count) % list.size()<\/code> \u6539\u4e3a <code>(count % list.size() + list.size()) % list.size()<\/code> \u5373\u53ef\uff0c\u4e0b\u9762\u5206\u6790\u4e00\u4e0b\u4e3a\u4ec0\u4e48\u4f1a\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u6539\u4e3a <code>(count % list.size() + list.size()) % list.size()<\/code> \u800c\u4e0d\u662f <code>Math.abs(count % list.size())<\/code> \u662f\u56e0\u4e3a\u524d\u8005\u7b26\u5408\u53d6\u4f59\u7684\u6570\u5b66\u5b9a\u4e49<br \/>\n\u8be6\u60c5\u53ef\u4ee5\u770b\u6211\u7684\u53e6\u4e00\u7bc7\u6587\u7ae0 <a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/the-mathematical-principle-of-ones-complement-and-twos-complement\" >\u53cd\u7801\u548c\u8865\u7801\u7684\u6570\u5b66\u539f\u7406<\/a>\n<\/div>\n<p><\/p>\n<h2 id=\"\u8fd0\u7b97\u7b26---\u7684\u539f\u7406\">\u8fd0\u7b97\u7b26 - \u7684\u539f\u7406<\/h2>\n<p>\u5206\u6790 <code>Math.abs()<\/code> \u7684\u4ee3\u7801\u53ef\u4ee5\u53d1\u73b0\u95ee\u9898\u51fa\u5728\u8fd0\u7b97\u7b26 <code>-<\/code> \u4e0a\uff0c\u4e5f\u5c31\u662f\u8bf4 <code>-Integer.MIN_VALUE == Integer.MIN_VALUE<\/code>\uff0c\u663e\u7136\u51fa\u73b0\u8fd9\u79cd\u60c5\u51b5\u8bf4\u660e\u8fd0\u7b97\u7b26 <code>-<\/code> \u7684\u4f5c\u7528\u4e0d\u53ef\u80fd\u662f\u7b80\u5355\u7684\u5c06\u7b26\u53f7\u4f4d\u53d6\u53cd\u3002<\/p>\n<p>\u8981\u7ee7\u7eed\u5206\u6790\u5c31\u8981\u5148\u4e86\u89e3\u6570\u5728\u8ba1\u7b97\u673a\u4e2d\u7684\u50a8\u5b58\u539f\u7406\uff1a\u5bf9\u4e8e\u8ba1\u7b97\u673a\u6765\u8bf4\u52a0\u51cf\u662f\u6700\u57fa\u7840\u7684\u8fd0\u7b97\u8981\u8bbe\u8ba1\u7684\u5c3d\u91cf\u7b80\u5355\uff0c\u800c\u51cf\u6cd5\u76f8\u5f53\u4e8e\u52a0\u4e0a\u4e00\u4e2a\u8d1f\u6570\uff0c\u6240\u4ee5\u5b8c\u5168\u53ef\u4ee5\u4f7f\u7528\u52a0\u6cd5\u6765\u4ee3\u66ff\u51cf\u6cd5\u3002\u4f46\u662f\u8fd9\u5c31\u51fa\u73b0\u4e86\u5982\u4f55\u5904\u7406\u7b26\u53f7\u4f4d\u7684\u95ee\u9898\uff0cshort\u3001int\u3001long \u7684\u4f4d\u6570\u4e0d\u540c\u7b26\u53f7\u4f4d\u81ea\u7136\u4e5f\u4e0d\u540c\uff0c\u4e3a\u4e86\u907f\u514d\u8fd0\u7b97\u524d\u8fd8\u9700\u8981\u5224\u65ad\u7b26\u53f7\u4f4d\u7684\u4f4d\u7f6e\uff0c\u524d\u4eba\u63d0\u51fa\u4e86\u5c06\u7b26\u53f7\u4f4d\u4e5f\u5f15\u5165\u8ba1\u7b97\u7684\u673a\u5236\uff0c\u4e5f\u5c31\u662f\u8865\u7801\u3002<\/p>\n<p>\u8865\u7801\u7684\u8868\u793a\u65b9\u6cd5\u662f:<\/p>\n<ul>\n<li>\u6b63\u6570\u7684\u8865\u7801\u5c31\u662f\u5176\u672c\u8eab<\/li>\n<li>\u8d1f\u6570\u7684\u8865\u7801\u662f\u5728\u5176\u539f\u7801\u7684\u57fa\u7840\u4e0a\u7b26\u53f7\u4f4d\u4e0d\u53d8\uff0c\u5176\u4f59\u5404\u4f4d\u53d6\u53cd\uff0c\u6700\u540e +1<\/li>\n<\/ul>\n<p>\u8ba1\u7b97\u673a\u4e2d\u8ba1\u7b97 1 - 1 \u7684\u539f\u7406\uff1a<\/p>\n<div>\n$$\n\\begin{split}\n&1 - 1 \\\\\n&= 1 + (-1) \\\\\n&= [0000 0001]_\u539f + [1000 0001]_\u539f \\\\\n&= [0000 0001]_\u8865 + [1111 1111]_\u8865 \\\\\n&= [0000 0000]_\u8865 \\\\\n&= [0000 0000]_\u539f \\\\\n&= 0\n\\end{split}\n$$\n<\/div>\n<p>\u6240\u4ee5\u8fd0\u7b97\u7b26 <code>-<\/code> \u7684\u539f\u7406\u662f\u8fdb\u884c\u6c42\u5176\u8865\u7801\u7684\u8fd0\u7b97\uff0c\u5373\u6309\u4f4d\u53d6\u53cd\u7136\u540e +1\uff0c\u4e8e\u662f\u6211\u4eec\u6765\u5206\u6790 <code>-Integer.MIN_VALUE<\/code> \u7684\u8fd0\u7b97\u8fc7\u7a0b<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"><span class=\"o\">-<\/span><span class=\"n\">Integer<\/span><span class=\"o\">.<\/span><span class=\"na\">MIN_VALUE<\/span> <span class=\"o\">=<\/span> <span class=\"o\">~<\/span><span class=\"n\">Integer<\/span><span class=\"o\">.<\/span><span class=\"na\">MIN_VALUE<\/span> <span class=\"o\">+<\/span> <span class=\"n\">1<\/span> <span class=\"o\">=<\/span> <span class=\"o\">~<\/span><span class=\"n\">0x80000000<\/span> <span class=\"o\">+<\/span> <span class=\"n\">1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">0x7fffffff<\/span> <span class=\"o\">+<\/span> <span class=\"n\">1<\/span> <span class=\"o\">=<\/span> <span class=\"n\">0x80000000<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u53d1\u73b0\u5728 <code>0x7fffffff + 1<\/code> \u7684\u8fc7\u7a0b\u4e2d\u53d1\u751f\u4e86\u6ea2\u51fa\uff0c\u6240\u4ee5\u6700\u540e\u7684\u7ed3\u679c\u8fd8\u662f 0x80000000 \u4e5f\u5c31\u662f Integer.MIN_VALUE<\/p>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u901a\u8fc7\u4ee5\u4e0a\u5206\u6790\u6211\u4eec\u53ef\u4ee5\u77e5\u9053\uff0c\u4f7f\u7528 <code>Math.abs()<\/code> \u5bf9 Short.MIN_VALUE\u3001Integer.MIN_VALUE\u3001Long.MIN_VALUE \u53d6\u7edd\u5bf9\u503c\u90fd\u5f97\u4e0d\u5230\u6b63\u786e\u7684\u7ed3\u679c\u3002\u90a3\u6709\u6ca1\u6709\u65b9\u6cd5\u53ef\u4ee5\u5f97\u5230\u6b63\u786e\u7684\u7ed3\u679c\u5462\uff1f\u7b54\u6848\u662f Integer.MIN_VALUE \u7684\u7edd\u5bf9\u503c\u5728 Integer \u7684\u8303\u56f4\u5185\u65e0\u6cd5\u8868\u793a\uff0c\u56e0\u4e3a 0 \u7684\u5b58\u5728 Integer. MAX_VALUE \u6bd4 Integer.MIN_VALUE \u7684\u7edd\u5bf9\u503c\u5c0f 1\u3002\u5982\u679c\u786e\u5b9e\u8981\u5f97\u5230 Integer.MIN_VALUE \u7684\u7edd\u5bf9\u503c\u53ef\u4ee5\u5148\u8f6c\u6362\u4e3a Long\uff1a<code>Math.abs(Long.valueOf(Integer.MIN_VALUE))<\/code><\/p>"},{"title":"\u5bf9\u4e00\u4e2a\u5e76\u53d1\u95ee\u9898\u7684\u601d\u8003","link":"https:\/\/blog.lv5.moe\/p\/thinking-about-a-concurrency-problem","pubDate":"Wed, 13 Nov 2019 22:29:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/thinking-about-a-concurrency-problem","description":"<p>\u9047\u5230\u4e86\u4e00\u4e2a\u5e76\u53d1\u95ee\u9898\uff0c\u5c06\u5bf9\u9501\u7684\u8bbe\u8ba1\u7684\u601d\u8003\u8bb0\u5f55\u4e00\u4e0b\uff1a<\/p>\n<p>\u8fd9\u4e2a\u95ee\u9898\u7684\u903b\u8f91\u662f\uff1a\u9700\u8981\u6839\u636e id \u83b7\u53d6\u6570\u636e\u5e93\u4e2d\u6307\u5b9a\u7684\u4e00\u884c\u6570\u636e\uff0c\u5982\u679c\u8fd9\u884c\u6570\u636e\u7684\u67d0\u4e2a\u5b57\u6bb5\u4e3a null \u5219\u8bf7\u6c42\u8fdc\u7a0b\u63a5\u53e3\u6765\u83b7\u53d6\u6570\u636e\uff08\u6bcf\u6b21\u8bf7\u6c42\u63a5\u53e3\u8fd9\u4e2a\u6570\u636e\u90fd\u4f1a\u66f4\u65b0\uff09\uff0c\u7136\u540e\u5c06\u83b7\u53d6\u7684\u503c\u5199\u5165\u5230\u6570\u636e\u5e93\u4e2d<\/p>\n<p>\u5173\u952e\u7684\u95ee\u9898\u5728\u4e8e\u5982\u4f55\u80fd\u5728\u9ad8\u5e76\u53d1\u7684\u60c5\u51b5\u4e0b\u4fdd\u8bc1\u6700\u540e\u6570\u636e\u5e93\u4e2d\u5b58\u7684\u662f\u6700\u65b0\u83b7\u53d6\u7684\u6570\u636e\uff0c\u663e\u7136\u6211\u4eec\u53ef\u4ee5\u7528 synchronized \u9501\u6765\u89e3\u51b3\u3002\u4f46\u662f\u8fd9\u4e2a\u65b9\u6cd5\u4e2d\u6709\u4e09\u4e2a\u8017\u65f6\u64cd\u4f5c\uff0c\u5982\u679c\u8fd9\u6837\u7c97\u66b4\u7684\u89e3\u51b3\u80af\u5b9a\u662f\u884c\u4e0d\u901a\u7684\uff0c\u6240\u4ee5\u8981\u8003\u8651\u5982\u4f55\u51cf\u5c0f\u9501\u7684\u7c92\u5ea6\u3002<\/p>\n<p>\u6211\u7684\u89e3\u51b3\u65b9\u6848\u662f\u4f7f\u7528\u4e00\u4e2a HashMap \u6765\u4e3a\u6bcf\u4e2a id \u751f\u6210\u4e00\u628a\u9501\uff08\u91c7\u7528 lazyload \u7b56\u7565\uff0c\u5c1d\u8bd5\u83b7\u53d6\u9501\u65f6\u518d\u751f\u6210\uff09\u8fd9\u6837\u53ea\u6709\u5bf9\u591a\u4e2a id \u7684\u8fde\u7eed\u8bf7\u6c42\u624d\u4f1a\u963b\u585e<\/p>\n<p>\u4f46\u662f\u8fd9\u6837\u968f\u4e4b\u800c\u6765\u7684\u662f\u53e6\u4e00\u4e2a\u65b0\u95ee\u9898\uff1aHashMap \u4f1a\u65e0\u9650\u5730\u65b0\u589e\u9501\uff0c\u5982\u679c id \u7684\u6570\u91cf\u8fc7\u591a\u90a3\u5c82\u4e0d\u662f\u5f97\u88ab\u6324\u7206\u5185\u5b58\uff0c\u6240\u4ee5\u6211\u8fd9\u91cc\u65b0\u5f00\u4e00\u4e2a\u7ebf\u7a0b\u53bb\u5220\u9664\u6682\u65f6\u4e0d\u7528\u7684\u9501<\/p>\n<p>\u8fd9\u4e2a\u5220\u9664\u903b\u8f91\u53c8\u6709\u4e24\u4e2a\u95ee\u9898\uff1a<\/p>\n<ol>\n<li>\u5982\u4f55\u4fdd\u8bc1\u524d\u4e00\u4e2a\u7ebf\u7a0b\u6267\u884c\u5b8c\u4e0b\u4e00\u4e2a\u7ebf\u7a0b\u6709\u673a\u4f1a\u83b7\u53d6\u9501<\/li>\n<li>\u5982\u4f55\u4fdd\u8bc1\u5220\u9664\u7684\u9501\u771f\u7684\u662f\u6ca1\u4eba\u7528\u7684<\/li>\n<\/ol>\n<p>\u7b2c\u4e00\u4e2a\u95ee\u9898\u901a\u8fc7\u628a\u5220\u9664\u7ebf\u7a0b\u7761\u7720 3s \u6765\u89e3\u51b3\uff0c\u7b2c\u4e8c\u4e2a\u95ee\u9898\u6211\u901a\u8fc7\u91cd\u65b0\u8bfb\u53d6 lock \u6765\u89e3\u51b3\uff0c\u5e76\u4e14\u83b7\u53d6 map \u7684\u9501\u6765\u4fdd\u8bc1\u6ca1\u6709\u5176\u4ed6\u7ebf\u7a0b\u80fd\u5728\u68c0\u6d4b\u8fc7\u7a0b\u4e2d\u80fd\u8bbf\u95ee map \u4ee5\u53ca\u83b7\u5f97\u65b0 lock\u3001\u68c0\u6d4b\u662f\u5426\u5360\u7528\u3001\u4ece map \u4e2d\u5220\u9664\u8fd9\u4e09\u4e2a\u64cd\u4f5c\u7684\u539f\u5b50\u6027<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-java\" data-lang=\"java\"><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ private static final ReentrantLock mapLock = new ReentrantLock();\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"c1\">\/\/ private static final HashMap&lt;Long, ReentrantLock&gt; map = new HashMap&lt;&gt;();\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kd\">private<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">checkAndUpdate<\/span><span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">id<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">mapLock<\/span><span class=\"o\">.<\/span><span class=\"na\">lock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ReentrantLock<\/span> <span class=\"n\">lock<\/span> <span class=\"o\">=<\/span> <span class=\"n\">map<\/span><span class=\"o\">.<\/span><span class=\"na\">getOrDefault<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"o\">,<\/span> <span class=\"k\">new<\/span> <span class=\"n\">ReentrantLock<\/span><span class=\"o\">());<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">mapLock<\/span><span class=\"o\">.<\/span><span class=\"na\">unlock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">lock<\/span><span class=\"o\">.<\/span><span class=\"na\">lock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ check and update\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">lock<\/span><span class=\"o\">.<\/span><span class=\"na\">unlock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">new<\/span> <span class=\"n\">Thread<\/span><span class=\"o\">(()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">try<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">Thread<\/span><span class=\"o\">.<\/span><span class=\"na\">sleep<\/span><span class=\"o\">(<\/span><span class=\"n\">3000<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">mapLock<\/span><span class=\"o\">.<\/span><span class=\"na\">lock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">ReentrantLock<\/span> <span class=\"n\">newLock<\/span> <span class=\"o\">=<\/span> <span class=\"n\">map<\/span><span class=\"o\">.<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">newLock<\/span> <span class=\"o\">!=<\/span> <span class=\"kc\">null<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"o\">!<\/span><span class=\"n\">newLock<\/span><span class=\"o\">.<\/span><span class=\"na\">isLocked<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">map<\/span><span class=\"o\">.<\/span><span class=\"na\">remove<\/span><span class=\"o\">(<\/span><span class=\"n\">id<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">mapLock<\/span><span class=\"o\">.<\/span><span class=\"na\">unlock<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span> <span class=\"k\">catch<\/span> <span class=\"o\">(<\/span><span class=\"n\">InterruptedException<\/span> <span class=\"n\">e<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}).<\/span><span class=\"na\">start<\/span><span class=\"o\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u4f18\u5316\u7684\u70b9\uff1a<\/p>\n<ol>\n<li>\u91c7\u7528\u7ebf\u7a0b\u6c60\u6765\u6267\u884c\u5220\u9664\u903b\u8f91<\/li>\n<li>\u83b7\u53d6\u5230 lock \u540e\u5148\u5224\u65ad\u662f\u5426\u5df2\u7ecf\u52a0\u9501\uff0c\u5982\u679c\u5df2\u7ecf\u52a0\u4e86\u5219\u76f4\u63a5\u653e\u5f03\u66f4\u65b0\uff0c\u5426\u5219\u5c1d\u8bd5\u52a0\u9501<br \/>\n\u56e0\u4e3a\u5982\u679c\u7ade\u4e89\u9501\u5931\u8d25\u90a3\u4e48\u8bf4\u660e\u5df2\u7ecf\u6709\u7ebf\u7a0b\u5728\u5c1d\u8bd5\u66f4\u65b0\u8fd9\u4e2a\u4e3a null \u7684\u503c\u4e86\uff0c\u5982\u679c\u66f4\u65b0\u6210\u529f\u90a3\u8fd9\u4e2a\u503c\u4e0d\u518d\u4e3a null \u5c31\u4e0d\u7528\u518d\u6b21\u66f4\u65b0\u4e86\uff0c\u5982\u679c\u66f4\u65b0\u5931\u8d25\u90a3\u663e\u7136\u8981\u63d0\u793a\u7528\u6237\u5931\u8d25\uff0c\u7528\u6237\u4f1a\u518d\u6b21\u5c1d\u8bd5\u3002\u6240\u4ee5\u8fd8\u662f\u76f4\u63a5\u653e\u5f03\u7684\u597d<\/li>\n<\/ol>"},{"title":"Nginx SSL\/TLS \u914d\u7f6e\u4f18\u5316","link":"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization","pubDate":"Sun, 06 Oct 2019 18:38:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/ssl-logo.jpg\" alt=\"Featured image of post Nginx SSL\/TLS \u914d\u7f6e\u4f18\u5316\" \/><p>\u672c\u6587\u63cf\u8ff0\u7684\u4f18\u5316\u6280\u5de7\u57fa\u4e8e Nginx 1.17\u3001OpenSSL 1.1.1d\u3001TLS1.2 \u548c TLS1.3<\/p>\n<h2 id=\"tls12-session-\u590d\u7528\">TLS1.2 Session \u590d\u7528<\/h2>\n<p>session \u590d\u7528\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u6211\u9009\u62e9\u7684\u662f Session Identifier\uff0c\u4e0b\u9762\u8ba8\u8bba\u4e0b\u8fd9\u4e24\u79cd\u65b9\u5f0f\u7684\u673a\u5236\uff1a<\/p>\n<h3 id=\"session-identifier\">Session Identifier<\/h3>\n<p>\u5ba2\u6237\u7aef\u4fdd\u5b58 session ID\uff0c\u5728\u53d1\u8d77 Client Hello \u65f6\u5c06\u4e0a\u6b21\u4f7f\u7528\u7684 session ID \u53d1\u9001\u7ed9\u670d\u52a1\u7aef\uff0c\u670d\u52a1\u7aef\u6839\u636e\u6536\u5230\u7684 session ID \u627e\u5230\u4fdd\u5b58\u597d\u7684\u5bf9\u79f0\u5bc6\u94a5\u3002<\/p>\n<p>nginx \u4e2d\u7684\u914d\u7f6e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u6307\u5b9a\u7f13\u5b58\u5927\u5c0f\u4e3a 30m\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">ssl_session_cache<\/span> <span class=\"s\">shared:SSL:30m<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u6307\u5b9a\u7f13\u5b58\u65f6\u95f4\u4e3a 1 \u5929\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">ssl_session_timeout<\/span> <span class=\"s\">1d<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u8fd9\u91cc\u9700\u8981\u5173\u95ed\u9ed8\u8ba4\u5f00\u542f\u7684 ssl_session_tickets\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">ssl_session_tickets<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u91cc\u6709\u4e24\u4e2a\u95ee\u9898\uff1a<\/p>\n<ul>\n<li>\u670d\u52a1\u5668\u7f13\u5b58 session \u4fe1\u606f\u4f1a\u5bf9\u670d\u52a1\u5668\u6027\u80fd\u9020\u6210\u5f71\u54cd<\/li>\n<li>\u4e0d\u652f\u6301\u5206\u5e03\u5f0f\u90e8\u7f72\uff0c\u7f13\u5b58\u53ea\u5728\u5355\u673a\u4e0a\u4fdd\u5b58\u3002\u8fd9\u4e2a\u95ee\u9898\u53ef\u4ee5\u4f7f\u7528 OpenResty \u914d\u5408 Redis \u89e3\u51b3\uff1a\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_session_fetch_by_lua_file<\/span> <span class=\"s\">lua\/session_fetch.lua<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_session_store_by_lua_file<\/span> <span class=\"s\">lua\/session_store.lua<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_session_timeout<\/span> <span class=\"s\">1d<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_session_tickets<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<\/ul>\n<h3 id=\"session-ticket\">Session Ticket<\/h3>\n<p>\u670d\u52a1\u5668\u5c06 session \u4fe1\u606f\u52a0\u5bc6\u540e\u4fdd\u5b58\u5728 session ticket \u4e2d\u4ea4\u7531\u5ba2\u6237\u7aef\u4fdd\u5b58\uff0c\u5ba2\u6237\u7aef\u4f1a\u5728 client hello \u7684\u62d3\u5c55\u4e2d\u52a0\u4e0a session ticket\uff0c\u670d\u52a1\u5668\u89e3\u5bc6\u540e\u5c31\u53ef\u4ee5\u6062\u590d\u4f1a\u8bdd\u4fe1\u606f<\/p>\n<p>\u8fd9\u4e2a\u65b9\u5f0f\u5b89\u5168\u6027\u8981\u5dee\u4e00\u4e9b\uff1a<\/p>\n<ul>\n<li>Nginx \u548c Apache \u90fd\u53ea\u5728\u91cd\u542f\u540e\u624d\u4f1a\u66f4\u6539\u52a0\u5bc6\u4f7f\u7528\u7684\u5bc6\u94a5<\/li>\n<li>session ticket \u4e0d\u5177\u6709\u524d\u5411\u4fdd\u5bc6\u6027\uff0c\u5e76\u4e14\u4e00\u65e6 session ticket \u88ab\u89e3\u5bc6\u4f1a\u4f7f TLS \u7684\u524d\u5411\u4fdd\u5bc6\u6027\u673a\u5236\u5b8c\u5168\u5931\u6548\u3002\u76f8\u5173\u8ba8\u8bba\u53ef\u4ee5\u53c2\u8003<a class=\"link\" href=\"https:\/\/www.imperialviolet.org\/2013\/06\/27\/botchingpfs.html\" target=\"_blank\" rel=\"noopener\"\n>\u8fd9\u7bc7\u6587\u7ae0<\/a>\uff1a<\/li>\n<\/ul>\n<h2 id=\"tls13-early-data0-rtt\">TLS1.3 Early data\uff080-RTT\uff09<\/h2>\n<p>TLS 1.3 \u4e2d\u629b\u5f03\u4e86\u4e4b\u524d\u7684\u4e24\u79cd session \u590d\u7528\u65b9\u5f0f\uff0c\u8f6c\u800c\u91c7\u7528 PSK \u590d\u7528\uff1a<\/p>\n<p><strong>\u548c TLS1.2 \u7684\u5bf9\u6bd4\uff1a<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>TLS1.2 \u9996\u6b21\u8fde\u63a5<\/th>\n<th>TLS1.2 \u4f1a\u8bdd\u590d\u7528<\/th>\n<th>TLS1.3 \u9996\u6b21\u8fde\u63a5<\/th>\n<th>TLS1.3 \u4f1a\u8bdd\u590d\u7528<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DNS \u89e3\u6790<\/td>\n<td>1-RTT<\/td>\n<td>0-RTT<\/td>\n<td>1-RTT<\/td>\n<td>0-RTT<\/td>\n<\/tr>\n<tr>\n<td>TCP \u63e1\u624b<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<\/tr>\n<tr>\n<td>TLS \u63e1\u624b<\/td>\n<td>2-RTT<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<td>0-RTT<\/td>\n<\/tr>\n<tr>\n<td>HTTP Request<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<td>1-RTT<\/td>\n<\/tr>\n<tr>\n<td>\u603b\u8ba1<\/td>\n<td>5-RTT<\/td>\n<td>3-RTT<\/td>\n<td>4-RTT<\/td>\n<td>2-RTT<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u5b9e\u73b0\u673a\u5236\">\u5b9e\u73b0\u673a\u5236<\/h3>\n<p>\u7b2c\u4e00\u6b21\u8fde\u63a5\u5efa\u7acb\u540e\u670d\u52a1\u5668\u5411\u5ba2\u6237\u7aef\u53d1\u9001 New Session Ticket \u5305\uff0c\u5176\u4e2d\u7684 early_data \u62d3\u5c55\u6307\u5b9a\u4e86\u662f\u5426\u80fd\u4f7f\u7528 Early data\uff080-RTT \u8fde\u63a5\uff09\u53ca\u5176\u53c2\u6570<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 206;\nflex-basis: 494px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/new-session-ticket.png\" data-size=\"616x299\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/new-session-ticket.png\"\nwidth=\"616\"\nheight=\"299\"\nloading=\"lazy\"\nalt=\"New Session Ticket\">\n<\/a>\n<figcaption>New Session Ticket<\/figcaption>\n<\/figure><\/p>\n<p>\u7b2c\u4e8c\u6b21\u8fde\u63a5\u5ba2\u6237\u7aef\u53d1\u9001 Client Hello \u65f6\u540c\u65f6\u53d1\u9001 Early data<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 532;\nflex-basis: 1277px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/early-data.png\" data-size=\"740x139\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/early-data.png\"\nwidth=\"740\"\nheight=\"139\"\nloading=\"lazy\"\nalt=\"Early data\">\n<\/a>\n<figcaption>Early data<\/figcaption>\n<\/figure><\/p>\n<p>\u53ef\u4ee5\u4f7f\u7528 openssl \u6d4b\u8bd5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">openssl s_client -connect :443 -tls1_3 -sess_in session.pem -early_data request.txt\n<\/span><\/span><\/code><\/pre><\/div><p><a class=\"link\" href=\"https:\/\/gist.github.com\/5e639bfaf012ad5840f36a591f7d4904#file-test-early-data-sh\" target=\"_blank\" rel=\"noopener\"\n>\u5b8c\u6574\u6d4b\u8bd5\u811a\u672c<\/a><\/p>\n<p>\u66f4\u591a\u7ec6\u8282\u53c2\u8003 RFC 8446\uff1a<a class=\"link\" href=\"https:\/\/tools.ietf.org\/html\/rfc8446#section-2.3\" target=\"_blank\" rel=\"noopener\"\n>https:\/\/tools.ietf.org\/html\/rfc8446#section-2.3<\/a><\/p>\n<p>\u8fd9\u79cd\u65b9\u5f0f\u867d\u7136\u53ef\u4ee5\u7701\u4e0b\u4e00\u4e2a RTT \u4f46\u662f\u727a\u7272\u4e86\u524d\u5411\u5b89\u5168\u6027\u548c\u62b5\u6297\u91cd\u653e\u653b\u51fb\u7684\u80fd\u529b<\/p>\n<p>\u5728 nginx \u4e2d\u5f00\u542f Early data \u7684\u65b9\u5f0f\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_early_data<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># \u53ef\u9009\u9879\uff0c\u8868\u793a\u6b64 HTTP \u8bf7\u6c42\u5728 Early data \u4e2d\u53d1\u9001\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">proxy_set_header<\/span> <span class=\"s\">Early-Data<\/span> <span class=\"nv\">$ssl_early_data<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"ocsp-stapling\">OCSP stapling<\/h2>\n<p>OCSP stapling \u662f\u4e00\u9879 TLS \u7684\u62d3\u5c55\uff1a<\/p>\n<p>\u670d\u52a1\u5668\u5c06 OCSP response \u7f13\u5b58\u5728\u670d\u52a1\u5668\u4e2d\uff0c\u7136\u540e\u628a\u5b83\u4eec\u4f5c\u4e3a TLS \u63e1\u624b\u7684\u4e00\u90e8\u5206\u53d1\u9001\u7ed9\u5ba2\u6237\u7aef\u3002\u56e0\u6b64\uff0c\u5ba2\u6237\u7aef\u5728\u548c\u4e00\u4e2a\u652f\u6301 OCSP Stapling \u6280\u672f\u7684\u670d\u52a1\u5668\u901a\u4fe1\u65f6\uff0c\u5b83\u53ef\u4ee5\u540c\u65f6\u63a5\u6536\u5230\u670d\u52a1\u5668\u8bc1\u4e66\u548c\u8be5\u8bc1\u4e66\u7684\u72b6\u6001<\/p>\n<p>\u8fd9\u9879\u6280\u672f\u6709\u6548\u7684\u4fdd\u62a4\u4e86\u7528\u6237\u7684\u9690\u79c1\u540c\u65f6\u4fdd\u8bc1\u4e86 OCSP \u7684\u53ef\u7528\u6027<\/p>\n<p>Nginx \u4e2d\u5f00\u542f OCSP stapling\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_stapling<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_stapling_verify<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">resolver<\/span> <span class=\"mi\">1<\/span><span class=\"s\">.1.1.1<\/span> <span class=\"mi\">1<\/span><span class=\"s\">.0.0.1<\/span> <span class=\"mi\">8<\/span><span class=\"s\">.8.8.8<\/span> <span class=\"mi\">8<\/span><span class=\"s\">.8.4.4<\/span> <span class=\"mi\">208<\/span><span class=\"s\">.67.222.222<\/span> <span class=\"mi\">208<\/span><span class=\"s\">.67.220.220<\/span> <span class=\"s\">valid=60s<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">resolver_timeout<\/span> <span class=\"s\">2s<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8981\u6ce8\u610f\u7684\u662f\u5982\u679c\u4f60\u7684 CA \u63d0\u4f9b\u7684 OCSP \u9700\u8981\u9a8c\u8bc1\u7684\u8bdd\uff0c\u5fc5\u987b\u7528 <code>ssl_trusted_certificate<\/code> \u6307\u5b9a CA \u7684\u4e2d\u7ea7\u8bc1\u4e66\u548c\u6839\u8bc1\u4e66\uff08PEM \u683c\u5f0f\uff0c\u653e\u5728\u4e00\u4e2a\u6587\u4ef6\u4e2d\uff09\u7684\u4f4d\u7f6e\uff0c\u5426\u5219\u4f1a\u62a5\u9519 <code>[error] 17105#17105: OCSP_basic_verify() failed<\/code><\/p>\n<h2 id=\"strict-sni\">Strict SNI<\/h2>\n<p>\u4e3a Nginx \u5f00\u542f\u4e25\u683c\u7684 SNI \u5339\u914d\uff0c\u9632\u6b62\u4f7f\u7528 ip \u6216\u9519\u8bef\u57df\u540d\u7684\u8bbf\u95ee\u66b4\u9732\u8bc1\u4e66<\/p>\n<p>Nginx \u672c\u8eab\u4e0d\u63d0\u4f9b\u8fd9\u4e2a\u529f\u80fd\uff0c1.15.10 \u4ee5\u540e\u7684\u7248\u672c\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a patch\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\"># run in nginx directory\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">curl<\/span> <span class=\"s\">https:\/\/github.com\/hakasenyang\/openssl-patch\/blob\/master\/nginx_strict-sni_1.15.10.patch<\/span> <span class=\"s\">|<\/span> <span class=\"s\">patch<\/span> <span class=\"s\">-p1<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u5728 http \u6a21\u5757\u4e2d\u5f00\u542f<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">strict_sni<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">strict_sni_header<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u4f7f\u7528-ecc-\u8bc1\u4e66\">\u4f7f\u7528 ECC \u8bc1\u4e66<\/h2>\n<p>ECC \u8bc1\u4e66\u5373\u4f7f\u7528 ECDSA\uff08Elliptic Curve Digital Signature Algorithm\uff09\u7684\u8bc1\u4e66\uff0c\u62e5\u6709\u66f4\u5c0f\u7684\u5bc6\u94a5\u957f\u5ea6\u548c\u4e0e\u4e3b\u6d41\u7b97\u6cd5\u76f8\u6bd4\u66f4\u597d\u7684\u52a0\u5bc6\u5f3a\u5ea6\uff08\u76f8\u5f53\u4e8e RSA 3072\uff09<\/p>\n<p>\u4e0b\u56fe\u5373\u662f\u4e00\u4e2a ECC \u8bc1\u4e66\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 162;\nflex-basis: 390px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/ecc-cert.png\" data-size=\"446x274\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/nginx-ssl-tls-configuration-optimization\/ecc-cert.png\"\nwidth=\"446\"\nheight=\"274\"\nloading=\"lazy\"\nalt=\"ECC \u8bc1\u4e66\">\n<\/a>\n<figcaption>ECC \u8bc1\u4e66<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u5bc6\u7801\u5957\u4ef6\u9009\u62e9\">\u5bc6\u7801\u5957\u4ef6\u9009\u62e9<\/h2>\n<p>\u6211\u9009\u7528\u7684\u670d\u52a1\u5668\u504f\u597d\u5bc6\u7801\u5957\u4ef6\uff1a<\/p>\n<p>\u5bc6\u94a5\u4ea4\u6362\u7b97\u6cd5\uff1aECDH \uff08\u5177\u6709\u524d\u5411\u5b89\u5168\u6027\u5e76\u4e14\u6bd4 DH \u8d44\u6e90\u6d88\u8017\u4f4e\uff09<\/p>\n<p>\u7b7e\u540d\u7b97\u6cd5\uff1aECC<\/p>\n<p>\u5bf9\u79f0\u52a0\u5bc6\u7b97\u6cd5\uff1aAES-GCM \uff08\u662f\u4e00\u79cd AEAD \u7b97\u6cd5\u5e76\u4e14\u52a0\u5bc6\u89e3\u5bc6\u5747\u53ef\u5e76\u884c\u8ba1\u7b97\uff09<\/p>\n<p>\u5b8c\u6574\u914d\u7f6e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_ecdh_curve<\/span> <span class=\"s\">X25519:P-256:P-384:P-224:P-521<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_ciphers<\/span> <span class=\"s\">[TLS_AES_256_GCM_SHA384|TLS_AES_128_GCM_SHA256|TLS_CHACHA20_POLY1305_SHA256]:[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_prefer_server_ciphers<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u7b49\u4ef7\u52a0\u5bc6\u7b97\u6cd5\u7ec4\">\u7b49\u4ef7\u52a0\u5bc6\u7b97\u6cd5\u7ec4<\/h3>\n<p>\u4e0a\u6587\u4e2d <code>[XXX|XXX]<\/code> \u662f\u7b49\u4ef7\u5bc6\u7801\u7ec4\u7684\u5199\u6cd5\uff0c\u5728\u5f00\u542f <code>ssl_prefer_server_ciphers on<\/code> \u7684\u60c5\u51b5\u4e0b\u7ed9\u4e88\u5ba2\u6237\u7aef\u5728\u6709\u9650\u7684\u51e0\u79cd\u5bc6\u7801\u5957\u4ef6\u4e4b\u95f4\u9009\u62e9\u6700\u5408\u9002\u7684\u4e00\u79cd<\/p>\n<p>\u672c\u7ad9\u4f7f\u7528\u8fd9\u9879\u6280\u672f\u4e3a\u4e0d\u652f\u6301 AES-NI \u7684\u8bbe\u5907\u81ea\u52a8\u534f\u5546 CHACHA20-POLY1305 \u7b97\u6cd5<br \/>\nOpenSSL \u4e2d\u4e0d\u652f\u6301\u6b64\u9879\u6280\u672f\uff0c\u53ef\u4ee5\u4f7f\u7528 boringssl \u6216\u6253\u4e0a<a class=\"link\" href=\"https:\/\/github.com\/hakasenyang\/openssl-patch\/blob\/master\/openssl-equal-1.1.1d_ciphers.patch\" target=\"_blank\" rel=\"noopener\"\n>\u8fd9\u4e2a patch<\/a>\uff1a<\/p>\n<p>PS. ARMv8 \u4e2d\u5c31\u63d0\u4f9b\u4e86 AES \u6307\u4ee4\u96c6\u652f\u6301\uff0c\u90fd 9102 \u5e74\u4e86\uff0c\u65b0\u624b\u673a\u57fa\u672c\u4e0a\u6ca1\u6709\u4e0d\u652f\u6301\u7684<\/p>\n<h3 id=\"dh-\u53c2\u6570\">DH \u53c2\u6570<\/h3>\n<p>\u4e3a\u4e0a\u6587\u4e2d DHE \u548c ECDHE \u6307\u5b9a\u4e00\u4e2a\u66f4\u5f3a\u7684\u53c2\u6570\uff08\u8fd9\u91cc\u662f 4096 \u4f4d\uff09<\/p>\n<p>step 1. \u4f7f\u7528 openssl \u751f\u6210 <code>dhparam.pem<\/code> \u6587\u4ef6<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">openssl<\/span> <span class=\"s\">dhparam<\/span> <span class=\"s\">-out<\/span> <span class=\"s\">dhparam.pem<\/span> <span class=\"mi\">4096<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>step 2. \u914d\u7f6e nginx \u53c2\u6570<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">ssl_dhparam<\/span> <span class=\"s\">path-to-dhparam-file<\/span>\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Nginx \u7f16\u8bd1\u5b89\u88c5\u811a\u672c","link":"https:\/\/blog.lv5.moe\/p\/nginx-compile-and-install-script","pubDate":"Fri, 23 Aug 2019 11:20:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/nginx-compile-and-install-script","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/nginx-compile-and-install-script\/nginx-logo.jpg\" alt=\"Featured image of post Nginx \u7f16\u8bd1\u5b89\u88c5\u811a\u672c\" \/><p>\u6b64\u811a\u672c\u9002\u7528\u4e8e Ubuntu\uff0c\u81ea\u52a8\u7f16\u8bd1\u5b89\u88c5 nginx<\/p>\n<h2 id=\"\u4e3a\u4ec0\u4e48\u9700\u8981\u6b64\u811a\u672c\">\u4e3a\u4ec0\u4e48\u9700\u8981\u6b64\u811a\u672c<\/h2>\n<ol>\n<li>\n<p>\u5b89\u88c5 Nginx \u6700\u65b0 Mainline version<\/p>\n<\/li>\n<li>\n<p>\u5bf9 nginx \u548c OpenSSL \u6253\u8865\u4e01<\/p>\n<ul>\n<li>\u4e3a nginx \u6dfb\u52a0 SPDY\u3001FULL HPACK\u3001Dynamic TLS Record \u652f\u6301<\/li>\n<li>\u4e3a nginx \u63d0\u4f9b\u9009\u62e9 TLS 1.3 \u5bc6\u7801\u5957\u4ef6\u7684\u529f\u80fd<\/li>\n<li>\u4e3a openssl \u6dfb\u52a0\u7b49\u4ef7\u5bc6\u7801\u7ec4\u3001chacha \u8349\u6848\u652f\u6301<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4f7f\u7528 jemalloc \u4f18\u5316\u5185\u5b58\u7ba1\u7406<\/p>\n<\/li>\n<li>\n<p>\u4f7f\u7528 Cloudflare \u4f18\u5316\u7684 zlib\uff0c\u63d0\u5347\u6027\u80fd<\/p>\n<\/li>\n<li>\n<p>\u6dfb\u52a0 brotli \u538b\u7f29\u652f\u6301<\/p>\n<\/li>\n<li>\n<p>\u6dfb\u52a0 Strict-SNI \u652f\u6301<\/p>\n<\/li>\n<li>\n<p>\u6dfb\u52a0 Lua \u652f\u6301<\/p>\n<\/li>\n<li>\n<p>\u53ef\u9009\u9879\uff1anginx \u6d41\u5a92\u4f53\u652f\u6301\uff08Rmtp\u3001HLS\u3001Dash\uff09\u3001\u7b80\u6613\u7684 web \u5e94\u7528\u9632\u706b\u5899\uff08lua_waf\uff09<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"\u4f7f\u7528\u65b9\u6cd5\">\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<p>GitHub \u4ed3\u5e93\uff1a<a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/vps-setup\" target=\"_blank\" rel=\"noopener\"\n>ShadowySpirits\/vps-setup<\/a><\/p>\n<p>\u8fd0\u884c\u6b64\u884c\u4ee3\u7801\u5373\u53ef<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">curl https:\/\/raw.githubusercontent.com\/ShadowySpirits\/vps-setup\/master\/nginx_install.sh <span class=\"p\">|<\/span> bash\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd0\u884c\u811a\u672c\u65f6\u6dfb\u52a0\u4ee5\u4e0b\u53c2\u6570\u5f00\u542f\u53ef\u9009\u529f\u80fd\uff1a<\/p>\n<ul>\n<li>&ndash;with-vod \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: \u6dfb\u52a0 nginx-vod-module\uff08nginx \u6d41\u5a92\u4f53\u652f\u6301\uff09<\/li>\n<li>&ndash;enable-mkv \u00a0\u00a0: \u5f00\u542f nginx-vod-module \u7684 mkv \u683c\u5f0f\u652f\u6301 (\u5b9e\u9a8c\u6027\u529f\u80fd)<\/li>\n<li>&ndash;with-waf \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: \u6dfb\u52a0 lua_waf \uff08\u7b80\u6613\u7684 web \u5e94\u7528\u9632\u706b\u5899\uff09<\/li>\n<\/ul>\n<p>\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5f00\u542f\u3001\u5173\u95ed\u6216\u91cd\u542f\u670d\u52a1<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">sudo service nginx start\/stop\/restart\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u6b64\u811a\u672c\u4f9d\u8d56\u7684\u4ee3\u7801\u4ed3\u5e93\u591a\u4f4d\u4e8e\u56fd\u5916\u670d\u52a1\u5668\uff0c\u5982\u5b89\u88c5\u5931\u8d25\u8bf7\u68c0\u67e5\u662f\u5426\u662f\u7f51\u7edc\u95ee\u9898\n<\/div>\n<p><\/p>"},{"title":"Deluge 2.0.3 \u4fee\u6539 user-agent \u548c peer-id \u6559\u7a0b","link":"https:\/\/blog.lv5.moe\/p\/deluge-modify-user-agent-and-peer-id-tutorials","pubDate":"Fri, 23 Aug 2019 10:57:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/deluge-modify-user-agent-and-peer-id-tutorials","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/deluge-modify-user-agent-and-peer-id-tutorials\/deluge-logo.jpg\" alt=\"Featured image of post Deluge 2.0.3 \u4fee\u6539 user-agent \u548c peer-id \u6559\u7a0b\" \/><p>\u672c\u6587\u63d0\u4f9b\u4e00\u79cd\u4fee\u6539 Deluge \u7684 user-agent \u548c peer-id \u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u4f2a\u88c5\u5176\u4ed6 BT \u4e0b\u8f7d\u5de5\u5177\uff0c\u7ed5\u8fc7\u67d0\u4e9b\u9650\u5236<\/p>\n<p>PS\uff1a\u9644\u90e8\u5206 BT \u4e0b\u8f7d\u5de5\u5177 user-agent \u548c peer-id \u5217\u8868<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u5982\u4f55\u5b89\u88c5 Deluge \u8bf7\u5148\u9605\u8bfb <a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/deluge-oneclick-installation-script\" >Deluge \u4e00\u952e\u5b89\u88c5\u811a\u672c<\/a>\n<\/div>\n<p><\/p>\n<h2 id=\"tldr\">TL;DR<\/h2>\n<p>\u53ef\u4ee5\u4f7f\u7528 dzhuang \u6253\u5305\u597d\u7684 docker iamge: <a class=\"link\" href=\"https:\/\/hub.docker.com\/r\/dzhuang\/docker-deluge\" target=\"_blank\" rel=\"noopener\"\n>dzhuang\/docker-deluge<\/a><\/p>\n<p>\u5728\u8bbe\u7f6e\u4e2d\u76f4\u63a5\u4fee\u6539 user-agent \u548c peer-id<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 96;\nflex-basis: 230px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/deluge-modify-user-agent-and-peer-id-tutorials\/deluge-config.png\" data-size=\"485x504\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/deluge-modify-user-agent-and-peer-id-tutorials\/deluge-config.png\"\nwidth=\"485\"\nheight=\"504\"\nloading=\"lazy\"\nalt=\"config\">\n<\/a>\n<figcaption>config<\/figcaption>\n<\/figure><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\ndzhuang \u63d0\u4f9b\u4e86<a class=\"link\" href=\"https:\/\/github.com\/dzhuang\/deluge-alpine-build\" target=\"_blank\" rel=\"noopener\"\n>\u6e90\u7801\u4ed3\u5e93<\/a>\uff0c\u8bf7\u4f7f\u7528\u8005\u81ea\u884c\u8bc4\u4f30\n<\/div>\n<p><\/p>\n<h2 id=\"\u4fee\u6539-user-agent\">\u4fee\u6539 user-agent<\/h2>\n<p>\u6253\u5f00\u6587\u4ef6 <code>\/usr\/lib\/python3\/dist-packages\/deluge\/core\/core.py<\/code><\/p>\n<p>\u4fee\u6539 123 \u884c\u5de6\u53f3\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\"><span class=\"line\"><span class=\"cl\"># Start the libtorrent session.\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"gd\">- user_agent = &#39;Deluge\/{} libtorrent\/{}&#39;.format(DELUGE_VER, LT_VERSION)\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"gd\"><\/span><span class=\"gi\">+ user_agent = &#39;Transmission\/2.11&#39;\n<\/span><\/span><\/span><\/code><\/pre><\/div><h2 id=\"\u4fee\u6539-peer-id\">\u4fee\u6539 peer-id<\/h2>\n<p>\u4fee\u6539 291 \u884c\u5de6\u53f3\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\"><span class=\"line\"><span class=\"cl\">peer_id = substitute_chr(peer_id, 6, release_chr)\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"gd\">- return peer_id\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"gd\"><\/span><span class=\"gi\">+ return &#39;-TR2110-&#39;\n<\/span><\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock info\">\n\u867d\u7136\u8fd9\u662f Deluge 2.0.3 \u7684\u6559\u7a0b\uff0c\u4f46 Deluge \u5176\u4ed6\u7248\u672c\u4fee\u6539\u65b9\u5f0f\u5927\u540c\u5c0f\u5f02\uff0c\u641c\u7d22\u5b57\u7b26\u4e32 user_agent \u548c peer_id \u4e5f\u80fd\u627e\u5230\u5173\u952e\u4ee3\u7801\u4f4d\u7f6e\n<\/div>\n<p><\/p>\n<h2 id=\"\u90e8\u5206-bt-\u4e0b\u8f7d\u5de5\u5177-user-agent-\u548c-peer-id-\u5217\u8868\">\u90e8\u5206 BT \u4e0b\u8f7d\u5de5\u5177 user-agent \u548c peer-id \u5217\u8868<\/h2>\n<table>\n<thead>\n<tr>\n<th>name<\/th>\n<th>user-agent<\/th>\n<th>peer-id<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>utorrentMac 1.6.4<\/td>\n<td>uTorrentMac\/1640(27255)<\/td>\n<td>-UM1640-<\/td>\n<\/tr>\n<tr>\n<td>utorrent 2.2.1<\/td>\n<td>uTorrent\/2210(25110)<\/td>\n<td>-UT2210-<\/td>\n<\/tr>\n<tr>\n<td>Transmission 2.11<\/td>\n<td>Transmission\/2.11<\/td>\n<td>-TR2110-<\/td>\n<\/tr>\n<tr>\n<td>Deluge 1.3.5<\/td>\n<td>Deluge\/1350<\/td>\n<td>-DE1350-<\/td>\n<\/tr>\n<\/tbody>\n<\/table>"},{"title":"Deluge \u4e00\u952e\u5b89\u88c5\u811a\u672c","link":"https:\/\/blog.lv5.moe\/p\/deluge-oneclick-installation-script","pubDate":"Fri, 23 Aug 2019 10:26:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/deluge-oneclick-installation-script","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/deluge-oneclick-installation-script\/deluge-logo.jpg\" alt=\"Featured image of post Deluge \u4e00\u952e\u5b89\u88c5\u811a\u672c\" \/><p>\u6b64\u811a\u672c\u9002\u7528\u4e8e Ubuntu\uff0c\u81ea\u52a8\u5b89\u88c5 deluged \u548c deluge-webui<\/p>\n<h2 id=\"\u4e3a\u4ec0\u4e48\u9700\u8981\u6b64\u811a\u672c\">\u4e3a\u4ec0\u4e48\u9700\u8981\u6b64\u811a\u672c<\/h2>\n<ol>\n<li>\u81ea\u52a8\u5b89\u88c5 deluge \u6700\u65b0\u7a33\u5b9a\u7248<\/li>\n<li>\u521b\u5efa deluge \u7528\u6237\u4ee5\u8fd0\u884c deluge \u7a0b\u5e8f<\/li>\n<li>\u521b\u5efa deluged \u548c deluge-web \u670d\u52a1\uff0c\u5f00\u673a\u81ea\u542f\u52a8<\/li>\n<\/ol>\n<h2 id=\"\u4f7f\u7528\u65b9\u6cd5\">\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<p>GitHub \u4ed3\u5e93\uff1a<a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/vps-setup\" target=\"_blank\" rel=\"noopener\"\n>ShadowySpirits\/vps-setup<\/a><\/p>\n<p>\u8fd0\u884c\u6b64\u884c\u4ee3\u7801\u5373\u53ef<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">curl https:\/\/raw.githubusercontent.com\/ShadowySpirits\/vps-setup\/master\/deluge_install.sh <span class=\"p\">|<\/span> sudo bash\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5f00\u5f00\u542f\u3001\u5173\u95ed\u6216\u91cd\u542f\u670d\u52a1<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">sudo service deluged start\/stop\/restart\n<\/span><\/span><span class=\"line\"><span class=\"cl\">sudo service deluge-web start\/stop\/restart\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u8bbf\u95ee <code>http:\/\/your-ip:8112<\/code> \u5c31\u53ef\u4ee5\u8fdb\u5165 Deluge WebUI<\/p>\n<p>\u8f93\u5165\u9ed8\u8ba4\u5bc6\u7801 deluge \u540e\uff0c\u70b9\u51fb connect \u5c31\u53ef\u4ee5\u8fde\u63a5\u4e0a\u670d\u52a1\u5668\uff0c\u5f00\u59cb\u4f7f\u7528\u4e86<\/p>"},{"title":"\u4f7f\u7528 Kotlin DSL \u4ee3\u66ff Builder \u6a21\u5f0f","link":"https:\/\/blog.lv5.moe\/p\/from-builder-to-kotlin-dsl","pubDate":"Mon, 29 Apr 2019 23:22:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/from-builder-to-kotlin-dsl","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/from-builder-to-kotlin-dsl\/kotlin-logo.png\" alt=\"Featured image of post \u4f7f\u7528 Kotlin DSL \u4ee3\u66ff Builder \u6a21\u5f0f\" \/><p>\u672c\u6587\u65e8\u5728\u4ecb\u7ecd\u5982\u4f55\u7528 Kotlin DSL \u6765\u4ee3\u66ff Builder \u6a21\u5f0f\uff0c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4ec0\u4e48\u662f DSL \u6216\u8005\u4e0d\u4e86\u89e3 Kotlin \u4e2d\u7684 DSL \u53ef\u4ee5\u9605\u8bfb\u6211\u7684\u4e0a\u4e00\u7bc7\u6587\u7ae0\uff1a<a class=\"link\" href=\"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl\" >Kotlin DSL \u7b80\u4ecb<\/a><\/p>\n<h2 id=\"\u4e3e\u4e2a\u4f8b\u5b50\">\u4e3e\u4e2a\u4f8b\u5b50<\/h2>\n<p>\u6211\u4eec\u60f3\u7f16\u5199\u4e00\u4e2a HTML \u6784\u5efa\u5668\u8f93\u51fa\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"line\"><span class=\"cl\"><span class=\"p\">&lt;<\/span><span class=\"nt\">html<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">head<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">title<\/span><span class=\"p\">&gt;<\/span>HTML encoding with Kotlin<span class=\"p\">&lt;\/<\/span><span class=\"nt\">title<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;\/<\/span><span class=\"nt\">head<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">h1<\/span><span class=\"p\">&gt;<\/span>HTML encoding with Kotlin<span class=\"p\">&lt;\/<\/span><span class=\"nt\">h1<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>this format can be used as an alternative markup to HTML<span class=\"p\">&lt;\/<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">a<\/span> <span class=\"na\">href<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;http:\/\/jetbrains.com\/kotlin&#34;<\/span><span class=\"p\">&gt;<\/span> Kotlin <span class=\"p\">&lt;\/<\/span><span class=\"nt\">a<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>some text<span class=\"p\">&lt;\/<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">&lt;\/<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">&lt;\/<\/span><span class=\"nt\">html<\/span><span class=\"p\">&gt;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u4f7f\u7528 Builder \u6a21\u5f0f\u4ee3\u7801\u7c7b\u4f3c\u8fd9\u6837\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">val<\/span> <span class=\"py\">html<\/span> <span class=\"p\">=<\/span> <span class=\"n\">HTMLBuilder<\/span><span class=\"p\">().<\/span><span class=\"n\">addHead<\/span><span class=\"p\">(<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">HeadBuilder<\/span><span class=\"p\">().<\/span><span class=\"n\">addTitle<\/span><span class=\"p\">(<\/span><span class=\"n\">TitleBuilder<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;HTML encoding with Kotlin&#34;<\/span><span class=\"p\">).<\/span><span class=\"n\">build<\/span><span class=\"p\">())<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">).<\/span><span class=\"n\">addBody<\/span><span class=\"p\">(<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">BodyBuilder<\/span><span class=\"p\">().<\/span><span class=\"n\">addH1<\/span><span class=\"p\">(<\/span><span class=\"n\">H1Builder<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;HTML encoding with Kotlin&#34;<\/span><span class=\"p\">))<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">.<\/span><span class=\"n\">addP<\/span><span class=\"p\">(<\/span><span class=\"n\">PBuilder<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;this format can be used as an alternative markup to HTML&#34;<\/span><span class=\"p\">).<\/span><span class=\"n\">build<\/span><span class=\"p\">())<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">.<\/span><span class=\"n\">addA<\/span><span class=\"p\">(<\/span><span class=\"n\">ABuilder<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Kotlin&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">.<\/span><span class=\"n\">setHerf<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;http:\/\/jetbrains.com\/kotlin&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">.<\/span><span class=\"n\">build<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">).<\/span><span class=\"n\">addP<\/span><span class=\"p\">(<\/span><span class=\"n\">PBuilder<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;some text&#34;<\/span><span class=\"p\">).<\/span><span class=\"n\">build<\/span><span class=\"p\">())<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">).<\/span><span class=\"n\">build<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">println<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u5199\u8fd9\u4e9b XXXBuilder \u5c31\u5f88\u9ebb\u70e6\u4e86\uff0c\u800c\u4e14\u4ee3\u7801\u5341\u5206\u81c3\u80bf\uff0c\u53ef\u8bfb\u6027\u5f88\u5dee\u3002\u518d\u6765\u770b\u770b Kotlin DSL \u7684\u5199\u6cd5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">fun<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"n\">Array<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">String<\/span><span class=\"p\">&gt;)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">result<\/span> <span class=\"p\">=<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">html<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">head<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">title<\/span> <span class=\"p\">{<\/span> <span class=\"p\">+<\/span><span class=\"s2\">&#34;HTML encoding with Kotlin&#34;<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">body<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">h1<\/span> <span class=\"p\">{<\/span> <span class=\"p\">+<\/span><span class=\"s2\">&#34;HTML encoding with Kotlin&#34;<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">p<\/span> <span class=\"p\">{<\/span> <span class=\"p\">+<\/span><span class=\"s2\">&#34;this format can be used as an alternative markup to HTML&#34;<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\">\/\/ an element with attributes and text content\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"n\">a<\/span><span class=\"p\">(<\/span><span class=\"n\">href<\/span> <span class=\"p\">=<\/span> <span class=\"s2\">&#34;http:\/\/jetbrains.com\/kotlin&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span> <span class=\"p\">+<\/span><span class=\"s2\">&#34;Kotlin&#34;<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">p<\/span> <span class=\"p\">{<\/span> <span class=\"p\">+<\/span><span class=\"s2\">&#34;some text&#34;<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">println<\/span><span class=\"p\">(<\/span><span class=\"n\">result<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u663e\u7136\u66f4\u52a0\u6e05\u6670\u660e\u4e86\uff0c\u5e76\u4e14\u4ee3\u7801\u91cf\u8981\u5c11\u7684\u591a\u3002<\/p>\n<h2 id=\"\u5177\u4f53\u5b9e\u73b0\">\u5177\u4f53\u5b9e\u73b0<\/h2>\n<p>\u6211\u4eec\u6765\u5206\u6790\u4e00\u4e0b\u8fd9\u6bb5 Kotlin DSL \u5b9e\u73b0\uff1a\u6784\u9020\u6807\u7b7e\u4f7f\u7528\u7684\u662f\u7c7b\u4f3c html { &hellip; } \u8fd9\u6837\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u63a5\u6536\u4e00\u4e2a Lambda \u8868\u8fbe\u5f0f\u4f5c\u4e3a\u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a HTML \u5bf9\u8c61\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">inline<\/span> <span class=\"k\">fun<\/span> <span class=\"nf\">html<\/span><span class=\"p\">(<\/span><span class=\"k\">init<\/span><span class=\"p\">:<\/span> <span class=\"n\">HTML<\/span><span class=\"p\">.()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">Unit<\/span><span class=\"p\">):<\/span> <span class=\"n\">HTML<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">html<\/span> <span class=\"p\">=<\/span> <span class=\"n\">HTML<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">html<\/span><span class=\"p\">.<\/span><span class=\"k\">init<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"n\">html<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p><\/p>\n<div class=\"tip inlineBlock info\">\n\u8fd9\u91cc\u4f7f\u7528\u5185\u8054\u51fd\u6570\u6765\u907f\u514d Lambda \u8868\u8fbe\u5f0f\u7684\u5f00\u9500\n<\/div>\n<p><\/p>\n<p>\u5176\u4ed6\u6807\u7b7e\u540c\u7406\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u4e00\u4e2a\u6cdb\u578b\u51fd\u6570\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">abstract<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Tag<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">children<\/span> <span class=\"p\">=<\/span> <span class=\"n\">arrayListOf<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">Tag<\/span><span class=\"p\">&gt;()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">inline<\/span> <span class=\"k\">protected<\/span> <span class=\"k\">fun<\/span> <span class=\"p\">&lt;<\/span><span class=\"nc\">T<\/span><span class=\"p\">:<\/span> <span class=\"nc\">Tag<\/span><span class=\"p\">&gt;<\/span> <span class=\"nf\">initTag<\/span><span class=\"p\">(<\/span><span class=\"n\">tag<\/span><span class=\"p\">:<\/span> <span class=\"n\">T<\/span><span class=\"p\">,<\/span> <span class=\"k\">init<\/span><span class=\"p\">:<\/span> <span class=\"n\">T<\/span><span class=\"p\">.()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">Unit<\/span><span class=\"p\">):<\/span> <span class=\"n\">T<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">tag<\/span><span class=\"p\">.<\/span><span class=\"k\">init<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">children<\/span><span class=\"p\">.<\/span><span class=\"n\">add<\/span><span class=\"p\">(<\/span><span class=\"n\">tag<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"n\">tag<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">....<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u4f20\u5165\u5bf9\u5e94\u7684\u6807\u7b7e\u7c7b\u578b\u5373\u53ef\u521b\u5efa\u4e0d\u540c\u7684\u6807\u7b7e\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">HTML<\/span><span class=\"p\">():<\/span> <span class=\"n\">Tag<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">fun<\/span> <span class=\"nf\">head<\/span><span class=\"p\">(<\/span><span class=\"k\">init<\/span><span class=\"p\">:<\/span> <span class=\"n\">Head<\/span><span class=\"p\">.()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">Unit<\/span><span class=\"p\">)<\/span> <span class=\"p\">=<\/span> <span class=\"n\">initTag<\/span><span class=\"p\">(<\/span><span class=\"n\">Head<\/span><span class=\"p\">(),<\/span> <span class=\"k\">init<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">fun<\/span> <span class=\"nf\">body<\/span><span class=\"p\">(<\/span><span class=\"k\">init<\/span><span class=\"p\">:<\/span> <span class=\"n\">Body<\/span><span class=\"p\">.()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">Unit<\/span><span class=\"p\">)<\/span> <span class=\"p\">=<\/span> <span class=\"n\">initTag<\/span><span class=\"p\">(<\/span><span class=\"n\">Body<\/span><span class=\"p\">(),<\/span> <span class=\"k\">init<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u6837\u6211\u4eec\u5c31\u5b8c\u6210\u4e86\u4e00\u4e2a\u7b80\u5355\u7684 HTML Builder\uff0c\u5b8c\u6574\u7684\u4ee3\u7801\u89c1\u6b64\uff1a<a class=\"link\" href=\"https:\/\/try.kotlinlang.org\/#\/Examples\/Longer%20examples\/HTML%20Builder\/HTML%20Builder.kt\" target=\"_blank\" rel=\"noopener\"\n>HTML Builder<\/a>\u3002<\/p>\n<h2 id=\"\u9650\u5236\u4f5c\u7528\u57df\">\u9650\u5236\u4f5c\u7528\u57df<\/h2>\n<p>\u601d\u8003\u5982\u4e0b\u4ee3\u7801\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">html<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;html scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">head<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;head scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">head<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;head scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u663e\u7136 <code>head<\/code> \u6807\u7b7e\u4e2d\u5d4c\u5957\u53e6\u4e00\u4e2a <code>head<\/code> \u6807\u7b7e\u662f\u6ca1\u6709\u610f\u4e49\u7684\uff0c\u800c\u4e14\u7f16\u8bd1\u5374\u4e0d\u4f1a\u62a5\u9519\u3002\u8fd9\u662f\u56e0\u4e3a Kotlin \u4f1a\u9690\u5f0f\u63a8\u65ad\u63a5\u6536\u8005\u4e3a\u6700\u9876\u5c42 Lambda \u8868\u8fbe\u5f0f\u4e2d this \u6307\u5411\u7684 HTML \u5bf9\u8c61\u3002\u6240\u4ee5\u6211\u4eec\u8981\u4fee\u6b63\u8fd9\u4e2a\u95ee\u9898\u5c31\u8981\u7981\u6b62\u8fd9\u79cd\u9690\u5f0f\u63a8\u65ad\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@DslMarker<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">annotation<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">HtmlTagMarker<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nd\">@HtmlTagMarker<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">abstract<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Tag<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"o\">....<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f7f\u7528 <code>@DslMarker<\/code> \u58f0\u660e\u4e00\u4e2a\u6ce8\u89e3 <code>@HtmlTagMarker<\/code>\uff0c\u7136\u540e\u4e3a\u6240\u6709\u6807\u7b7e\u7684\u57fa\u7c7b <code>Tag<\/code> \u52a0\u4e0a\u8fd9\u4e2a\u6ce8\u89e3\u5373\u53ef\u3002\u518d\u6b21\u5c1d\u8bd5\u4f7f\u7528\u8fd9\u79cd\u4e0d\u89c4\u8303\u7684\u5199\u6cd5\u5c31\u4f1a\u62a5\u9519\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-plaintext\" data-lang=\"plaintext\"><span class=\"line\"><span class=\"cl\">&#39;fun head(init: Head.() -&gt; Unit): Head&#39; can&#39;t be called in this context by implicit receiver.\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f46\u662f\u6211\u4eec\u4ecd\u901a\u8fc7\u6307\u5b9a\u7684\u63a5\u6536\u8005\u8fdb\u884c\u8c03\u7528\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">html<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;html scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">head<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;head scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">this<\/span><span class=\"nd\">@html<\/span><span class=\"p\">.<\/span><span class=\"n\">head<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">+<\/span><span class=\"s2\">&#34;head scope&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Kotlin DSL \u7b80\u4ecb","link":"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl","pubDate":"Mon, 29 Apr 2019 11:38:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl\/kotlin-logo.png\" alt=\"Featured image of post Kotlin DSL \u7b80\u4ecb\" \/><h2 id=\"\u4ec0\u4e48\u662f-dsl\">\u4ec0\u4e48\u662f DSL<\/h2>\n<p>DSL(Domain Specific Language) \u4e2d\u6587\u540d\u79f0<strong>\u7279\u5b9a\u9886\u57df\u4e13\u7528\u8bed\u8a00<\/strong>\uff0c\u4e0e GPL(General Purpose Language) \u5373<strong>\u901a\u7528\u7f16\u7a0b\u8bed\u8a00<\/strong>\u76f8\u5bf9\u3002<\/p>\n<p>\u7ef4\u57fa\u767e\u79d1\u4e2d\u5bf9 DSL \u7684\u5b9a\u4e49\u5982\u4e0b\uff1a<\/p>\n<blockquote>\n<p>A <strong>domain-specific language<\/strong> (<strong>DSL<\/strong>) is a computer languagespecialized to a particular application domain.<\/p>\n<\/blockquote>\n<p>\u4e5f\u5c31\u662f\u8bf4\uff0cDSL \u662f\u4e00\u79cd\u8868\u8fbe\u80fd\u529b\u6709\u5c40\u9650\u7684\u8bed\u8a00\u3002\u76f8\u6bd4\u4e8e\u5e38\u89c1\u7684 C\u3001Java\u3001PHP \u7b49\u8bed\u8a00\uff0cDSL \u5e76\u4e0d\u80fd\u89e3\u51b3\u6240\u6709\u95ee\u9898\uff1b\u76f8\u53cd\uff0cDSL \u7684\u4f18\u52bf\u5728\u4e8e\u9ad8\u6548\u3001\u8de8\u5e73\u53f0\u3002<\/p>\n<p>\u5e38\u89c1\u7684 DSL \u8bed\u8a00\uff1a<\/p>\n<ul>\n<li>Regex<\/li>\n<li>SQL<\/li>\n<li>HTML &amp; CSS<\/li>\n<\/ul>\n<p>\u4ee5\u524d\u7aef\u5f00\u53d1\u4e3a\u4f8b\uff0c\u4e00\u822c\u90fd\u662f\u4f7f\u7528 HTML \u6216 XML \u63cf\u8ff0\u754c\u9762\uff0c\u7136\u540e\u7528 js (Web) \u6216 java\/kotlin (Android) \u7b49\u8bed\u8a00\u7f16\u5199\u903b\u8f91\u3002\u4f60\u4f1a\u53d1\u73b0 DSL \u63cf\u8ff0\u754c\u9762\u6bd4\u7528\u4ee3\u7801\u521b\u5efa\u7ec4\u4ef6\u8981\u65b9\u4fbf\u7684\u591a\uff0c\u800c\u4e14\u5199\u51fa\u7684 HTML \u6216 XML \u6587\u4ef6\u5728\u4efb\u4f55\u8bed\u8a00\u4efb\u4f55\u7cfb\u7edf\u4e0b\u90fd\u53ef\u4ee5\u89e3\u6790\u3002<\/p>\n<h2 id=\"\u5728-kotlin-\u4e2d\u4f7f\u7528-dsl\">\u5728 Kotlin \u4e2d\u4f7f\u7528 DSL<\/h2>\n<p>\u4e0a\u4e00\u8282\u63d0\u5230\u7684 DSL \u662f\u4f5c\u4e3a\u4e00\u95e8\u5355\u72ec\u7684\u8bed\u8a00\u5b58\u5728\u7684 External DSL\uff0c\u67d0\u4e9b\u8bed\u8a00\u4e3a\u4e86\u5f15\u5165 DSL \u7684\u7279\u6027\u52a0\u5165\u4e86 Internal DSL \u8fd9\u79cd\u4e1c\u897f\u3002\u6bd4\u5982\u5728 Kotlin \u4e2d\u7528\u4ee3\u7801\u6784\u5efa\u4e00\u6bb5 HTML\uff1a<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 221;\nflex-basis: 531px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl\/html-builder.jpg\" data-size=\"574x259\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/introduction-to-kotlin-dsl\/html-builder.jpg\"\nwidth=\"574\"\nheight=\"259\"\nloading=\"lazy\"\nalt=\"HTML Builder\">\n<\/a>\n<figcaption>HTML Builder<\/figcaption>\n<\/figure><br \/>\n\u4f60\u53ef\u4ee5\u5728 <a class=\"link\" href=\"https:\/\/try.kotlinlang.org\/#\/Examples\/Longer%20examples\/HTML%20Builder\/HTML%20Builder.kt\" target=\"_blank\" rel=\"noopener\"\n>Try Kotlin<\/a> \u4e0a\u627e\u5230\u8fd9\u6bb5\u793a\u4f8b\u3002<\/p>\n<p>\u6240\u4ee5\uff0c\u6211\u4eec\u53ef\u4ee5\u7528\u8fd9\u79cd\u7279\u6027\u6781\u5927\u7684\u7cbe\u7b80\u6211\u4eec\u7684\u4ee3\u7801\uff08\u7b2c\u4e8c\u4e2a\u4f8b\u5b50\u4f7f\u7528\u7684\u662f <a class=\"link\" href=\"https:\/\/github.com\/Kotlin\/anko\" target=\"_blank\" rel=\"noopener\"\n>Kotlin\/anko<\/a> \u8fd9\u4e2a\u5e93\uff09\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ Create Alert Dialog\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ Android developer guide\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">val<\/span> <span class=\"py\">builder<\/span> <span class=\"p\">=<\/span> <span class=\"n\">AlertDialog<\/span><span class=\"p\">.<\/span><span class=\"n\">Builder<\/span><span class=\"p\">(<\/span><span class=\"k\">it<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">builder<\/span><span class=\"p\">.<\/span><span class=\"n\">setTitle<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Hi, I&#39;m Roy&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">.<\/span><span class=\"n\">setMessage<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Have you tried turning it off and on again?&#34;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">.<\/span><span class=\"n\">setPositiveButton<\/span><span class=\"p\">(<\/span><span class=\"n\">R<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">.<\/span><span class=\"n\">fire<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">DialogInterface<\/span><span class=\"p\">.<\/span><span class=\"n\">OnClickListener<\/span> <span class=\"p\">{<\/span> <span class=\"n\">dialog<\/span><span class=\"p\">,<\/span> <span class=\"n\">id<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">toast<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Oh\u2026&#34;<\/span><span class=\"p\">)})<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"n\">builder<\/span><span class=\"p\">.<\/span><span class=\"n\">create<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ Use Kotlin DSL\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"n\">alert<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Hi, I&#39;m Roy&#34;<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&#34;Have you tried turning it off and on again?&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">yesButton<\/span> <span class=\"p\">{<\/span> <span class=\"n\">toast<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Oh\u2026&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}.<\/span><span class=\"n\">show<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6216\u662f\u5728\u4ee3\u7801\u4e2d\u7f16\u5199\u754c\u9762\u5e03\u5c40\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-kotlin\" data-lang=\"kotlin\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">verticalLayout<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">val<\/span> <span class=\"py\">name<\/span> <span class=\"p\">=<\/span> <span class=\"n\">editText<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">button<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Say Hello&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"n\">onClick<\/span> <span class=\"p\">{<\/span> <span class=\"n\">toast<\/span><span class=\"p\">(<\/span><span class=\"s2\">&#34;Hello, <\/span><span class=\"si\">${name.text}<\/span><span class=\"s2\">!&#34;<\/span><span class=\"p\">)<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u53ef\u4ee5\u770b\u5230\u6211\u4eec\u6784\u5efa\u4e86\u7531\u4e00\u4e2a EditText \u548c\u4e00\u4e2a Button \u6784\u6210\u7684\u754c\u9762\uff0c\u5e76\u4e14\u6211\u4eec\u5728\u63cf\u8ff0\u754c\u9762\u7684\u540c\u65f6\u5c31\u5b8c\u6210\u4e86\u903b\u8f91\u7684\u7f16\u5199\u3002<\/p>"},{"title":"\u64cd\u4f5c\u7cfb\u7edf\u539f\u7406 \u2014\u2014 \u4e2d\u65ad","link":"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt","pubDate":"Tue, 19 Mar 2019 22:19:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/interrupt-timeline.jpg\" alt=\"Featured image of post \u64cd\u4f5c\u7cfb\u7edf\u539f\u7406 \u2014\u2014 \u4e2d\u65ad\" \/><blockquote>\n<p><strong>\u4e2d\u65ad<\/strong>\uff08\u82f1\u8bed\uff1aInterrupt\uff09\u662f\u6307\u5904\u7406\u5668\u63a5\u6536\u5230\u6765\u81ea\u786c\u4ef6\u6216\u8f6f\u4ef6\u7684\u4fe1\u53f7\uff0c\u63d0\u793a\u53d1\u751f\u4e86\u67d0\u4e2a\u4e8b\u4ef6\uff0c\u5e94\u8be5\u88ab\u6ce8\u610f\uff0c\u8fd9\u79cd\u60c5\u51b5\u5c31\u79f0\u4e3a\u4e2d\u65ad\u3002<sup id=\"fnref:1\"><a href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\">1<\/a><\/sup><\/p>\n<p>In summary, interrupts are used throughout modern operating systems to handle asynchronous events.<sup id=\"fnref:2\"><a href=\"#fn:2\" class=\"footnote-ref\" role=\"doc-noteref\">2<\/a><\/sup><\/p>\n<\/blockquote>\n<p>\u6211\u4eec\u8003\u8651\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff1a\u4ece\u952e\u76d8\u8bfb\u5165\u4e00\u4e2a\u5b57\u7b26\u3002\u4ece CPU \u7684\u89d2\u5ea6\u6765\u770b\u8fd9\u79cd I\/O \u64cd\u4f5c\u7684\u901f\u5ea6\u8fdc\u6162\u4e8e CPU \u9891\u7387\uff0c\u6240\u4ee5\u5728 CPU \u53d1\u51fa\u8bfb\u5165\u5b57\u7b26\u7684\u6307\u4ee4\u540e\u9700\u8981\u6d88\u8017\u6570\u767e\u4e0a\u5343\u4e2a\u65f6\u949f\u5468\u671f\u6765\u8f6e\u8be2\u662f\u5426\u6709\u6570\u636e\u8fd4\u56de\uff08\u8fd9\u88ab\u79f0\u4e3a\u5fd9\u7b49\u5f85 Busy waiting\uff09\uff0c\u5728\u8fd9\u4e2a\u8fc7\u7a0b\u4e2d\u5176\u4ed6\u64cd\u4f5c\u88ab\u963b\u585e\uff0c\u76f4\u5230\u952e\u76d8\u8fd4\u56de\u6570\u636e\u3002\u663e\u7136\u8fd9\u6837\u7684\u4f4e\u6548\u7387\u903b\u8f91\u662f\u4e0d\u53ef\u63a5\u53d7\u7684\u3002\u6211\u4eec\u9700\u8981\u7684\u662f\u4e00\u79cd<strong>\u5f02\u6b65\u673a\u5236<\/strong>\uff1a\u9700\u8981\u65f6\u518d\u901a\u77e5 CPU \u6765\u5904\u7406\uff0c\u8fd9\u6837\u53ef\u4ee5\u6700\u5927\u7a0b\u5ea6\u7684\u51cf\u5c11 CPU \u7684\u7b49\u5f85\u65f6\u95f4\u3002<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 228;\nflex-basis: 549px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/interrupt-timeline.jpg\" data-size=\"1495x653\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/interrupt-timeline.jpg\"\nwidth=\"1495\"\nheight=\"653\"\nloading=\"lazy\"\nalt=\"Interrupt timeline\">\n<\/a>\n<figcaption>Interrupt timeline<\/figcaption>\n<\/figure><\/p>\n<p>\u5982\u56fe\u6240\u793a\uff0c\u6bcf\u5f53 I\/O \u8bbe\u5907\u5b8c\u6210\u52a8\u4f5c\u65f6\u90fd\u4f1a\u89e6\u53d1\u4e2d\u65ad\uff0c\u7136\u540e CPU \u505c\u6b62\u6b63\u5728\u8fdb\u884c\u7684\u5de5\u4f5c\uff0c\u53bb\u5904\u7406\u76f8\u5e94\u7684\u4e2d\u65ad<\/p>\n<p>\u4e0b\u9762\u6211\u4eec\u901a\u8fc7<strong>\u786c\u4ef6\u4e2d\u65ad<\/strong>\uff08Hardware Interrupt\uff09\u6765\u8be6\u7ec6\u4ecb\u7ecd\u4e00\u4e0b\u4e2d\u65ad\u673a\u5236\uff1a<\/p>\n<ol>\n<li>CPU \u901a\u77e5\u8bbe\u5907\u9a71\u52a8\u7a0b\u5e8f\u5f00\u59cb\u4e00\u4e2a I\/O \u64cd\u4f5c\uff0c\u7136\u540e\u53bb\u5904\u7406\u5176\u4ed6\u5e94\u7528\u7a0b\u5e8f<\/li>\n<li>\u8bbe\u5907\u63a7\u5236\u5668\u5904\u7406 I\/O \u64cd\u4f5c\u5e76\u5728\u5b8c\u6210\u65f6\u53d1\u9001\u4e2d\u65ad\u4fe1\u53f7<\/li>\n<li>CPU \u68c0\u6d4b\u5230\u4e2d\u65ad\u4fe1\u53f7\u6682\u505c\u6b63\u5728\u5904\u7406\u7684\u7a0b\u5e8f\u8f6c\u800c\u5904\u7406\u4e2d\u65ad<\/li>\n<\/ol>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 99;\nflex-basis: 238px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/interrupt-process.png\" data-size=\"589x592\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/interrupt-process.png\"\nwidth=\"589\"\nheight=\"592\"\nloading=\"lazy\"\nalt=\"Interrupt process\">\n<\/a>\n<figcaption>Interrupt process<\/figcaption>\n<\/figure><\/p>\n<p>\u8fd9\u5c31\u662f\u6574\u4e2a\u786c\u4ef6\u4e2d\u65ad\u7684\u539f\u7406\uff0c\u4f46\u662f\u6211\u4eec\u8fd8\u9700\u8981\u8ba8\u8bba\u51e0\u4e2a\u7ec6\u8282\u95ee\u9898<\/p>\n<ul>\n<li>CPU \u5982\u4f55\u68c0\u6d4b\u4e2d\u65ad\u4fe1\u53f7<\/li>\n<li>CPU \u5982\u4f55\u5904\u7406\u4e0d\u540c\u7c7b\u578b\u7684\u4e2d\u65ad<\/li>\n<li>\u5982\u4f55\u51b3\u5b9a\u662f\u5426\u5ef6\u8fdf\u6267\u884c\u6216\u4f18\u5148\u6267\u884c\u67d0\u4e2a\u4e2d\u65ad<\/li>\n<\/ul>\n<p>\u4e3a\u4e86\u56de\u7b54\u4e0a\u9762 3 \u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u9996\u5148\u8981\u77e5\u9053\u4ec0\u4e48\u662f\u4e2d\u65ad\u4fe1\u53f7\u3002\u6bcf\u4e2a\u8bbe\u5907\u7684\u9a71\u52a8\u7a0b\u5e8f\u90fd\u63d0\u4f9b<strong>\u4e2d\u65ad\u670d\u52a1\u7a0b\u5e8f<\/strong>\uff08interrupt service routine\uff0cISR\uff09\u7528\u4e8e\u54cd\u5e94\u4e2d\u65ad\uff0c\u8fd9\u4e9b\u4e2d\u65ad\u670d\u52a1\u7a0b\u5e8f\u7684\u5730\u5740\u50a8\u5b58\u5728\u4e00\u4e2a\u88ab\u79f0\u4e3a<strong>\u4e2d\u65ad\u5411\u91cf<\/strong>\uff08interrupt vector\uff09\u7684\u6570\u7ec4\u4e2d\uff0c\u800c\u4e2d\u65ad\u4fe1\u53f7\u7ed9\u51fa\u4e86\u5bf9\u5e94\u8bbe\u5907\u7684\u4e2d\u65ad\u670d\u52a1\u7a0b\u5e8f\u5728\u4e2d\u65ad\u5411\u91cf\u4e2d\u7684\u7d22\u5f15\u3002<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5728\u5927\u591a\u6570\u7684\u64cd\u4f5c\u7cfb\u7edf\u4e2d\uff0c\u4e2d\u65ad\u5411\u91cf\u5e76\u4e0d\u76f4\u63a5\u50a8\u5b58\u4e2d\u65ad\u670d\u52a1\u7a0b\u5e8f\u7684\u5730\u5740\uff0c\u800c\u662f\u5b58\u50a8\u7740\u591a\u4e2a\u6570\u7ec4\u7684\u9996\u5730\u5740\uff0c\u6bcf\u4e2a\u6570\u7ec4\u4e2d\u5305\u542b\u4e00\u7c7b\u4e2d\u65ad\u5904\u7406\u7a0b\u5e8f\u7684\u5730\u5740\u3002CPU \u901a\u8fc7\u4e2d\u65ad\u4fe1\u53f7\u7684\u7d22\u5f15\u627e\u5230\u5bf9\u5e94\u7c7b\u522b\u7684\u6570\u7ec4\uff0c\u7136\u540e\u901a\u8fc7\u904d\u5386\u8be5\u6570\u7ec4\u6765\u627e\u5230\u76f8\u5e94\u7684\u5904\u7406\u7a0b\u5e8f\u3002\u8fd9\u79cd\u673a\u5236\u88ab\u79f0\u4e3a <strong>interrupt chaining<\/strong>\uff0c\u4e0b\u56fe\u662f Intel \u5904\u7406\u5668\u7684\u4e2d\u65ad\u5411\u91cf\u3002\n<\/div>\n<p><\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 116;\nflex-basis: 280px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/intel-interrupt-vector.png\" data-size=\"627x537\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/operating-system-principle-interrupt\/intel-interrupt-vector.png\"\nwidth=\"627\"\nheight=\"537\"\nloading=\"lazy\"\nalt=\"Intel interrupt vector\">\n<\/a>\n<figcaption>Intel interrupt vector<\/figcaption>\n<\/figure><\/p>\n<p>CPU \u786c\u4ef6\u6709\u88ab\u79f0\u4e3a<strong>\u4e2d\u65ad\u8bf7\u6c42\u7ebf<\/strong>\uff08interrupt-request line\uff09\u7684\u673a\u5236\uff0cCPU \u5728\u6267\u884c\u6bcf\u6761\u6307\u4ee4\u540e\u68c0\u6d4b\u5230\u8be5\u7ebf\u4e2d\u662f\u5426\u6709\u4e2d\u65ad\u4fe1\u53f7\uff0c\u5982\u679c\u6709\u5219\u4ee5\u8fd9\u4e2a\u4e2d\u65ad\u4fe1\u53f7\u4f5c\u4e3a\u7d22\u5f15\u4ece\u4e2d\u65ad\u5411\u91cf\u4e2d\u53d6\u51fa\u4e2d\u65ad\u670d\u52a1\u7a0b\u5e8f\u7684\u5730\u5740\uff0c\u7136\u540e\u53bb\u6267\u884c\u76f8\u5e94\u7684\u7a0b\u5e8f\u3002<\/p>\n<p>\u4e3a\u4e86\u89e3\u51b3\u7b2c 3 \u4e2a\u95ee\u9898\uff0c\u64cd\u4f5c\u7cfb\u7edf\u9700\u8981\u591a\u7ea7\u4e2d\u65ad\u673a\u5236\uff0c\u4ee5\u4fbf\u64cd\u4f5c\u7cfb\u7edf\u53ef\u4ee5\u533a\u5206\u9ad8\u4f18\u5148\u7ea7\u548c\u4f4e\u4f18\u5148\u7ea7\u4e2d\u65ad\uff0c\u5e76\u4e14\u53ef\u4ee5\u5bf9\u4e0d\u540c\u7d27\u6025\u7a0b\u5ea6\u7684\u4e2d\u65ad\u8fdb\u884c\u54cd\u5e94\u3002\u5927\u591a\u6570 CPU \u6709\u4e24\u4e2a\u4e2d\u65ad\u8bf7\u6c42\u7ebf\u3002\u4e00\u79cd\u662f<strong>\u4e0d\u53ef\u5c4f\u853d\u7684\u4e2d\u65ad<\/strong>\uff08nonmaskable interrupt\uff09\uff1a\u5b83\u88ab\u7528\u4e8e\u53ca\u65f6\u54cd\u5e94\u4e0d\u53ef\u6062\u590d\u7684\u9519\u8bef\u3002\u7b2c\u4e8c\u79cd\u662f<strong>\u53ef\u5c4f\u853d\u7684\u4e2d\u65ad<\/strong>\uff08maskable interrupt\uff09\uff1aCPU \u53ef\u4ee5\u901a\u8fc7\u4e0d\u540c\u4e2d\u65ad\u7684\u4f18\u5148\u7ea7\u51b3\u5b9a\u662f\u5426\u5ef6\u8fdf\u54cd\u5e94\u6216\u8005\u5148\u54cd\u5e94\u9ad8\u4f18\u5148\u7ea7\u4e2d\u65ad\u3002<\/p>\n<p>\u9664\u4e86\u786c\u4ef6\u4e2d\u65ad\u5916\u8fd8\u6709\u4e00\u79cd\u201c<strong>\u8f6f\u4e2d\u65ad<\/strong>\u201d\uff08Software interrupt\uff09\uff0c\u5b83\u901a\u5e38\u5728\u7a0b\u5e8f\u629b\u51fa\u5f02\u5e38\u4ee5\u53ca\u7cfb\u7edf\u8c03\u7528\u4e2d\u89e6\u53d1\u3002\u8f6f\u4e2d\u65ad\u76f8\u5173\u5185\u5bb9\u5728\u5185\u6838\u6001\u53ca\u7cfb\u7edf\u8c03\u7528\u4e2d\u4ecb\u7ecd\u3002<\/p>\n<div class=\"footnotes\" role=\"doc-endnotes\">\n<hr \/>\n<ol>\n<li id=\"fn:1\" role=\"doc-endnote\">\n<p>\u7ef4\u57fa\u767e\u79d1&#160;<a href=\"#fnref:1\" class=\"footnote-backref\" role=\"doc-backlink\">&#x21a9;&#xfe0e;<\/a><\/p>\n<\/li>\n<li id=\"fn:2\" role=\"doc-endnote\">\n<p>\u300aOperating System Concepts\u300b&#160;<a href=\"#fnref:2\" class=\"footnote-backref\" role=\"doc-backlink\">&#x21a9;&#xfe0e;<\/a><\/p>\n<\/li>\n<\/ol>\n<\/div>"},{"title":"php \u51e0\u79cd\u975e\u963b\u585e\u65b9\u5f0f\u5206\u6790","link":"https:\/\/blog.lv5.moe\/p\/analysis-of-several-nonblocking-modes-of-php","pubDate":"Sat, 02 Mar 2019 12:11:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/analysis-of-several-nonblocking-modes-of-php","description":"<p>\u672c\u6587\u4ecb\u7ecd\u4e86\u51e0\u79cd\u975e\u963b\u585e\u6267\u884c php \u4ee3\u7801\u7684\u65b9\u6cd5\uff0c\u5e76\u5206\u6790\u4ed6\u4eec\u7684\u6027\u80fd\u4e0e\u9002\u7528\u73af\u5883<\/p>\n<p>\u672c\u6587\u7528\u5982\u4e0b\u4ee3\u7801\u6765\u6d4b\u8bd5\u8fd9\u51e0\u79cd\u975e\u963b\u585e\u5b9e\u73b0\u7684\u6027\u80fd\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ 1.php:\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"nv\">$stime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$stime<\/span> <span class=\"o\">.=<\/span> <span class=\"nx\">PHP_EOL<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u6267\u884c\u975e\u963b\u585e\u903b\u8f91\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"nx\">file_put_contents<\/span><span class=\"p\">(<\/span><span class=\"no\">__DIR__<\/span> <span class=\"o\">.<\/span> <span class=\"s1\">&#39;\/debug.log&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;stime\uff1a&#39;<\/span> <span class=\"o\">.<\/span> <span class=\"nv\">$stime<\/span><span class=\"p\">,<\/span> <span class=\"nx\">FILE_APPEND<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ 2.php:\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u6a21\u62df\u8017\u65f6\u64cd\u4f5c\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"nx\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$etime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$etime<\/span> <span class=\"o\">.=<\/span> <span class=\"nx\">PHP_EOL<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">file_put_contents<\/span><span class=\"p\">(<\/span><span class=\"no\">__DIR__<\/span> <span class=\"o\">.<\/span> <span class=\"s1\">&#39;\/debug.log&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;etime\uff1a&#39;<\/span> <span class=\"o\">.<\/span> <span class=\"nv\">$etime<\/span><span class=\"p\">,<\/span> <span class=\"nx\">FILE_APPEND<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"curl\">curl<\/h2>\n<p>\u5229\u7528 php curl \u51fd\u6570\u8bbe\u7f6e\u4e00\u4e2a\u8f83\u5c0f\u7684 timeout\uff0c\u6765\u95f4\u63a5\u8fbe\u6210\u975e\u963b\u585e\u3002\u8fd9\u79cd\u65b9\u6cd5\u4f1a\u4e3b\u52a8\u65ad\u5f00\u8fde\u63a5\uff0c\u6240\u4ee5\u5bf9\u4e8e\u6709\u8fd9\u65b9\u9762\u9650\u5236\u7684 api \u662f\u4e0d\u9002\u7528\u7684<\/p>\n<h3 id=\"curlopt_timeout\">CURLOPT_TIMEOUT<\/h3>\n<p>\u8f83\u8001\u7684 curl \u62d3\u5c55\u53ea\u652f\u6301 <code>CURLOPT_TIMEOUT<\/code> \u8fd9\u4e2a\u53c2\u6570\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e timeout \u4e3a 1s<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">function<\/span> <span class=\"nf\">curl<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$ch<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">curl_init<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_URL<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;127.0.0.1\/aaa.php&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_RETURNTRANSFER<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_TIMEOUT<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ \u4e00\u79d2\u540e\u5173\u95ed\u8fde\u63a5\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_HEADER<\/span><span class=\"p\">,<\/span> <span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_exec<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_close<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">3.002<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">3.001<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.9951<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"curlopt_timeout_ms\">CURLOPT_TIMEOUT_MS<\/h3>\n<p>\u8fd9\u4e2a\u53c2\u6570\u5728 curl 7.16.2 \u4e2d\u88ab\u52a0\u5165\uff0c\u7528\u4e8e\u8bbe\u7f6e\u6beb\u79d2\u7ea7\u7684 timeout<\/p>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5982\u679c libcurl \u7f16\u8bd1\u65f6\u4f7f\u7528\u7cfb\u7edf\u6807\u51c6\u7684\u540d\u79f0\u89e3\u6790\u5668\uff08 standard system name resolver\uff09\uff0c\u90a3\u90e8\u5206\u7684\u8fde\u63a5\u4ecd\u65e7\u4f7f\u7528\u4ee5\u79d2\u8ba1\u7684\u8d85\u65f6\u89e3\u51b3\u65b9\u6848\uff0c\u6700\u5c0f\u8d85\u65f6\u65f6\u95f4\u8fd8\u662f\u4e00\u79d2\u949f\n<\/div>\n<p><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">function<\/span> <span class=\"nf\">curl<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$ch<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">curl_init<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_URL<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;127.0.0.1\/aaa.php&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_RETURNTRANSFER<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_TIMEOUT_MS<\/span><span class=\"p\">,<\/span> <span class=\"mi\">10<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ 10 \u6beb\u79d2\u540e\u5173\u95ed\u8fde\u63a5\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_HEADER<\/span><span class=\"p\">,<\/span> <span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_exec<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_close<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0141<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0043<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0127<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"curl_multi\">curl_multi<\/h2>\n<p>\u5229\u7528 cURL \u4e2d\u7684 <code>curl_multi_*<\/code> \u51fd\u6570\u53d1\u9001\u5f02\u6b65\u8bf7\u6c42\uff0c\u5e76\u4e14\u53ef\u4ee5\u5e76\u53d1\u8bf7\u6c42<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">function<\/span> <span class=\"nf\">curl_multi<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$mh<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">curl_multi_init<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$ch<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">curl_init<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_setopt<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">,<\/span> <span class=\"nx\">CURLOPT_URL<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;127.0.0.1\/aaa.php&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_multi_add_handle<\/span><span class=\"p\">(<\/span><span class=\"nv\">$mh<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_multi_exec<\/span><span class=\"p\">(<\/span><span class=\"nv\">$mh<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$active<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_close<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_multi_remove_handle<\/span><span class=\"p\">(<\/span><span class=\"nv\">$mh<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$ch<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">curl_multi_close<\/span><span class=\"p\">(<\/span><span class=\"nv\">$mh<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0134<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0226<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0157<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"fsocketopen-\u6216-stream_socket_client\">fsocketopen \u6216 stream_socket_client<\/h2>\n<p>\u7528 <code>fsocketopen()<\/code> \u6253\u5f00\u4e00\u4e2a\u8fde\u63a5\uff0c\u7136\u540e\u7528 <code>stream_set_blocking()<\/code> \u8bbe\u7f6e\u975e\u963b\u585e\u6a21\u5f0f<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">function<\/span> <span class=\"nf\">sock<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$fp<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">fsockopen<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;127.0.0.1&#39;<\/span><span class=\"p\">,<\/span> <span class=\"mi\">80<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$error_code<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$error_msg<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nv\">$fp<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"k\">array<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;error_code&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nv\">$error_code<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;error_msg&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nv\">$error_msg<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">stream_set_blocking<\/span><span class=\"p\">(<\/span><span class=\"nv\">$fp<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$header<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">&#34;GET \/aaa.php HTTP\/1.1<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s2\">&#34;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$header<\/span> <span class=\"o\">.=<\/span> <span class=\"s2\">&#34;Host: 127.0.0.1<\/span><span class=\"se\">\\r\\n<\/span><span class=\"s2\">&#34;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$header<\/span> <span class=\"o\">.=<\/span> <span class=\"s2\">&#34;Connection: close<\/span><span class=\"se\">\\r\\n\\r\\n<\/span><span class=\"s2\">&#34;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">fwrite<\/span><span class=\"p\">(<\/span><span class=\"nv\">$fp<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$header<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">fclose<\/span><span class=\"p\">(<\/span><span class=\"nv\">$fp<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"k\">array<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;error_code&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0348<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0142<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.0149<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"fastcgi_finish_request\">fastcgi_finish_request<\/h2>\n<p>\u8fd9\u4e2a\u51fd\u6570\u53ef\u4ee5\u8fd4\u56de\u7f13\u51b2\u533a\u5185\u7684\u6240\u6709\u54cd\u5e94\u7684\u6570\u636e\u7ed9\u5ba2\u6237\u7aef\u5e76\u7ed3\u675f\u8bf7\u6c42\uff0c\u4f46\u662f\u4ecd\u7ee7\u7eed\u8fd0\u884c\u5f53\u524d\u811a\u672c\u76f4\u5230\u8fd0\u884c\u5b8c\u6210\u6216\u8005\u8fbe\u5230 timeout\u3002\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u5728\u8017\u65f6\u64cd\u4f5c\u524d\u4f7f\u7528\u8be5\u51fd\u6570\u4ee5\u5b9e\u73b0\u975e\u963b\u585e<\/p>\n<p>\u6ce8\u610f\uff1a<\/p>\n<ol>\n<li>\u867d\u7136\u8fd9\u4e2a\u51fd\u6570\u53eb fastcgi \u4f46\u662f\u8fd9\u662f\u4e2a\u5b9e\u5b9e\u5728\u5728\u7684 FPM \u51fd\u6570\uff0c\u9700\u8981\u5728 FPM \u73af\u5883\u4e0b\u8c03\u7528<\/li>\n<li>\u4f7f\u7528\u8be5\u51fd\u6570\u540e\uff0c\u8fd9\u4e2a\u811a\u672c\u5c06\u5360\u7528\u4e00\u4e2a FPM \u8fdb\u7a0b\uff0c\u6240\u4ee5\u5982\u679c\u5bf9\u9ad8\u8017\u65f6\u811a\u672c\u6ee5\u7528\u6b64\u51fd\u6570\u4f1a\u5bfc\u81f4 502 bad gateway<\/li>\n<li>\u4f7f\u7528\u8fd9\u4e2a\u51fd\u6570\u4f1a\u7ed9\u5f53\u524d session \u52a0\u9501\uff0c\u5982\u4e0d\u9700\u8981\u4fee\u6539 session \u63a8\u8350\u4f7f\u7528 <code>session_write_close()<\/code> \u89e3\u9664\u5360\u7528<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$stime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">PHP_SAPI<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;fpm-fcgi&#39;<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">function_exists<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;fastcgi_finish_request&#39;<\/span><span class=\"p\">))<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">fastcgi_finish_request<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$etime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$etime<\/span> <span class=\"o\">.=<\/span> <span class=\"nx\">PHP_EOL<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">file_put_contents<\/span><span class=\"p\">(<\/span><span class=\"no\">__DIR__<\/span> <span class=\"o\">.<\/span> <span class=\"s1\">&#39;\/debugtest.log&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$stime<\/span> <span class=\"o\">-<\/span> <span class=\"nv\">$etime<\/span><span class=\"p\">,<\/span> <span class=\"nx\">FILE_APPEND<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.00048<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.00043<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.00042<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h2 id=\"pcntl_fork\">pcntl_fork<\/h2>\n<p>\u7528 <code>pcntl_fork<\/code> \u521b\u5efa\u5b50\u8fdb\u7a0b\u7684\u65b9\u5f0f\u5b9e\u73b0\u771f\u6b63\u7684\u5f02\u6b65\uff0c\u8fd9\u4e2a\u51fd\u6570\u7531 pcntl \u6269\u5c55\u63d0\u4f9b\u3002<br \/>\n\u4e3a\u4e86\u9632\u6b62\u5b50\u8fdb\u7a0b\u53d8\u6210\u50f5\u5c38\u8fdb\u7a0b\uff0c\u5728\u7236\u8fdb\u7a0b\u4f7f\u7528 <code>pcntl_wait<\/code> \u7b49\u5f85\u5b50\u8fdb\u7a0b\u8fd4\u56de\u5e76\u56de\u6536\u8d44\u6e90<br \/>\n\u6211\u8fd9\u91cc\u91c7\u7528\u4e86\u4e8c\u6b21 fork \u7684\u65b9\u5f0f\uff0c\u8ba9\u7b2c\u4e00\u6b21 fork \u51fa\u7684\u5b50\u8fdb\u7a0b a \u518d fork \u51fa\u5b9e\u9645\u7684\u5de5\u4f5c\u8fdb\u7a0b b\uff0c\u8ba9 a \u5148\u884c\u9000\u51fa\uff0c\u4f7f\u5f97 b \u6210\u4e3a\u5b64\u513f\u8fdb\u7a0b\uff0c\u88ab init \u8fdb\u7a0b\u6258\u7ba1\u3002\u8fd9\u6837\u5b9e\u73b0\u4e86\u7236\u8fdb\u7a0b\u975e\u963b\u585e\uff0c\u800c\u4e14\u5b50\u8fdb\u7a0b\u4e0d\u4f1a\u6210\u4e3a\u50f5\u5c38\u8fdb\u7a0b\u3002<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">class<\/span> <span class=\"nc\">Arrow<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">static<\/span> <span class=\"nv\">$instance<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">public<\/span> <span class=\"k\">static<\/span> <span class=\"k\">function<\/span> <span class=\"nf\">getInstance<\/span><span class=\"p\">()<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"k\">null<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">self<\/span><span class=\"o\">::<\/span><span class=\"nv\">$instance<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">self<\/span><span class=\"o\">::<\/span><span class=\"nv\">$instance<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">self<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">return<\/span> <span class=\"nx\">self<\/span><span class=\"o\">::<\/span><span class=\"nv\">$instance<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">public<\/span> <span class=\"k\">function<\/span> <span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"nv\">$rb<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">cli_set_process_title<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;process_a&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$pid<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">pcntl_fork<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$pid<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">pcntl_wait<\/span><span class=\"p\">(<\/span><span class=\"nv\">$status<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">elseif<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$pid<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$cid<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">pcntl_fork<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$cid<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">cli_set_process_title<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;process_b&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">exit<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">elseif<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$cid<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">cli_set_process_title<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;process_c&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$rb<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">exit<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">exit<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$stime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$stime<\/span> <span class=\"o\">.=<\/span> <span class=\"nx\">PHP_EOL<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">Arrow<\/span><span class=\"o\">::<\/span><span class=\"na\">getInstance<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">run<\/span><span class=\"p\">(<\/span><span class=\"k\">function<\/span> <span class=\"p\">()<\/span> <span class=\"k\">use<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$stime<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">sleep<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$etime<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">microtime<\/span><span class=\"p\">(<\/span><span class=\"k\">true<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nv\">$etime<\/span> <span class=\"o\">.=<\/span> <span class=\"nx\">PHP_EOL<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nx\">file_put_contents<\/span><span class=\"p\">(<\/span><span class=\"no\">__DIR__<\/span> <span class=\"o\">.<\/span> <span class=\"s1\">&#39;\/debug.log&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$stime<\/span> <span class=\"o\">-<\/span> <span class=\"nv\">$etime<\/span><span class=\"p\">,<\/span> <span class=\"nx\">FILE_APPEND<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">});<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">output<\/span><span class=\"o\">:<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.023<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.004<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"mf\">2.010<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u6211\u4eec\u7528 <code>ps ax<\/code> \u67e5\u770b\u4e00\u4e0b\u8fdb\u7a0b\uff1a<br \/>\nTTY \u4e3a ? \u7684\u8fdb\u7a0b\u5373\u4e3a\u4e0e\u7ec8\u7aef\u65e0\u5173\uff0c\u662f\u5b88\u62a4\u8fdb\u7a0b\uff08daemon\uff09<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">ps ax <span class=\"p\">|<\/span> grep -v grep <span class=\"p\">|<\/span> grep -E <span class=\"s1\">&#39;process_|PID&#39;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> PID TTY STAT TIME COMMAND\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"m\">7750<\/span> ? S 0:00 process_c\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Laravel \u5f00\u53d1\u51c6\u5907\u5de5\u4f5c","link":"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development","pubDate":"Sat, 23 Feb 2019 23:24:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development","description":"<p>\u56e0\u4e3a\u67d0\u4e9b\u539f\u56e0\u9700\u8981\u641e\u4e2a laravel \u9879\u76ee\uff0c\u4e8e\u662f\u4e4e\u7ffb\u51fa\u6b64\u524d\u7684\u6587\u7ae0\u8865\u5145\u8bb0\u5f55\u4e0b laravel \u5f00\u53d1\u51c6\u5907\u5de5\u4f5c\u3002<\/p>\n<p>\u672c\u6559\u7a0b\u9002\u7528\u73af\u5883\uff1a<\/p>\n<ul>\n<li><a class=\"link\" href=\"https:\/\/laravel.com\/\" target=\"_blank\" rel=\"noopener\"\n>Laravel 5.5<\/a><\/li>\n<li><a class=\"link\" href=\"https:\/\/www.jetbrains.com\/phpstorm\/\" target=\"_blank\" rel=\"noopener\"\n>PhpStorm<\/a><\/li>\n<\/ul>\n<h2 id=\"\u5b89\u88c5-laravel\">\u5b89\u88c5 laravel<\/h2>\n<ul>\n<li>\u5b89\u88c5 php<\/li>\n<li>\u5b89\u88c5 composer<\/li>\n<li>\u6362\u6e90\uff1a<code>composer config -g repo.packagist composer https:\/\/packagist.laravel-china.org<\/code><\/li>\n<li>\u5168\u5c40\u5b89\u88c5 <code>laravel\/installer<\/code>\uff1a<code>composer global require laravel\/installer<\/code><\/li>\n<li>\u521b\u5efa laravel \u9879\u76ee\uff1a<code>laravel new blog<\/code><\/li>\n<\/ul>\n<h2 id=\"\u5b89\u88c5-laravel-ide-helper\">\u5b89\u88c5 laravel-ide-helper<\/h2>\n<p>Laravel \u672c\u8eab\u7684\u4f9d\u8d56\u6ce8\u5165\uff0c\u670d\u52a1\u63d0\u4f9b\u8005\u7b49\u7279\u6027\u4f7f\u5f97 IDE \u5f88\u96be\u505a\u5230\u4ee3\u7801\u68c0\u67e5\u548c\u667a\u80fd\u63d0\u793a\uff0c\u6240\u4ee5\u9700\u8981\u5b89\u88c5 <a class=\"link\" href=\"https:\/\/github.com\/barryvdh\/laravel-ide-helper\" target=\"_blank\" rel=\"noopener\"\n>barryvdh\/laravel-ide-helper<\/a> \u6765\u8f85\u52a9\u8fdb\u884c\u4ee3\u7801\u8865\u5168\u548c\u8ffd\u8e2a\u3002<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">composer require --dev barryvdh\/laravel-ide-helper\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u8fd0\u884c\u4e0b\u5217\u4ee3\u7801\u547d\u4ee4\u751f\u6210\u4ee3\u7801\u63d0\u793a\u6587\u4ef6\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">php artisan ide-helper:generate\n<\/span><\/span><span class=\"line\"><span class=\"cl\">php artisan ide-helper:meta\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f60\u53ef\u4ee5\u8bbe\u7f6e <code>composer.json<\/code> \u4f7f\u6bcf\u6b21\u81ea\u52a8\u66f4\u65b0\u540e\u91cd\u65b0\u751f\u6210\u4ee3\u7801\u63d0\u793a\u6587\u4ef6\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-json\" data-lang=\"json\"><span class=\"line\"><span class=\"cl\"><span class=\"s2\">&#34;scripts&#34;<\/span><span class=\"err\">:<\/span><span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">&#34;post-update-cmd&#34;<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"s2\">&#34;Illuminate\\\\Foundation\\\\ComposerScripts::postUpdate&#34;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"s2\">&#34;php artisan ide-helper:generate&#34;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"s2\">&#34;php artisan ide-helper:meta&#34;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">]<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u53ef\u9009\u8bbe\u7f6e\u9879\">\u53ef\u9009\u8bbe\u7f6e\u9879\uff1a<\/h3>\n<ol>\n<li>\n<p>\u6dfb\u52a0\u5bf9 migration \u7684\u4ee3\u7801\u63d0\u793a\u7684\u652f\u6301\uff1a<\/p>\n<p>\u53d1\u5e03\u914d\u7f6e\u6587\u4ef6 <code>config\/ide-helper.php<\/code><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">php artisan vendor:publish --provider<span class=\"o\">=<\/span><span class=\"s2\">&#34;Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider&#34;<\/span> --tag<span class=\"o\">=<\/span>config\n<\/span><\/span><\/code><\/pre><\/div><p>\u66f4\u6539 <code>include_fluent<\/code> \u8bbe\u7f6e<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;include_fluent&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">true<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u7136\u540e\u91cd\u65b0\u751f\u6210\u4ee3\u7801\u63d0\u793a\u6587\u4ef6<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">php artisan ide-helper:generate\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u6dfb\u52a0\u5bf9 Model \u7684\u4ee3\u7801\u63d0\u793a\u7684\u652f\u6301\uff1a<\/p>\n<p>\u8fd9\u91cc\u4f7f\u7528 <strong>@mixin<\/strong> \u6ce8\u89e3\u6765\u6807\u6ce8\u6587\u6863<\/p>\n<blockquote>\n<p>PhpStorm interprets <em>@mixin<\/em> regardless of PHP version just the same way it interprets \u201c<em>use trait<\/em>\u201d (see <a class=\"link\" href=\"http:\/\/youtrack.jetbrains.com\/issue\/WI-1730\" target=\"_blank\" rel=\"noopener\"\n>WI-1730<\/a> for details)<\/p>\n<\/blockquote>\n<p>\u5728\u4f60\u7684\u6a21\u578b\u7c7b\u6216\u8005 <code>Illuminate\\Database\\Eloquent\\Model<\/code> \u524d\u52a0\u4e0a <code>\/** @mixin \\Eloquent *\/<\/code><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"> <span class=\"k\">namespace<\/span> <span class=\"nx\">Illuminate\\Database\\Eloquent<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">use<\/span> <span class=\"o\">...<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"sd\">\/** @mixin \\Eloquent *\/<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"k\">abstract<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Model<\/span> <span class=\"k\">implements<\/span> <span class=\"nx\">ArrayAccess<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Arrayable<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Jsonable<\/span><span class=\"p\">,<\/span> <span class=\"nx\">JsonSerializable<\/span><span class=\"p\">,<\/span> <span class=\"nx\">QueueableEntity<\/span><span class=\"p\">,<\/span> <span class=\"nx\">UrlRoutable<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">{<\/span> <span class=\"o\">...<\/span> <span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<\/ol>\n<h2 id=\"\u5b89\u88c5-laravel-plugin\">\u5b89\u88c5 Laravel Plugin<\/h2>\n<p><a class=\"link\" href=\"https:\/\/plugins.jetbrains.com\/plugin\/7532-laravel-plugin\" target=\"_blank\" rel=\"noopener\"\n>Laravel Plugin<\/a> \u662f\u4e00\u4e2a\u589e\u5f3a PhpStorm \u5bf9 Laravel \u652f\u6301\u7684\u63d2\u4ef6\uff0c\u529f\u80fd\u622a\u56fe\u5982\u4e0b\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 123;\nflex-basis: 297px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development\/screenshot1.png\" data-size=\"573x463\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development\/screenshot1.png\"\nwidth=\"573\"\nheight=\"463\"\nloading=\"lazy\"\nalt=\"\u529f\u80fd\u622a\u56fe1\">\n<\/a>\n<figcaption>\u529f\u80fd\u622a\u56fe1<\/figcaption>\n<\/figure><br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 123;\nflex-basis: 297px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development\/screenshot1.png\" data-size=\"573x463\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/preparations-for-laravel-development\/screenshot1.png\"\nwidth=\"573\"\nheight=\"463\"\nloading=\"lazy\"\nalt=\"\u529f\u80fd\u622a\u56fe2\">\n<\/a>\n<figcaption>\u529f\u80fd\u622a\u56fe2<\/figcaption>\n<\/figure><\/p>\n<p>\u6b64\u63d2\u4ef6\u4f9d\u8d56\u4e8e <a class=\"link\" href=\"https:\/\/github.com\/barryvdh\/laravel-ide-helper\" target=\"_blank\" rel=\"noopener\"\n>barryvdh\/laravel-ide-helper<\/a><\/p>\n<p>\u5728 <code>Settings &gt; Plugins<\/code> \u4e2d\u641c\u7d22 <strong>Laravel Plugin<\/strong> \u8fdb\u884c\u5b89\u88c5<\/p>\n<h2 id=\"\u672c\u5730\u5316\">\u672c\u5730\u5316<\/h2>\n<h3 id=\"\u751f\u6210-application-key\">\u751f\u6210 Application Key<\/h3>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">php artisan key:generate\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u4fee\u6539\u65f6\u533a\">\u4fee\u6539\u65f6\u533a<\/h3>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ config\/app.php\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"s1\">&#39;timezone&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;Asia\/Shanghai&#39;<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5b89\u88c5\u8bed\u8a00\u5305\">\u5b89\u88c5\u8bed\u8a00\u5305<\/h3>\n<p>\u5b89\u88c5 <a class=\"link\" href=\"https:\/\/github.com\/overtrue\/laravel-lang\" target=\"_blank\" rel=\"noopener\"\n>overtrue\/laravel-lang<\/a> :<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">composer require --dev overtrue\/laravel-lang\n<\/span><\/span><\/code><\/pre><\/div><p>\u5c06 <code>config\/app.php<\/code> \u4e2d<\/p>\n<p><code>Illuminate\\Translation\\TranslationServiceProvider::class<\/code><\/p>\n<p>\u66ff\u6362\u4e3a<\/p>\n<p><code>Overtrue\\LaravelLang\\TranslationServiceProvider::class<\/code><\/p>\n<p>\u5e76\u4fee\u6539 <code>locale<\/code><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;locale&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;zh-CN&#39;<\/span>\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Typecho \u8ffd\u756a\u5217\u8868\u63d2\u4ef6","link":"https:\/\/blog.lv5.moe\/p\/typecho-anime-list-plugin","pubDate":"Mon, 18 Feb 2019 21:31:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/typecho-anime-list-plugin","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/typecho-anime-list-plugin\/typecho-anime-list-plugin.png\" alt=\"Featured image of post Typecho \u8ffd\u756a\u5217\u8868\u63d2\u4ef6\" \/><h2 id=\"\u9879\u76ee\u4ecb\u7ecd\">\u9879\u76ee\u4ecb\u7ecd<\/h2>\n<p>Bangumi \u8ffd\u756a\u5217\u8868\u63d2\u4ef6 Typecho \u7248<\/p>\n<p>\u4f7f\u7528\u77ed\u4ee3\u7801 <code>[bangumi]<\/code> \u5728\u4efb\u4f55\u4f4d\u7f6e\u63d2\u5165\u4f60\u7684 Bangumi \u8ffd\u756a\u5217\u8868<\/p>\n<p>\u63d2\u4ef6\u6548\u679c\u89c1\u6b64\u5904\uff1ahttps:\/\/blog.sspirits.top\/about<\/p>\n<p>GitHub \u4ed3\u5e93\uff1a<a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/BangumiList\" target=\"_blank\" rel=\"noopener\"\n>ShadowySpirits\/BangumiList<\/a><\/p>\n<h2 id=\"\u4f7f\u7528\u65b9\u6cd5\">\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u5728 <a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/BangumiList\/releases\" target=\"_blank\" rel=\"noopener\"\n>Release<\/a> \u4e2d\u4e0b\u8f7d\u6b64\u63d2\u4ef6\u7684\u6700\u65b0\u7248\uff0c\u4e0a\u4f20\u81f3\u7f51\u7ad9\u7684 \/usr\/plugins \u76ee\u5f55\u4e0b\uff1b<\/li>\n<li>\u542f\u7528\u8be5\u63d2\u4ef6\uff0c\u6b63\u786e\u586b\u5199\u76f8\u5173\u4fe1\u606f\u3002<\/li>\n<li>\u5728\u4f60\u60f3\u5c55\u793a\u7684\u4f4d\u7f6e\u63d2\u5165\u77ed\u4ee3\u7801 <code>[bangumi]<\/code><\/li>\n<\/ol>"},{"title":"Typecho \u8bc4\u8bba SMTP\u3001Mailgun \u90ae\u4ef6\u901a\u77e5\u63d2\u4ef6","link":"https:\/\/blog.lv5.moe\/p\/typecho-comments-smtp-mailgun-mail-notification-plugin","pubDate":"Mon, 18 Feb 2019 21:08:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/typecho-comments-smtp-mailgun-mail-notification-plugin","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/typecho-comments-smtp-mailgun-mail-notification-plugin\/mail_screenshot.png\" alt=\"Featured image of post Typecho \u8bc4\u8bba SMTP\u3001Mailgun \u90ae\u4ef6\u901a\u77e5\u63d2\u4ef6\" \/><h2 id=\"\u63d2\u4ef6\u7b80\u4ecb\">\u63d2\u4ef6\u7b80\u4ecb<\/h2>\n<p>Comment2Mail \u662f Typecho \u8bc4\u8bba\u90ae\u4ef6\u901a\u77e5\u63d2\u4ef6\uff0c\u652f\u6301 SMTP\u3001Mailgun \u4e24\u79cd\u63a5\u53e3\uff0c\u5176\u4e2d SMTP \u63a5\u53e3\u91c7\u7528\u975e\u963b\u585e\u65b9\u5f0f\u53d1\u9001\u90ae\u4ef6<\/p>\n<p>\u5728\u8bc4\u8bba\u5ba1\u6838\u901a\u8fc7\u3001\u7528\u6237\u8bc4\u8bba\u6587\u7ae0\u3001\u7528\u6237\u8bc4\u8bba\u88ab\u56de\u590d\u65f6\u53d1\u9001\u90ae\u4ef6\u901a\u77e5<\/p>\n<p>\u8be6\u89c1 GitHub\uff1a<a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/Comment2Mail\" target=\"_blank\" rel=\"noopener\"\n>ShadowySpirits\/Comment2Mail<\/a><\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 150;\nflex-basis: 362px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/typecho-comments-smtp-mailgun-mail-notification-plugin\/mail_screenshot.png\" data-size=\"1041x690\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/typecho-comments-smtp-mailgun-mail-notification-plugin\/mail_screenshot.png\"\nwidth=\"1041\"\nheight=\"690\"\nloading=\"lazy\"\nalt=\"\u90ae\u4ef6\u6a21\u677f\">\n<\/a>\n<figcaption>\u90ae\u4ef6\u6a21\u677f<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u5b89\u88c5\u65b9\u6cd5\">\u5b89\u88c5\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u81f3 <a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/Comment2Mail\/releases\" target=\"_blank\" rel=\"noopener\"\n>Releases<\/a> \u4e2d\u4e0b\u8f7d\u6700\u65b0\u7248\u672c\u63d2\u4ef6\uff0c\u4e0a\u4f20\u81f3\u7f51\u7ad9\u7684 \/usr\/plugins\/ \u76ee\u5f55\u4e0b<\/li>\n<li>\u542f\u7528\u8be5\u63d2\u4ef6\uff0c\u6b63\u786e\u586b\u5199\u76f8\u5173\u4fe1\u606f<\/li>\n<\/ol>\n<h2 id=\"\u9e23\u8c22\">\u9e23\u8c22<\/h2>\n<p>\u672c\u63d2\u4ef6\u6a21\u677f\u53c2\u8003\u81ea <a class=\"link\" href=\"https:\/\/github.com\/ylqjgm\/LoveKKComment\" target=\"_blank\" rel=\"noopener\"\n>ylqjgm\/LoveKKComment<\/a><\/p>"},{"title":"KMS \u6fc0\u6d3b Windows \u548c Office","link":"https:\/\/blog.lv5.moe\/p\/kms-activates-windows-and-office","pubDate":"Sun, 17 Feb 2019 19:38:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/kms-activates-windows-and-office","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/kms-activates-windows-and-office\/active-success.jpg\" alt=\"Featured image of post KMS \u6fc0\u6d3b Windows \u548c Office\" \/><p><\/p>\n<div class=\"tip inlineBlock info\">\nkms \u6fc0\u6d3b\u9002\u7528\u4e8e\u6279\u91cf\u6388\u6743\u7248\u672c\uff0c\u5373 VL \u7248\u7684 Windows \u548c Office\n<\/div>\n<p><\/p>\n<h2 id=\"\u4f7f\u7528\u65b9\u6cd5\">\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<p>\u4ee5<strong>\u7ba1\u7406\u5458<\/strong>\u8eab\u4efd\u5f00\u542f\u4e00\u4e2a CMD \u7a97\u53e3<\/p>\n<h3 id=\"windows\">Windows<\/h3>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">slmgr.vbs -ipk &lt;windows-GVLK-key&gt;\n<\/span><\/span><span class=\"line\"><span class=\"cl\">slmgr.vbs -skms &lt;kms-server&gt;\n<\/span><\/span><span class=\"line\"><span class=\"cl\">slmgr.vbs -ato\n<\/span><\/span><\/code><\/pre><\/div><p><a class=\"link\" href=\"https:\/\/github.com\/SystemRage\/py-kms\/wiki\/Windows-GVLK-Keys\" target=\"_blank\" rel=\"noopener\"\n>\u5404\u7248\u672c\u7684 Windows GVLK Keys<\/a><\/p>\n<h3 id=\"office\">Office<\/h3>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"nb\">cd<\/span> &lt;your-office-dir&gt;\n<\/span><\/span><span class=\"line\"><span class=\"cl\">cscript ospp.vbs \/inpkey:&lt;office-GVLK-key&gt;\n<\/span><\/span><span class=\"line\"><span class=\"cl\">cscript ospp.vbs \/sethst:&lt;kms-server&gt;\n<\/span><\/span><span class=\"line\"><span class=\"cl\">cscript ospp.vbs \/act\n<\/span><\/span><\/code><\/pre><\/div><p><a class=\"link\" href=\"https:\/\/github.com\/SystemRage\/py-kms\/wiki\/Office-GVLK-Keys\" target=\"_blank\" rel=\"noopener\"\n>\u5404\u7248\u672c\u7684 Office GVLK Keys<\/a><\/p>\n<p>\u6fc0\u6d3b\u6210\u529f\u4f1a\u770b\u5230\u8fd9\u6837\u7684\u63d0\u793a\uff1a<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 180;\nflex-basis: 434px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/kms-activates-windows-and-office\/active-success.jpg\" data-size=\"340x188\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/kms-activates-windows-and-office\/active-success.jpg\"\nwidth=\"340\"\nheight=\"188\"\nloading=\"lazy\"\nalt=\"active success\">\n<\/a>\n<figcaption>active success<\/figcaption>\n<\/figure><\/p>\n<p>\u8fc7\u671f\u65f6\u95f4\u53ef\u4ee5\u4f7f\u7528 <code>slmgr.vbs -xpr<\/code> \u67e5\u8be2<\/p>"},{"title":"Nextcloud15 \u4f18\u5316\u5fc3\u5f97","link":"https:\/\/blog.lv5.moe\/p\/nextcloud-15-optimization-experience","pubDate":"Sun, 17 Feb 2019 12:07:16 +0800","guid":"https:\/\/blog.lv5.moe\/p\/nextcloud-15-optimization-experience","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/nextcloud-15-optimization-experience\/nextcloud.jpg\" alt=\"Featured image of post Nextcloud15 \u4f18\u5316\u5fc3\u5f97\" \/><p>\u6700\u8fd1\u62bd\u7a7a\u628a Nextcloud \u4ece 14 \u5347\u7ea7\u5230 15\uff0c\u8fd9\u91cc\u8bb0\u5f55\u4e00\u4e0b\u5347\u7ea7\u6d41\u7a0b\u548c\u4f18\u5316\u5fc3\u5f97<\/p>\n<h2 id=\"nextcloud15-\u529f\u80fd\u66f4\u65b0\">Nextcloud15 \u529f\u80fd\u66f4\u65b0<\/h2>\n<p>\u8fd9\u91cc\u5217\u51fa\u51e0\u4e2a\u66f4\u65b0\u7684\u529f\u80fd\uff0c\u7ed9\u89c2\u671b\u7684\u670b\u53cb\u4eec\u505a\u4e2a\u53c2\u8003<\/p>\n<ul>\n<li>\u5168\u6587\u641c\u7d22<\/li>\n<li>\u5de5\u4f5c\u6d41\uff1a\u6587\u6863\u81ea\u52a8\u8f6c PDF\uff0c\u81ea\u52a8\u6267\u884c shell \u547d\u4ee4<\/li>\n<li>\u5206\u4eab\u529f\u80fd\u5347\u7ea7\uff1a\u73b0\u5728\u4e00\u4e2a\u6587\u4ef6\u53ef\u4ee5\u521b\u5efa\u591a\u4e2a\u5206\u4eab\u94fe\u63a5\u3001\u53ef\u4ee5\u5206\u4eab\u53ea\u8bfb\u6587\u4ef6<\/li>\n<li>\u534f\u4f5c\u529f\u80fd\u52a0\u5f3a<\/li>\n<li>2-3x loading \u901f\u5ea6\u63d0\u5347<\/li>\n<\/ul>\n<h2 id=\"\u5347\u7ea7\u6d41\u7a0b\">\u5347\u7ea7\u6d41\u7a0b<\/h2>\n<p>\u56e0\u4e3a Nextcloud14 \u65e0\u6cd5\u76f4\u63a5\u5347\u7ea7\u5230 15\uff0c\u6240\u4ee5\u6211\u91c7\u7528\u5168\u65b0\u5b89\u88c5\u7684\u65b9\u5f0f\u3002\u5b89\u88c5\u5b8c\u6210\u540e\u7528\u5907\u4efd\u6062\u590d\u6570\u636e\u3002\u8be6\u7ec6\u6d41\u7a0b\u53ef\u4ee5\u53c2\u7167\u6587\u6863\u4e2d\u7684 <a class=\"link\" href=\"https:\/\/docs.nextcloud.com\/server\/15\/admin_manual\/maintenance\/migrating.html#migrating-to-a-different-server\" target=\"_blank\" rel=\"noopener\"\n>Migrating to a different server<\/a><\/p>\n<p><\/p>\n<div class=\"tip inlineBlock info\">\n\u5c06\u65e7\u7684 data \u6587\u4ef6\u5939\u590d\u5236\u8fc7\u53bb\u540e\u9700\u8981\u7528 sudo -uwww php occ files:scan &ndash;all \u626b\u63cf\u66f4\u6539\n<\/div>\n<p><\/p>\n<h2 id=\"\u4f18\u5316\u5fc3\u5f97\">\u4f18\u5316\u5fc3\u5f97<\/h2>\n<h3 id=\"\u7f8e\u5316-url\">\u7f8e\u5316 URL<\/h3>\n<p>\u8fd9\u91cc\u5206\u4eab\u4e00\u4e0b\u6211\u7684 nginx \u914d\u7f6e\uff08\u53bb\u6389\u4e86 URL \u4e2d\u7684 index.php \u548c remote.php\uff09\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-nginx\" data-lang=\"nginx\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">server<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">listen<\/span> <span class=\"mi\">443<\/span> <span class=\"s\">ssl<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_certificate<\/span> <span class=\"s\">&lt;your<\/span> <span class=\"s\">certificate&gt;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_certificate_key<\/span> <span class=\"s\">&lt;your<\/span> <span class=\"s\">certificate<\/span> <span class=\"s\">key&gt;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_session_timeout<\/span> <span class=\"mi\">5m<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_protocols<\/span> <span class=\"s\">TLSv1<\/span> <span class=\"s\">TLSv1.1<\/span> <span class=\"s\">TLSv1.2<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_ciphers<\/span> <span class=\"s\">ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">ssl_prefer_server_ciphers<\/span> <span class=\"no\">on<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">server_name<\/span> <span class=\"s\">&lt;your<\/span> <span class=\"s\">server<\/span> <span class=\"s\">name&gt;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">root<\/span> <span class=\"s\">&lt;your<\/span> <span class=\"s\">nextcloud<\/span> <span class=\"s\">path&gt;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">error_log<\/span> <span class=\"s\">\/var\/log\/nextcloud15_error.log<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">access_log<\/span> <span class=\"s\">\/var\/log\/nextcloud15_access.log<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">location<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\/robots.txt<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">allow<\/span> <span class=\"s\">all<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">log_not_found<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">access_log<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\"># Deny access to the data and config directories, .ht* files,\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"c1\"># the README, and the database structure definition\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span> <span class=\"sr\">^\/(data|config|\\.ht|db_structure\\.xml|README)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">deny<\/span> <span class=\"s\">all<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\"># Pretty URLs for WebDAV\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span><span class=\"sr\">*<\/span> <span class=\"s\">\\\/remote\\\/(?:.*)<\/span>$ <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">rewrite<\/span> <span class=\"s\">^<\/span> <span class=\"s\">\/remote.php<\/span><span class=\"nv\">$uri$is_args$args<\/span> <span class=\"s\">last<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"c1\"># Pretty URLs\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span> <span class=\"kn\">location<\/span> <span class=\"s\">\/<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span><span class=\"sr\">*<\/span> <span class=\"s\">^\\\/core\\\/(?=preview)<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">rewrite<\/span> <span class=\"s\">^<\/span> <span class=\"s\">\/index.php<\/span><span class=\"nv\">$uri$is_args$args<\/span> <span class=\"s\">last<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span><span class=\"sr\">*<\/span> <span class=\"s\">^\\\/core(\/.*)?<\/span>$ <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">break<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">rewrite<\/span> <span class=\"s\">^<\/span> <span class=\"s\">\/index.php<\/span> <span class=\"s\">last<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span> <span class=\"sr\">^(.+?\\.php)(\/.*)?$<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">try_files<\/span> <span class=\"nv\">$1<\/span> <span class=\"p\">=<\/span> <span class=\"mi\">404<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">include<\/span> <span class=\"s\">fastcgi_params<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">fastcgi_param<\/span> <span class=\"s\">SCRIPT_FILENAME<\/span> <span class=\"nv\">$document_root$1<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">fastcgi_param<\/span> <span class=\"s\">PATH_INFO<\/span> <span class=\"nv\">$2<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">fastcgi_param<\/span> <span class=\"s\">front_controller_active<\/span> <span class=\"s\">true<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">fastcgi_pass<\/span> <span class=\"s\">unix:\/tmp\/php-cgi.sock<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">rewrite<\/span> <span class=\"s\">\/.well-known\/carddav<\/span> <span class=\"s\">\/remote.php\/dav<\/span> <span class=\"s\">permanent<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">rewrite<\/span> <span class=\"s\">\/.well-known\/caldav<\/span> <span class=\"s\">\/remote.php\/dav<\/span> <span class=\"s\">permanent<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">location<\/span> <span class=\"p\">~<\/span> <span class=\"sr\">\\.(?:css|js|woff|svg|gif|png|html|ttf|woff|woff2|ico|jpg|jpeg)$<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">try_files<\/span> <span class=\"nv\">$uri<\/span> <span class=\"s\">\/index.php<\/span><span class=\"nv\">$request_uri<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">add_header<\/span> <span class=\"s\">Cache-Control<\/span> <span class=\"s\">&#34;public,<\/span> <span class=\"s\">max-age=2592000&#34;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"kn\">access_log<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"p\">}<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5f00\u542f-opcache\">\u5f00\u542f OPcache<\/h3>\n<p>\u4e00\u822c\u7684\u6e90\u6bd4\u5982 <code>ppa:ondrej\/php<\/code> \u90fd\u4f1a\u9ed8\u8ba4\u5b89\u88c5 OPcache\uff08\u53ef\u4ee5\u7528 <code>php -m | grep Zend\\ OPcache<\/code> \u6765\u68c0\u67e5\u662f\u5426\u5b89\u88c5\uff09\u4f46\u662f\u4e00\u822c\u9ed8\u8ba4\u90fd\u4e0d\u4f1a\u5f00\u542f OPcache\uff0c\u9700\u8981\u5728 php.ini \u4e2d\u624b\u52a8\u5f00\u542f\u3002\u5b98\u65b9\u63a8\u8350\u914d\u7f6e\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-ini\" data-lang=\"ini\"><span class=\"line\"><span class=\"cl\"><span class=\"na\">zend_extension<\/span><span class=\"o\">=<\/span><span class=\"s\">opcache.so<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.enable<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.enable_cli<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.interned_strings_buffer<\/span><span class=\"o\">=<\/span><span class=\"s\">8<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.max_accelerated_files<\/span><span class=\"o\">=<\/span><span class=\"s\">10000<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.memory_consumption<\/span><span class=\"o\">=<\/span><span class=\"s\">128<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.save_comments<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">opcache.revalidate_freq<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u5f00\u542f\u5185\u5b58\u7f13\u5b58\">\u5f00\u542f\u5185\u5b58\u7f13\u5b58<\/h3>\n<p>\u5b98\u65b9\u6587\u6863\u63a8\u8350\u672c\u5730\u7f13\u5b58\u7528 APCu\uff0c\u5206\u5e03\u5f0f\u7f13\u5b58\u548c\u9501\u7528 Redis\uff0c\u914d\u7f6e\u6587\u4ef6\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ &lt;your-nextcloud-path&gt;\/config\/config.php\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;memcache.local&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;\\OC\\Memcache\\APCu&#39;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;memcache.distributed&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;\\OC\\Memcache\\Redis&#39;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;memcache.locking&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;\\OC\\Memcache\\Redis&#39;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"s1\">&#39;redis&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"s1\">&#39;host&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s1\">&#39;redis-host.example.com&#39;<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"s1\">&#39;port&#39;<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"mi\">6379<\/span><span class=\"p\">,<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">],<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u4f7f\u7528 APCu \u548c Redis \u90fd\u9700\u8981\u5b89\u88c5\u76f8\u5e94 PHP \u62d3\u5c55\uff08Redis \u8fd8\u9700\u8981\u5b89\u88c5\u76f8\u5e94\u7684\u670d\u52a1\u7aef\uff1a <code>apt install redis-server<\/code>\uff09\u6211\u4e2a\u4eba\u63a8\u8350\u81ea\u884c\u7f16\u8bd1\u5b89\u88c5\uff1a<\/p>\n<ol>\n<li>\u4e0b\u8f7d\u5bf9\u5e94\u6e90\u7801\uff1a<a class=\"link\" href=\"https:\/\/pecl.php.net\/package\/APCu\" target=\"_blank\" rel=\"noopener\"\n>APCu<\/a>\u3001<a class=\"link\" href=\"https:\/\/pecl.php.net\/package\/redis\" target=\"_blank\" rel=\"noopener\"\n>Redis<\/a><\/li>\n<li>\u89e3\u538b\u5230\u4f60\u7684\u670d\u52a1\u5668\u4e0a<\/li>\n<li>\u8fdb\u5165\u5bf9\u5e94\u76ee\u5f55\u5e76\u7f16\u8bd1\u5b89\u88c5\uff1a<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">phpize \/\/ \u8fd9\u4e2a\u547d\u4ee4\u5728 php \u7684\u5b89\u88c5\u8def\u7ecf\u4e0b\u7684 bin \u76ee\u5f55\u91cc\n<\/span><\/span><span class=\"line\"><span class=\"cl\">.\/configure --with-php-config<span class=\"o\">=<\/span>&lt;your-php-bin-dir&gt;\/php-config\n<\/span><\/span><span class=\"line\"><span class=\"cl\">make <span class=\"o\">&amp;&amp;<\/span> make install\n<\/span><\/span><\/code><\/pre><\/div><ol start=\"4\">\n<li>\u5728 php.ini \u4e2d\u542f\u7528\u5bf9\u5e94\u62d3\u5c55\uff1a<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-ini\" data-lang=\"ini\"><span class=\"line\"><span class=\"cl\"><span class=\"na\">extension<\/span> <span class=\"o\">=<\/span> <span class=\"s\">redis.so<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">extension<\/span> <span class=\"o\">=<\/span> <span class=\"s\">apcu.so<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">apc.enabled<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">apc.shm_size<\/span><span class=\"o\">=<\/span><span class=\"s\">32M<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"na\">apc.enable_cli<\/span><span class=\"o\">=<\/span><span class=\"s\">1<\/span>\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u540e\u53f0\u4efb\u52a1\u8bbe\u7f6e\u4e3a-cron\">\u540e\u53f0\u4efb\u52a1\u8bbe\u7f6e\u4e3a cron<\/h3>\n<p>\u5728\u7ba1\u7406\u5458\u9762\u677f\u57fa\u672c\u8bbe\u7f6e\u91cc\u5c06\u540e\u53f0\u4efb\u52a1\u8bbe\u7f6e\u6210 cron\uff0c\u7136\u540e\u767b\u9646\u670d\u52a1\u5668\u914d\u7f6e cron\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">sudo -uwww crontab -e \/\/ -u \u53c2\u6570\u4e3a\u8fd0\u884c php \u7684\u7528\u6237\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\/\/ \u5728\u6253\u5f00\u7684\u6587\u4ef6\u4e2d\u6dfb\u52a0\uff1a\n<\/span><\/span><span class=\"line\"><span class=\"cl\">*\/15 * * * * php -f &lt;your-next-cloud-path&gt;\/cron.php\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"Typecho \u65b0\u7248\u53c8\u62cd\u4e91\u63d2\u4ef6\u4f7f\u7528\u6559\u7a0b","link":"https:\/\/blog.lv5.moe\/p\/new-version-of-upyunfile-plugin-use-tutorial","pubDate":"Mon, 21 Jan 2019 00:30:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/new-version-of-upyunfile-plugin-use-tutorial","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/new-version-of-upyunfile-plugin-use-tutorial\/upyun.png\" alt=\"Featured image of post Typecho \u65b0\u7248\u53c8\u62cd\u4e91\u63d2\u4ef6\u4f7f\u7528\u6559\u7a0b\" \/><h2 id=\"\u8bf4\u660e\">\u8bf4\u660e<\/h2>\n<p>\u672c\u63d2\u4ef6 <a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/UpyunFile\" target=\"_blank\" rel=\"noopener\"\n>ShadowySpirits\/UpyunFile<\/a> \u662f\u53c8\u62cd\u4e91\u6587\u4ef6\u4e0a\u4f20\u63d2\u4ef6\uff0c\u57fa\u4e8e <a class=\"link\" href=\"https:\/\/github.com\/codesee\/UpyunFile\" target=\"_blank\" rel=\"noopener\"\n>codesee\/UpyunFile<\/a> \u4e8c\u6b21\u5f00\u53d1\u3002<\/p>\n<p>\u76f8\u6bd4\u4e8e\u539f\u63d2\u4ef6\uff1a<\/p>\n<ul>\n<li>\u4fee\u590d\u4e86\u542f\u7528\u672c\u63d2\u4ef6\u4f1a\u5f71\u54cd\u5176\u4ed6\u66ff\u6362\u5185\u5bb9\u63d2\u4ef6\u751f\u6548\u7684 Bug<\/li>\n<li>\u4fee\u590d\u4e86\u67d0\u4e9b\u60c5\u51b5\u4e0b\u56fe\u7247\u94fe\u63a5\u66ff\u6362\u5931\u8d25\u7684 Bug<\/li>\n<li>\u65b0\u589e\uff1a\u63a5\u5165\u53c8\u62cd\u4e91\u56fe\u7247\u5904\u7406\u529f\u80fd<\/li>\n<li>\u65b0\u589e\uff1a\u4e3a\u535a\u5ba2\u9759\u6001\u8d44\u6e90\u52a0\u5165 Token \u9632\u76d7\u94fe<\/li>\n<\/ul>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u53c8\u62cd\u4e91 SDK \u4ec5\u652f\u6301 PHP &gt;= 5.6 \u7684\u73af\u5883\n<\/div>\n<p><\/p>\n<h2 id=\"\u4f7f\u7528\u65b9\u6cd5\">\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u5728 <a class=\"link\" href=\"https:\/\/github.com\/ShadowySpirits\/UpyunFile\/releases\" target=\"_blank\" rel=\"noopener\"\n>Release<\/a> \u4e2d\u4e0b\u8f7d\u6b64\u63d2\u4ef6\u7684\u6700\u65b0\u7248\uff0c\u4e0a\u4f20\u81f3\u7f51\u7ad9\u7684 \/usr\/plugins\/ \u76ee\u5f55\u4e0b\u3002\u52a1\u5fc5\u4fdd\u6301\u672c\u63d2\u4ef6\u6587\u4ef6\u5939\u540d\u79f0\u4e3a <strong>UpyunFile<\/strong>\uff0c\u4e0d\u80fd\u968f\u610f\u66f4\u6539<\/li>\n<li>\u542f\u7528\u8be5\u63d2\u4ef6\uff0c\u6b63\u786e\u586b\u5199\u76f8\u5173\u4fe1\u606f\uff0c\u4fdd\u5b58\u5373\u53ef<\/li>\n<\/ol>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 106;\nflex-basis: 256px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/new-version-of-upyunfile-plugin-use-tutorial\/screenshot.jpg\" data-size=\"991x929\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/new-version-of-upyunfile-plugin-use-tutorial\/screenshot.jpg\"\nwidth=\"991\"\nheight=\"929\"\nloading=\"lazy\"\nalt=\"screenshot\">\n<\/a>\n<figcaption>screenshot<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u6ce8\u610f\u4e8b\u9879\">\u6ce8\u610f\u4e8b\u9879<\/h2>\n<ol>\n<li>\u542f\u7528\u53c8\u62cd\u4e91\u56fe\u7247\u5904\u7406\u9700\u5728\u53c8\u62cd\u4e91\u63a7\u5236\u53f0\u4e2d\u521b\u5efa\u7f29\u7565\u56fe\u7248\u672c\u5e76\u586b\u5165\u63d2\u4ef6\u76f8\u5e94\u4f4d\u7f6e\uff0c\u6587\u6863\uff1a<a class=\"link\" href=\"https:\/\/help.upyun.com\/knowledge-base\/image\/#thumb\" target=\"_blank\" rel=\"noopener\"\n>https:\/\/help.upyun.com\/knowledge-base\/image\/#thumb<\/a>\uff1b\u53c8\u62cd\u4e91\u56fe\u7247\u5904\u7406\u4f1a\u5ffd\u7565\u5e26\u6709\u540e\u7f00 <code>_nothumb<\/code> \u7684\u56fe\u7247\uff08\u6bd4\u5982\uff1aexample_nothumb.png\uff09<\/li>\n<li>\u5982\u4f60\u521b\u5efa\u7684\u7f29\u7565\u56fe\u7248\u672c\u5f00\u542f\u4e86\u8f6c\u7801\u529f\u80fd\uff0c\u5219\u9700\u5c06\u8f93\u51fa\u683c\u5f0f\u586b\u5165\u63d2\u4ef6\u76f8\u5e94\u4f4d\u7f6e<\/li>\n<li>\u53ea\u6709 <code>JPG\u3001JPEG\u3001PNG\u3001BMP<\/code> \u8fd9 4 \u79cd\u683c\u5f0f\u7684\u56fe\u7247\u624d\u4f1a\u8fdb\u884c\u5904\u7406<\/li>\n<li>\u542f\u7528 Token \u9632\u76d7\u94fe\u9700\u5728\u53c8\u62cd\u4e91\u63a7\u5236\u53f0\u4e2d\u542f\u7528 Token \u9632\u76d7\u94fe\u5e76\u5c06\u5bc6\u94a5\u586b\u5165\u63d2\u4ef6\u76f8\u5e94\u4f4d\u7f6e<\/li>\n<li>\u81ea\u5b9a\u4e49\u76ee\u5f55\u7ed3\u6784\u53ef\u4ee5\u5728 Typecho \u6839\u76ee\u5f55\u4e0b\u7684 config.inc.php \u4e2d\u6dfb\u52a0\u4ee3\u7801 <code>define('__TYPECHO_UPLOAD_DIR__', '\/path\/to\/uploads');<\/code> \u5e76\u8bbe\u7f6e\u76ee\u5f55\u7ed3\u6784\u4e3a <code>Typecho\u7ed3\u6784<\/code>\u3002<\/li>\n<\/ol>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\nToken \u9632\u76d7\u94fe\u529f\u80fd\u53ea\u80fd\u4fee\u6539 HTML \u4ee3\u7801\u4e2d\u7684 CDN \u94fe\u63a5\uff0c\u5982\u679c\u9700\u8981\u5f15\u5165\u5b57\u4f53\u56fe\u7247\u7b49\u8d44\u6e90\u8bf7\u5185\u8054 CSS\n<\/div>\n<p><\/p>\n<h2 id=\"\u66f4\u65b0\u8bb0\u5f55\">\u66f4\u65b0\u8bb0\u5f55\uff1a<\/h2>\n<p><strong>v0.9.0\uff1a<\/strong><\/p>\n<ul>\n<li>\u5347\u7ea7 SDK\uff0c\u4fee\u590d Bug\uff0c\u52a0\u5165\u65b0\u529f\u80fd<\/li>\n<\/ul>\n<p><strong>v1.0.0\uff1a<\/strong><\/p>\n<ul>\n<li>\u63a7\u5236\u53f0\u7684\u6587\u4ef6\u7ba1\u7406\u4e2d\u73b0\u5728\u53ef\u4ee5\u6b63\u5e38\u67e5\u770b\u6709 Token \u9632\u76d7\u94fe\u4fdd\u62a4\u7684\u56fe\u7247<\/li>\n<li>\u53c8\u62cd\u4e91\u56fe\u7247\u5904\u7406\u4f1a\u5ffd\u7565\u5e26\u6709\u540e\u7f00 <code>_nothumb<\/code> \u7684\u56fe\u7247\uff08\u6bd4\u5982\uff1aexample_nothumb.png\uff09<\/li>\n<li>\u4f18\u5316\u4ee3\u7801<\/li>\n<\/ul>\n<p><strong>v1.0.2\uff1a<\/strong><\/p>\n<ul>\n<li>\u4fee\u590d\u67d0\u4e9b\u60c5\u51b5\u4e0b\u91cd\u590d\u6dfb\u52a0 Token \u7684 bug<\/li>\n<\/ul>\n<p><strong>v1.0.3\uff1a<\/strong><\/p>\n<ul>\n<li>\u4f18\u5316\u4ee3\u7801<\/li>\n<li>\u589e\u5f3a\u517c\u5bb9\u6027<\/li>\n<\/ul>\n<p><strong>v1.0.4\uff1a<\/strong><\/p>\n<ul>\n<li>\u89e3\u51b3\u517c\u5bb9\u6027\u95ee\u9898<\/li>\n<\/ul>\n<p><\/p>\n<div class=\"tip inlineBlock warning\">\n\u5982\u679c\u4f60\u6709\u4f7f\u7528\u4e0a\u7684\u95ee\u9898\u8bf7\u5728\u63d0\u95ee\u65f6\u5199\u6e05\u695a\u4f60\u7684 <strong>php<\/strong> \u548c <strong>typecho<\/strong> \u7248\u672c\u4ee5\u53ca<strong>\u62a5\u9519\u4fe1\u606f<\/strong>\uff0c\u5426\u5219\u4e00\u5f8b\u4e0d\u4e88\u56de\u590d\n<\/div>\n<p><\/p>"},{"title":"\u7f51\u9875\u5b57\u4f53\u4f18\u5316","link":"https:\/\/blog.lv5.moe\/p\/web-font-optimization","pubDate":"Thu, 03 Jan 2019 22:32:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/web-font-optimization","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/blog_title.jpg\" alt=\"Featured image of post \u7f51\u9875\u5b57\u4f53\u4f18\u5316\" \/><p>\u5982\u679c\u4f60\u60f3\u5728\u7f51\u9875\u4e2d\u5f15\u5165\u4e00\u4e9b\u82b1\u5f0f\u5b57\u4f53\uff0c\u6bd4\u5982\u8fd9\u6837\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 265;\nflex-basis: 637px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/blog_title.jpg\" data-size=\"369x139\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/blog_title.jpg\"\nwidth=\"369\"\nheight=\"139\"\nloading=\"lazy\"\nalt=\"blog_title\">\n<\/a>\n<figcaption>blog_title<\/figcaption>\n<\/figure><\/p>\n<p>\u53ef\u4ee5\u8bd5\u8bd5\u4e0b\u9762\u51e0\u4e2a\u6280\u5de7\u6765\u4f18\u5316\u5b57\u4f53\u52a0\u8f7d\u901f\u5ea6\uff1a<\/p>\n<h2 id=\"\u4f7f\u7528-cdn-\u52a0\u901f\u5b57\u4f53\u8d44\u6e90\u52a0\u8f7d\">\u4f7f\u7528 CDN \u52a0\u901f\u5b57\u4f53\u8d44\u6e90\u52a0\u8f7d<\/h2>\n<p>\u4f60\u53ef\u4ee5\u628a\u5b57\u4f53\u6258\u7ba1\u5728\u5404\u5927 CDN \u670d\u52a1\u5546\u7684\u4e91\u50a8\u5b58\u4e2d\uff0c\u6216\u8005\u4f7f\u7528\u5404\u79cd\u516c\u5171 CDN \u6765\u5206\u53d1\u4f60\u7684\u5b57\u4f53\u3002\u7279\u522b\u662f\u540e\u8005\uff0c\u5982\u679c\u7528\u6237\u6d4f\u89c8\u8fc7\u7684\u5176\u4ed6\u7f51\u9875\u4e5f\u4f7f\u7528\u8fc7\u8fd9\u79cd\u5b57\u4f53\uff0c\u90a3\u4e48\u6d4f\u89c8\u5668\u5c31\u53ef\u4ee5\u4ece\u7f13\u5b58\u4e2d\u8bfb\u53d6\uff0c\u800c\u4e0d\u7528\u91cd\u65b0\u4e0b\u8f7d\u3002<\/p>\n<h2 id=\"\u4f7f\u7528-woff2-\u4f18\u5316\u5b57\u4f53\u4f53\u79ef\">\u4f7f\u7528 WOFF2 \u4f18\u5316\u5b57\u4f53\u4f53\u79ef<\/h2>\n<p>WOFF2 \u91c7\u7528\u81ea\u5b9a\u4e49\u9884\u5904\u7406\u548c\u538b\u7f29\u7b97\u6cd5\uff0c\u63d0\u4f9b\u7684\u6587\u4ef6\u5927\u5c0f\u538b\u7f29\u7387\u6bd4\u5176\u4ed6\u683c\u5f0f\u9ad8\u5927\u7ea6 30%\u3002\u4e0b\u9762\u662f\u4e00\u5f20 ttf vs woff vs woff2 \u7684\u6bd4\u8f83\u56fe\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 410;\nflex-basis: 984px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/font_type.jpg\" data-size=\"734x179\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/font_type.jpg\"\nwidth=\"734\"\nheight=\"179\"\nloading=\"lazy\"\nalt=\"font_type\">\n<\/a>\n<figcaption>font_type<\/figcaption>\n<\/figure><\/p>\n<p>\u53ef\u4ee5\u770b\u5230 woff2 \u5728\u4f53\u79ef\u7684\u63a7\u5236\u4e0a\u8fd8\u662f\u975e\u5e38\u6709\u4f18\u52bf\u7684\uff0c\u8fd9\u91cc\u63a8\u8350\u4e00\u4e2a ttf \u8f6c woff2 \u7684\u5de5\u5177\uff0c\u63d0\u4f9b CLI \u548c API \u4e24\u79cd\u8f6c\u6362\u65b9\u5f0f\u3002<br \/>\n[button color=&ldquo;dark&rdquo; icon=&ldquo;fontello fontello-github&rdquo; url=&ldquo;https:\/\/github.com\/nfroidure\/ttf2woff2&rdquo;]nfroidure\/ttf2woff2[\/button]<\/p>\n<p>\u76ee\u524d\u6d4f\u89c8\u5668\u5bf9 woff2 \u7684\u517c\u5bb9\u6027\u5df2\u7ecf\u76f8\u5f53\u4e0d\u9519\u4e86\uff0c\u53ef\u4ee5\u770b\u5230\u6d4f\u89c8\u5668\u7684\u652f\u6301\u7387\u8fbe\u5230\u4e86 84.03%\u3002\u79fb\u52a8\u7aef Android 5+\/IOS 10+ \u7684 webview \u652f\u6301 woff2\uff0c\u76ee\u524d\u6211\u6d4b\u8bd5\u7684\u51e0\u6b3e\u4e3b\u6d41\u624b\u673a\u6d4f\u89c8\u5668\u5bf9 woff2 \u90fd\u5b8c\u7f8e\u652f\u6301\u3002<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 315;\nflex-basis: 757px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/woff2_support.jpg\" data-size=\"1584x502\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/woff2_support.jpg\"\nwidth=\"1584\"\nheight=\"502\"\nloading=\"lazy\"\nalt=\"woff2_support\">\n<\/a>\n<figcaption>woff2_support<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u63d0\u53d6\u90e8\u5206\u5b57\u4f53\">\u63d0\u53d6\u90e8\u5206\u5b57\u4f53<\/h2>\n<p>\u5f88\u591a\u60c5\u51b5\u4e0b\uff08\u7279\u522b\u662f\u4e2d\u6587\u5b57\u4f53\u4f53\u79ef\u5728\u901a\u5e38\u60c5\u51b5\u4e0b\u8d85\u5927\uff09\uff0c\u4f60\u5e76\u4e0d\u9700\u8981\u4f7f\u7528\u5b8c\u6574\u7684\u5b57\u4f53\u6587\u4ef6\uff0c\u6bd4\u5982\u6211\u7684\u7b7e\u540d\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 202;\nflex-basis: 486px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/sign.jpg\" data-size=\"233x115\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/web-font-optimization\/sign.jpg\"\nwidth=\"233\"\nheight=\"115\"\nloading=\"lazy\"\nalt=\"sign\">\n<\/a>\n<figcaption>sign<\/figcaption>\n<\/figure><\/p>\n<p>\u5bf9\u4e8e\u8fd9\u6837\u7684\u9759\u6001\u9875\u9762\uff0c\u53ef\u4ee5\u63d0\u53d6\u6240\u9700\u7684\u5b57\u4f53\u6765\u51cf\u5c0f\u5f15\u5165\u7684\u5b57\u4f53\u6587\u4ef6\u4f53\u79ef\uff0c\u8fd9\u91cc\u63a8\u8350\u4e24\u4e2a\u5de5\u5177\uff1a<a class=\"link\" href=\"http:\/\/font-spider.org\/\" target=\"_blank\" rel=\"noopener\"\n>\u5b57\u86db<\/a> &amp; <a class=\"link\" href=\"http:\/\/ecomfe.github.io\/fontmin\" target=\"_blank\" rel=\"noopener\"\n>fontmin<\/a>\uff0c\u5e76\u4e14 fontmin \u63d0\u4f9b\u4e86 <em>Mac OS X<\/em>\u3001<em>Windows<\/em> \u5e73\u53f0\u4e0b\u7684\u5ba2\u6237\u7aef\uff1a<a class=\"link\" href=\"https:\/\/github.com\/ecomfe\/fontmin-app\" target=\"_blank\" rel=\"noopener\"\n>Github: ecomfe\/fontmin-app<\/a><\/p>\n<h2 id=\"\u5185\u8054\u5b57\u4f53\">\u5185\u8054\u5b57\u4f53<\/h2>\n<p>\u5728\u5b57\u4f53\u4e0d\u5927\u7684\u60c5\u51b5\u4e0b\uff0c\u4f7f\u7528 data \u534f\u8bae\u5185\u8054\u662f\u4e2a\u4e0d\u9519\u7684\u9009\u62e9\uff0c\u53ef\u4ee5\u51cf\u5c11\u8bf7\u6c42\u6570\uff0c\u5e76\u4e14\u5b8c\u5168\u907f\u514d\u4e86 FOUT \u548c FOIT\u3002<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-css\" data-lang=\"css\"><span class=\"line\"><span class=\"cl\"><span class=\"p\">@<\/span><span class=\"k\">font-face<\/span> <span class=\"p\">{<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">font-family<\/span><span class=\"o\">:<\/span> <span class=\"nt\">AomemoFont-Regular<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">src<\/span><span class=\"o\">:<\/span> <span class=\"nt\">url<\/span><span class=\"o\">(<\/span><span class=\"s2\">&#34;data:font\/woff2;base64,...&#34;<\/span><span class=\"o\">)<\/span> <span class=\"nt\">format<\/span><span class=\"o\">(<\/span><span class=\"s2\">&#34;woff2&#34;<\/span><span class=\"o\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">font-style<\/span><span class=\"o\">:<\/span> <span class=\"nt\">normal<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> <span class=\"nt\">font-weight<\/span><span class=\"o\">:<\/span> <span class=\"nt\">normal<\/span><span class=\"o\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"p\">}<\/span>\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u79cd\u65b9\u5f0f\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u62d6\u6162\u4e86\u9996\u5c4f\u52a0\u8f7d\u65f6\u95f4\uff0c\u63a8\u8350\u914d\u5408\u63d0\u53d6\u90e8\u5206\u5b57\u4f53\u4f7f\u7528\u3002<\/p>"},{"title":"\u4e2a\u4eba\u7f51\u7ad9 CDN \u9009\u7528\u6307\u5317","link":"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference","pubDate":"Wed, 02 Jan 2019 14:05:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_logo.jpg\" alt=\"Featured image of post \u4e2a\u4eba\u7f51\u7ad9 CDN \u9009\u7528\u6307\u5317\" \/><h2 id=\"\u5168\u80fd\u738b-cloudflare\">\u5168\u80fd\u738b Cloudflare<\/h2>\n<p>Cloudflare \u662f\u4e00\u5bb6\u63d0\u4f9b DNS \u548c CDN \u7b49\u670d\u52a1\u7684\u516c\u53f8\uff0c\u53f7\u79f0 <code>Powering over 39% of managed DNS domains<\/code> \uff0c\u5176\u63d0\u4f9b\u7684 CDN \u670d\u52a1\u5728\u529f\u80fd\u6027\uff08WAF\u3001Page Rules\u3001Argo\u3001Load Balancing\uff09\u4e0a\u4e0d\u77e5\u9053\u7529\u6389\u56fd\u5185\u540c\u884c\u51e0\u6761\u8857\uff0c\u800c\u4e14\u57fa\u7840\u529f\u80fd\u548c\u6d41\u91cf\u5b8c\u5168\u514d\u8d39\u3002\u4f46\u662f\u57fa\u4e8e\u56fd\u60c5\u5728\u56fd\u5185\u8bbf\u95ee\u4e0d\u662f\u5f88\u7406\u60f3\uff0c\u66f4\u5efa\u8bae\u4f53\u91cf\u5927\u7684\u9759\u6001\u8d44\u6e90\u4f7f\u7528\u56fd\u5185 CDN \u670d\u52a1\u3002<\/p>\n<p>Cloudflare \u7684\u63a5\u5165\u65b9\u5f0f\u9ed8\u8ba4\u53ea\u652f\u6301 DNS \u63a5\u5165\uff0cCNAME \u63a5\u5165\u9700\u8981 py\uff08\u5927\u96fe\uff09\u3002\u8fd9\u91cc\u7b80\u5355\u4ecb\u7ecd\u4e0b Cloudflare \u7684\u51e0\u4e2a\u529f\u80fd\u3002<\/p>\n<h3 id=\"\u5168\u7ad9-https\">\u5168\u7ad9 HTTPS<\/h3>\n<p>Cloudflare \u514d\u8d39\u63d0\u4f9b\u6cdb\u57df\u540d\u8bc1\u4e66\uff0c\u53ea\u8981\u63a5\u5165\u4ed6\u5bb6\u7684 CDN \u5c31\u53ef\u4ee5\u4f53\u9a8c\u5230\u5168\u7ad9 HTTPS \u7684\u8212\u723d\uff08\u624b\u52a8\u72d7\u5934\uff09\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\u514d\u8d39\u8bc1\u4e66\u4e0b\u8f7d\u4e0b\u6765\u662f\u81ea\u7b7e\u540d\u8bc1\u4e66\uff0c\u53ea\u6709\u5728 Cloudflare \u7f51\u7edc\u5185\u53d7\u4fe1\uff0c\u7528\u5b83\u6765\u5f00\u542f\u4e2a\u56de\u6e90 HTTPS \u8fd8\u884c\uff0c\u6d4f\u89c8\u5668\u662f\u4e0d\u8ba4\u7684\u3002\u63a7\u5236\u53f0\u7684 Crypto \u6807\u7b7e\u4e0b\u53ef\u4ee5\u914d\u7f6e\u5176\u4ed6\u76f8\u5173\u9009\u9879\u3002<\/p>\n<h3 id=\"\u81ea\u52a8\u963b\u6b62\u6076\u610f\u8bbf\u95ee\">\u81ea\u52a8\u963b\u6b62\u6076\u610f\u8bbf\u95ee<\/h3>\n<p>\u81ea\u52a8\u68c0\u6d4b\u51fa\u6076\u610f IP \u540e\u4f7f\u7528 challenge page \u6765\u8fdb\u4e00\u6b65\u7504\u522b\u548c\u963b\u6b62\u6076\u610f\u8bbf\u95ee\uff08\u4e0b\u56fe\u662f javascript challenge page\uff09\uff0c\u53ef\u4ee5\u5728\u63a7\u5236\u53f0\u7684 Firewall \u6807\u7b7e\u9875\u4e0b\u8c03\u6574 Security Level \u548c Challenge Passage \u7684\u7b49\u7ea7\uff0c\u6216\u8005\u5728 IP Access Rules \u4e0b\u6839\u636e IP\u3001ASN\u3001 \u56fd\u5bb6\u7b49\u624b\u52a8\u914d\u7f6e \u3002<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 321;\nflex-basis: 771px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_challenge_page.jpg\" data-size=\"926x288\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_challenge_page.jpg\"\nwidth=\"926\"\nheight=\"288\"\nloading=\"lazy\"\nalt=\"challenge page\">\n<\/a>\n<figcaption>challenge page<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"web-application-firewall\">Web Application Firewall<\/h3>\n<p>Cloudflare \u63d0\u4f9b\u7684 WAF \u53ef\u4ee5\u8bf4\u662f\u76f8\u5f53\u5f3a\u5927\u7684\u5e94\u7528\u9632\u706b\u5899\uff0c\u514d\u8d39\u7528\u6237\u62e5\u6709 5 \u6761\u89c4\u5219\uff0c\u53ef\u4ee5\u6839\u636e IP\u3001Cookie\u3001host\u3001URI\u3001\u5a01\u80c1\u7b49\u7ea7\u3001\u662f\u5426\u662f\u673a\u5668\u4eba\u7b49\u5339\u914d\u89c4\u5219\u6307\u5b9a\u963b\u6b62\u8bbf\u95ee\u6216\u8005\u9700\u8981\u8f93\u5165\u9a8c\u8bc1\u7801\u7b49\u7b56\u7565\u3002<\/p>\n<p>\u8fd9\u91cc\u7ed9\u51fa\u4e00\u4e2a\u4f8b\u5b50\uff0c\u7981\u6b62\u9664\u6211\u7684 IP \u4ee5\u5916\u7684\u7528\u6237\u8bbf\u95ee\u67d0\u4e2a\u654f\u611f\u9875\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 212;\nflex-basis: 509px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_waf.jpg\" data-size=\"1240x584\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_waf.jpg\"\nwidth=\"1240\"\nheight=\"584\"\nloading=\"lazy\"\nalt=\"waf\">\n<\/a>\n<figcaption>waf<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"page-rules\">Page Rules<\/h3>\n<p>\u5bf9\u67d0\u4e9b\u9875\u9762\u6307\u5b9a\u7279\u5b9a\u7684 Cloudflare \u8bbe\u7f6e\uff08\u7f13\u5b58\u7b49\u7ea7\u3001\u8fc7\u671f\u65f6\u95f4\u3001\u5f00\u542f Always Online \u7b49\u7b49\uff09\uff0c\u6bd4\u5982\u5bf9\u67d0\u4e2a\u5b50\u57df\u540d\u7684\u6240\u6709 HTML \u6587\u4ef6\u6dfb\u52a0\u81ea\u52a8\u4f18\u5316\u529f\u80fd\uff1a<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 172;\nflex-basis: 413px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_page_rules.jpg\" data-size=\"967x561\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/individual-website-cdn-usage-reference\/cf_page_rules.jpg\"\nwidth=\"967\"\nheight=\"561\"\nloading=\"lazy\"\nalt=\"page rules\">\n<\/a>\n<figcaption>page rules<\/figcaption>\n<\/figure><\/p>\n<h3 id=\"\u6dfb\u52a0\u7b2c\u4e09\u65b9-app\">\u6dfb\u52a0\u7b2c\u4e09\u65b9 APP<\/h3>\n<p>\u5728\u63a7\u5236\u53f0\u7684 Apps \u6807\u7b7e\u4e0b\u53ef\u4ee5\u6dfb\u52a0\u7b2c\u4e09\u65b9 App\uff0c\u6bd4\u5982\u63a5\u5165 Google Analytics\u3001\u52a0\u5165\u672c\u7ad9\u4f7f\u7528 Cookie \u7684\u63d0\u793a\u7b49\u7b49\u3002<\/p>\n<h3 id=\"\u5176\u4ed6\u529f\u80fd\">\u5176\u4ed6\u529f\u80fd<\/h3>\n<p>\u9664\u4e86\u4e00\u822c\u7684 CDN \u8be5\u6709\u7684\u529f\u80fd\u4ee5\u5916\u8fd8\u6709\u81ea\u52a8\u8df3\u8f6c\u79fb\u52a8\u7aef\u9875\u9762\u3001AMP \u4f18\u5316\u3001 Rocket Loader\u3001Always Online \u7b49\u5b9e\u7528\u529f\u80fd\u3002\u4ee5\u4e0a\u4ecb\u7ecd\u7684\u90fd\u662f\u514d\u8d39\u529f\u80fd\uff0c\u5982\u679c\u4f60\u613f\u610f\u4ed8\u8d39\u7684\u8bdd\u8fd8\u80fd\u4eab\u53d7\u5230 Argo\u3001Load Balancing\u3001Rate Limiting \u7b49\u8fdb\u9636\u529f\u80fd\u3002<\/p>\n<h2 id=\"\u56fd\u5185-cdn-\u670d\u52a1\u5546\">\u56fd\u5185 CDN \u670d\u52a1\u5546<\/h2>\n<p>\u524d\u9762\u8bf4\u8fc7 Cloudflare \u867d\u7136\u529f\u80fd\u975e\u5e38\u5f3a\u5927\uff0c\u53ef\u60dc\u5929\u671d\u81ea\u6709\u56fd\u60c5\u5728\uff0c\u6240\u4ee5\u4e3b\u7ad9\u4f7f\u7528 Cloudflare CDN\uff0c\u9759\u6001\u8d44\u6e90\u6258\u7ba1\u5728\u56fd\u5185\u4e91\u50a8\u5b58\u8fd9\u79cd\u52a8\u9759\u5206\u79bb\u7684\u65b9\u5f0f\u53ef\u4ee5\u6709\u66f4\u597d\u7684\u4f53\u9a8c\u3002<\/p>\n<p>\u672c\u7ad9\u4f7f\u7528\u7684\u662f\u53c8\u62cd\u4e91\uff0c\u6211\u4e2a\u4eba\u89c9\u5f97\u53c8\u62cd\u4e91\u6027\u80fd\u548c\u529f\u80fd\u4e0a\u6bd4\u4e03\u725b\u8981\u597d\u4e00\u4e9b\uff0c\u800c\u4e14\u6bd4\u963f\u91cc\u4e91\u8981\u4fbf\u5b9c qwq\u3002\u5e76\u4e14\u53c8\u62cd\u4e91\u63d0\u4f9b\u878d\u5408\u4e91\u50a8\u5b58\uff0c\u53ef\u4ee5\u5c06\u589e\u91cf\u6587\u4ef6\u540c\u6b65\u5230\u4e03\u725b\u6216\u8005\u963f\u91cc\u4e91\uff0c\u52a0\u5165<a class=\"link\" href=\"https:\/\/www.upyun.com\/league\" target=\"_blank\" rel=\"noopener\"\n>\u53c8\u62cd\u4e91\u8054\u76df<\/a>\u53ef\u4ee5\u83b7\u5f97 10GB \u514d\u8d39\u5b58\u50a8\u7a7a\u95f4\u548c 15GB \u514d\u8d39\u6d41\u91cf\uff08HTTPS \u4e5f\u80fd\u7528\uff0c\u8fd9\u70b9\u8981\u6bd4\u4e03\u725b\u826f\u5fc3\uff09<\/p>"},{"title":"Windows \u4e0b\u7f16\u8bd1 AV1 codec","link":"https:\/\/blog.lv5.moe\/p\/compiling-av1-codec-under-windows","pubDate":"Tue, 18 Dec 2018 10:52:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/compiling-av1-codec-under-windows","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/compiling-av1-codec-under-windows\/codec-timeline.jpg\" alt=\"Featured image of post Windows \u4e0b\u7f16\u8bd1 AV1 codec\" \/><h2 id=\"\u4ec0\u4e48\u662f-av1\">\u4ec0\u4e48\u662f AV1<\/h2>\n<p>AV1 \u5168\u79f0 AOMedia Video 1 \u662f AOM (Alliance for Open Media) \u5728 2018 \u5e74\u63a8\u51fa\u7684\u65b0\u4e00\u4ee3\u89c6\u9891\u7f16\u7801\u6807\u51c6\uff0c\u5176\u8bbe\u8ba1\u76ee\u7684\u662f\u63d0\u4f9b\u66f4\u597d\u7684\u8d28\u91cf\u3001\u66f4\u5c0f\u7684\u4f53\u79ef\uff0c\u4ee5\u7528\u4e8e\u5728\u4e92\u8054\u7f51\u4e0a\u4f20\u8f93\u9ad8\u8d28\u91cf\u7684\u89c6\u9891\u3002\u76ee\u524d Chrome 69 \u548c Firefox 63 \u4e2d\u90fd\u6dfb\u52a0\u4e86\u5bf9 AV1 \u7684\u652f\u6301\uff08\u9700\u8981\u624b\u52a8\u5f00\u542f\uff09\uff0cLAV \u5728 <a class=\"link\" href=\"https:\/\/github.com\/Nevcairiel\/LAVFilters\/releases\/tag\/0.73\" target=\"_blank\" rel=\"noopener\"\n>0.73<\/a> \u4e2d\u5f00\u59cb\u652f\u6301\u5bf9 AV1 \u7684\u89e3\u7801\u3002<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 242;\nflex-basis: 581px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/compiling-av1-codec-under-windows\/codec-timeline.jpg\" data-size=\"1400x578\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/compiling-av1-codec-under-windows\/codec-timeline.jpg\"\nwidth=\"1400\"\nheight=\"578\"\nloading=\"lazy\"\nalt=\"codec timeline\">\n<\/a>\n<figcaption>codec timeline<\/figcaption>\n<\/figure><br \/>\n\u66f4\u8be6\u7ec6\u7684\u4ecb\u7ecd\u53ef\u4ee5\u53c2\u8003\u4ee5\u4e0b\u4e24\u7bc7\u6587\u7ae0\uff1a<\/p>\n<ul>\n<li><a class=\"link\" href=\"https:\/\/research.mozilla.org\/av1-media-codecs\/\" target=\"_blank\" rel=\"noopener\"\n>mozilla research<\/a><\/li>\n<li><a class=\"link\" href=\"https:\/\/www.theoplayer.com\/blog\/av1-hevc-comparative-look-video-codecs\" target=\"_blank\" rel=\"noopener\"\n>AV1 or HEVC? How to choose the best video codec<\/a><\/li>\n<\/ul>\n<h2 id=\"\u7f16\u8bd1-av1-codec\">\u7f16\u8bd1 AV1 codec<\/h2>\n<h3 id=\"\u7f16\u8bd1\u6240\u9700\u73af\u5883\">\u7f16\u8bd1\u6240\u9700\u73af\u5883\uff1a<\/h3>\n<ol>\n<li><a class=\"link\" href=\"https:\/\/cmake.org\/\" target=\"_blank\" rel=\"noopener\"\n>CMake<\/a> version 3.5 or higher.<\/li>\n<li><a class=\"link\" href=\"https:\/\/git-scm.com\/\" target=\"_blank\" rel=\"noopener\"\n>Git<\/a>.<\/li>\n<li><a class=\"link\" href=\"https:\/\/www.perl.org\/\" target=\"_blank\" rel=\"noopener\"\n>Perl<\/a>.<\/li>\n<li>For x86 targets, <a class=\"link\" href=\"http:\/\/yasm.tortall.net\/\" target=\"_blank\" rel=\"noopener\"\n>yasm<\/a>, which is preferred, or a recent version of <a class=\"link\" href=\"http:\/\/www.nasm.us\/\" target=\"_blank\" rel=\"noopener\"\n>nasm<\/a>.<\/li>\n<li>Building the documentation requires <a class=\"link\" href=\"http:\/\/doxygen.org\/\" target=\"_blank\" rel=\"noopener\"\n>doxygen<\/a>.<\/li>\n<li>Building the unit tests requires <a class=\"link\" href=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noopener\"\n>Python<\/a>.<\/li>\n<li>Emscripten builds require the portable <a class=\"link\" href=\"https:\/\/kripken.github.io\/emscripten-site\/index.html\" target=\"_blank\" rel=\"noopener\"\n>EMSDK<\/a>.<\/li>\n<\/ol>\n<h3 id=\"\u73af\u5883\u642d\u5efa\">\u73af\u5883\u642d\u5efa\uff1a<\/h3>\n<ul>\n<li>cmake\uff1a<a class=\"link\" href=\"https:\/\/cmake.org\/download\/\" target=\"_blank\" rel=\"noopener\"\n>cmake 3.7.1<\/a><\/li>\n<li>make\/gcc\uff1a<a class=\"link\" href=\"https:\/\/mingw-w64.org\/\" target=\"_blank\" rel=\"noopener\"\n>MinGW-W64<\/a> \uff08\u4e00\u5b9a\u8981\u9009 64 \u4f4d\u7684 MinGW\uff09<\/li>\n<li>perl\uff1a<a class=\"link\" href=\"http:\/\/strawberryperl.com\/download\/5.28.1.1\/strawberry-perl-5.28.1.1-64bit.msi\" target=\"_blank\" rel=\"noopener\"\n>strawberry-perl-5.28.1.1-64bit<\/a><\/li>\n<li>yasm\uff1a<a class=\"link\" href=\"http:\/\/www.tortall.net\/projects\/yasm\/releases\/yasm-1.3.0-win64.exe\" target=\"_blank\" rel=\"noopener\"\n>yasm-1.3.0-win64<\/a><\/li>\n<\/ul>\n<p>\u5b89\u88c5\u4e0a\u8ff0\u73af\u5883\u5e76\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\u540e\u5373\u53ef\u5f00\u59cb\u7f16\u8bd1<\/p>\n<h3 id=\"\u7f16\u8bd1\u6d41\u7a0b\">\u7f16\u8bd1\u6d41\u7a0b\uff1a<\/h3>\n<ol>\n<li>clone \u4ee3\u7801<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">git clone https:\/\/aomedia.googlesource.com\/aom\n<\/span><\/span><\/code><\/pre><\/div><ol start=\"2\">\n<li>\u5728 <code>aom<\/code> \u6587\u4ef6\u5939\u5916\u65b0\u5efa\u4e00\u4e2a\u6587\u4ef6\u5939 <code>aom_build<\/code><\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\"><span class=\"nb\">cd<\/span> aom_build\n<\/span><\/span><span class=\"line\"><span class=\"cl\">cmake ..\/aom\n<\/span><\/span><span class=\"line\"><span class=\"cl\">make\n<\/span><\/span><\/code><\/pre><\/div><ol start=\"3\">\n<li>\u4e00\u5207\u6b63\u5e38\u7684\u8bdd\u4f60\u4f1a\u5728 <code>aom_build<\/code> \u4e2d\u770b\u5230 <code>aomenc.exe<\/code> \u548c <code>aomdec.exe<\/code>\uff0c\u8fd9\u5c31\u662f\u6211\u4eec\u8981\u7684 codec<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\/\/ aomenc --help \u53ef\u4ee5\u770b\u5230\u7f16\u7801\u5668\u7248\u672c\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Included encoders:\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> av1 - AOMedia Project AV1 Encoder 1.0.0-1047-gf4e775cf3 <span class=\"o\">(<\/span>default<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"> Use --codec to switch to a non-default encoder.\n<\/span><\/span><\/code><\/pre><\/div>"},{"title":"iptables \u767d\u540d\u5355\u8fc7\u6ee4","link":"https:\/\/blog.lv5.moe\/p\/iptables-whitelist-filtering","pubDate":"Wed, 05 Dec 2018 20:43:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/iptables-whitelist-filtering","description":"<h2 id=\"iptables-\u8fc7\u6ee4\u53c2\u6570\u4ecb\u7ecd\">iptables \u8fc7\u6ee4\u53c2\u6570\u4ecb\u7ecd<\/h2>\n<h3 id=\"-a-append\">-A (append)<\/h3>\n<p>\u5411\u67d0\u4e2a\u89c4\u5219\u94fe\u5c3e\u90e8\u6dfb\u52a0\u4e00\u6761\u89c4\u5219\uff0c\u5982\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -A INPUT -p icmp -m icmp --icmp-type <span class=\"m\">8<\/span> -j ACCEPT\n<\/span><\/span><\/code><\/pre><\/div><h3 id=\"-i-insert-\u5728\u89c4\u5219\u94fe\u7684\u5934\u90e8\u63d2\u5165\u65b0\u7684\u89c4\u5219\">-I (Insert) \u5728\u89c4\u5219\u94fe\u7684\u5934\u90e8\u63d2\u5165\u65b0\u7684\u89c4\u5219<\/h3>\n<p>\u4e00\u5171\u6709\u4e09\u6761\u89c4\u5219\u94fe\uff1aForward\u3001Input\u3001Output<\/p>\n<ul>\n<li>\n<p>Forward\uff1a\u6570\u636e\u5305\u7684\u76ee\u7684\u5730\u5740\u4e0d\u662f\u672c\u673a\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u8fd9\u4e2a\u5305\u5c06\u88ab\u8f6c\u53d1<\/p>\n<\/li>\n<li>\n<p>Input\uff1a\u6570\u636e\u5305\u7684\u76ee\u7684\u5730\u5740\u662f\u672c\u673a<\/p>\n<\/li>\n<li>\n<p>Output\uff1a\u6570\u636e\u5305\u662f\u7531\u672c\u5730\u7cfb\u7edf\u8fdb\u7a0b\u4ea7\u751f\u7684\uff0c\u5e76\u901a\u8fc7\u67d0\u4e2a\u672c\u5730\u7aef\u53e3\u53d1\u9001\u7684<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"-m-module_name\">-m (module_name)<\/h3>\n<p>\u4f7f\u7528\u6269\u5c55\u6a21\u5757\u6765\u8fdb\u884c\u6570\u636e\u5305\u7684\u5339\u914d\uff0c\u672c\u6587\u4e3b\u8981\u4ecb\u7ecd <code>-m state<\/code><\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport <span class=\"m\">2333<\/span> -j ACCEPT\n<\/span><\/span><\/code><\/pre><\/div><p>\u5728 iptables \u4e0a\u4e00\u5171\u6709\u56db\u79cd\u72b6\u6001\uff1aNEW\u3001ESTABLISHED\u3001INVALID\u3001RELATED<\/p>\n<ol>\n<li>\n<p>NEW\uff1aNEW \u8bf4\u660e\u8fd9\u4e2a\u5305\u662f\u6211\u4eec\u770b\u5230\u7684\u7b2c\u4e00\u4e2a\u5305\u3002\u610f\u601d\u5c31\u662f\uff0c\u8fd9\u662f conntrack \u6a21\u5757\u770b\u5230\u7684\u67d0\u4e2a\u8fde\u63a5\u7684\u7b2c\u4e00\u4e2a\u5305\uff0c\u5b83\u5373\u5c06\u88ab\u5339\u914d\u4e86\u3002\u6bd4\u5982\uff0c\u6211\u4eec\u770b\u5230\u4e00\u4e2a SYN \u5305\uff0c\u662f\u6211\u4eec\u6240\u7559\u610f\u7684\u8fde\u63a5\u7684\u7b2c\u4e00\u4e2a\u5305\uff0c\u5c31\u8981\u5339\u914d\u5b83\u3002<\/p>\n<\/li>\n<li>\n<p>ESTABLISHED\uff1a ESTABLISHED \u5df2\u7ecf\u6ce8\u610f\u5230\u4e24\u4e2a\u65b9\u5411\u4e0a\u7684\u6570\u636e\u4f20\u8f93\uff0c\u800c\u4e14\u4f1a\u7ee7\u7eed\u5339\u914d\u8fd9\u4e2a\u8fde\u63a5\u7684\u5305\u3002\u5904\u4e8e ESTABLISHED \u72b6\u6001\u7684\u8fde\u63a5\u662f\u975e\u5e38\u5bb9\u6613\u7406\u89e3\u7684\u3002\u53ea\u8981\u53d1\u9001\u5e76\u63a5\u5230\u5e94\u7b54\uff0c\u8fde\u63a5\u5c31\u662f ESTABLISHED \u7684\u4e86\u3002\u4e00\u4e2a\u8fde\u63a5\u8981\u4ece NEW \u53d8\u4e3a ESTABLISHED\uff0c\u53ea\u9700\u8981\u63a5\u5230\u5e94\u7b54\u5305\u5373\u53ef\uff0c\u4e0d\u7ba1\u8fd9\u4e2a\u5305\u662f\u53d1\u5f80\u9632\u706b\u5899\u7684\uff0c\u8fd8\u662f\u8981\u7531\u9632\u706b\u5899\u8f6c\u53d1\u7684\u3002ICMP \u7684\u9519\u8bef\u548c\u91cd\u5b9a\u5411\u7b49\u4fe1\u606f\u5305\u4e5f\u88ab\u770b\u4f5c\u662f ESTABLISHED\uff0c\u53ea\u8981\u5b83\u4eec\u662f\u6211\u4eec\u6240\u53d1\u51fa\u7684\u4fe1\u606f\u7684\u5e94\u7b54\u3002<\/p>\n<\/li>\n<li>\n<p>RELATED\uff1a RELATED \u662f\u4e2a\u6bd4\u8f83\u9ebb\u70e6\u7684\u72b6\u6001\u3002\u5f53\u4e00\u4e2a\u8fde\u63a5\u548c\u67d0\u4e2a\u5df2\u5904\u4e8e ESTABLISHED \u72b6\u6001\u7684\u8fde\u63a5\u6709\u5173\u7cfb\u65f6\uff0c\u5c31\u88ab\u8ba4\u4e3a\u662f RELATED \u7684\u4e86\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u4e00\u4e2a\u8fde\u63a5\u8981\u60f3\u662f RELATED \u7684\uff0c\u9996\u5148\u8981\u6709\u4e00\u4e2a ESTABLISHED \u7684\u8fde\u63a5\u3002\u8fd9\u4e2a ESTABLISHED \u8fde\u63a5\u518d\u4ea7\u751f\u4e00\u4e2a\u4e3b\u8fde\u63a5\u4e4b\u5916\u7684\u8fde\u63a5\uff0c\u8fd9\u4e2a\u65b0\u7684\u8fde\u63a5\u5c31\u662f RELATED \u7684\u4e86\uff0c\u5f53\u7136\u524d\u63d0\u662f conntrack \u6a21\u5757\u8981\u80fd\u7406\u89e3 RELATED\u3002ftp \u662f\u4e2a\u5f88\u597d\u7684\u4f8b\u5b50\uff0cFTP-data \u8fde\u63a5\u5c31\u662f\u548c FTP-control \u6709\u5173\u8054\u7684\uff0c\u5982\u679c\u6ca1\u6709\u5728 iptables \u7684\u7b56\u7565\u4e2d\u914d\u7f6e RELATED \u72b6\u6001\uff0cFTP-data \u7684\u8fde\u63a5\u662f\u65e0\u6cd5\u6b63\u786e\u5efa\u7acb\u7684\uff0c\u8fd8\u6709\u5176\u4ed6\u7684\u4f8b\u5b50\uff0c\u6bd4\u5982\uff0c\u901a\u8fc7 IRC \u7684 DCC \u8fde\u63a5\u3002\u6709\u4e86\u8fd9\u4e2a\u72b6\u6001\uff0cICMP \u5e94\u7b54\u3001FTP \u4f20\u8f93\u3001DCC \u7b49\u624d\u80fd\u7a7f\u8fc7\u9632\u706b\u5899\u6b63\u5e38\u5de5\u4f5c\u3002\u6ce8\u610f\uff0c\u5927\u90e8\u5206\u8fd8\u6709\u4e00\u4e9b UDP \u534f\u8bae\u90fd\u4f9d\u8d56\u8fd9\u4e2a\u673a\u5236\u3002\u8fd9\u4e9b\u534f\u8bae\u662f\u5f88\u590d\u6742\u7684\uff0c\u5b83\u4eec\u628a\u8fde\u63a5\u4fe1\u606f\u653e\u5728\u6570\u636e\u5305\u91cc\uff0c\u5e76\u4e14\u8981\u6c42\u8fd9\u4e9b\u4fe1\u606f\u80fd\u88ab\u6b63\u786e\u7406\u89e3\u3002<\/p>\n<\/li>\n<li>\n<p>INVALID\uff1aINVALID \u8bf4\u660e\u6570\u636e\u5305\u4e0d\u80fd\u88ab\u8bc6\u522b\u5c5e\u4e8e\u54ea\u4e2a\u8fde\u63a5\u6216\u6ca1\u6709\u4efb\u4f55\u72b6\u6001\u3002\u6709\u51e0\u4e2a\u539f\u56e0\u53ef\u4ee5\u4ea7\u751f\u8fd9\u79cd\u60c5\u51b5\uff0c\u6bd4\u5982\uff0c\u5185\u5b58\u6ea2\u51fa\uff0c\u6536\u5230\u4e0d\u77e5\u5c5e\u4e8e\u54ea\u4e2a\u8fde\u63a5\u7684 ICMP \u9519\u8bef\u4fe1\u606f\u3002\u4e00\u822c\u5730\uff0c\u6211\u4eec DROP \u8fd9\u4e2a\u72b6\u6001\u7684\u4efb\u4f55\u4e1c\u897f\uff0c\u56e0\u4e3a\u9632\u706b\u5899\u8ba4\u4e3a\u8fd9\u662f\u4e0d\u5b89\u5168\u7684\u4e1c\u897f\u3002<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u66f4\u8be6\u7ec6\u7684\u89e3\u91ca\u89c1<a class=\"link\" href=\"http:\/\/os.51cto.com\/art\/201108\/285209.htm\" target=\"_blank\" rel=\"noopener\"\n>\u6b64\u6587<\/a><\/strong><\/p>\n<h3 id=\"\u767d\u540d\u5355\u8fc7\u6ee4\u914d\u7f6e\u65b9\u6cd5\">\u767d\u540d\u5355\u8fc7\u6ee4\u914d\u7f6e\u65b9\u6cd5<\/h3>\n<ol>\n<li>\u521b\u5efa\u767d\u540d\u5355<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -N whitelist\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -A whitelist -s 127.0.0.1 -j ACCEPT\n<\/span><\/span><\/code><\/pre><\/div><ol start=\"2\">\n<li>\u6307\u5b9a\u89c4\u5219<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -A INPUT -p tcp -m tcp --dport <span class=\"m\">3306<\/span> -j whitelist\n<\/span><\/span><\/code><\/pre><\/div><ol start=\"3\">\n<li>\u5728\u6240\u4ee5\u89c4\u5219\u6700\u540e\u52a0\u4e0a<\/li>\n<\/ol>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited\n<\/span><\/span><\/code><\/pre><\/div><p>\u8fd9\u6761\u89c4\u5219\u8868\u793a\u62d2\u7edd\u672a\u5339\u914d\u5230\u5176\u4ed6\u89c4\u5219\u7684\u5305<\/p>\n<p>\u5176\u4e2d &ndash;reject-with \u53ef\u4ee5\u6709\u5982\u4e0b\u51e0\u79cd\u503c<\/p>\n<p>icmp-net-unreachable<\/p>\n<p>icmp-host-unreachable<\/p>\n<p>icmp-port-unreachable<\/p>\n<p>icmp-proto-unreachable<\/p>\n<p>icmp-net-prohibited<\/p>\n<p>icmp-host-prohibited or icmp-admin-prohibited<\/p>\n<p>\u6ce8\uff1a<\/p>\n<ol>\n<li>\n<p>\u5ffd\u7565\u7f51\u7edc\u95ee\u9898\u7684\u60c5\u51b5\u4e0b <code>DROP<\/code> \u548c <code>REJECT<\/code> \u5206\u522b\u5bf9\u5e94 <code>ERR_CONNECTION_TIMEOUT<\/code> \u548c <code>ERR_CONNECTION_REFUSED<\/code> \uff0ciptables \u5e2e\u52a9\u6587\u6863\u4e2d\u7684\u89e3\u91ca\uff1aThis (mean REJECT) is used to send back an error packet in response to the matched packet: otherwise, it is equivalent to DROP<\/p>\n<\/li>\n<li>\n<p>\u7f16\u8f91\u89c4\u5219\u7684\u539f\u5219\uff1a\u653e\u884c\u7684\u8981\u5148\u653e\u5728\u524d\u9762, \u7981\u6b62\u7684\u8981\u653e\u5728\u6700\u540e<\/p>\n<\/li>\n<\/ol>"},{"title":"\u539f\u751f\u5b89\u5353 WiFi 4G \u4fe1\u53f7\u53bb\u53f9\u53f7\u53bb\u53c9\u6559\u7a0b","link":"https:\/\/blog.lv5.moe\/p\/native-android-wifi-4g-signal-exclamation-defork-tutorial","pubDate":"Tue, 30 Oct 2018 16:13:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/native-android-wifi-4g-signal-exclamation-defork-tutorial","description":"<p>\u9002\u7528\u4e8e 7.1.2+ :<\/p>\n<p>\u6b64\u7248\u672c\u670d\u52a1\u5668\u5730\u5740\u5224\u65ad\u903b\u8f91\u76f8\u6bd4 7.1.1 \u6ca1\u6709\u66f4\u6539\uff0c\u4f46\u662f\u68c0\u6d4b\u7684\u5f00\u5173\u5374\u53d8\u4e86\u3002<\/p>\n<p>\u68c0\u6d4b\u5f00\u5173\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u5220\u9664\u53d8\u91cf\uff1a\uff08\u5220\u9664\u4ee5\u540e\u9ed8\u8ba4\u542f\u7528\uff09\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings delete global captive_portal_mode\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u5173\u95ed\u68c0\u6d4b\uff1a\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings put global captive_portal_mode <span class=\"m\">0<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u67e5\u770b\u5f53\u524d\u72b6\u6001\uff1a\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings get global captive_portal_mode\n<\/span><\/span><\/code><\/pre><\/div><p>\u670d\u52a1\u5668\u5730\u5740\u76f8\u5173\uff08\u540c 7.1.1\uff09\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\"><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u5220\u9664\uff08\u5220\u9664\u9ed8\u8ba4\u7528HTTPS\uff09\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings delete global captive_portal_https_url\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings delete global captive_portal_http_url\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\u5206\u522b\u4fee\u6539\u4e24\u4e2a\u5730\u5740\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings put global captive_portal_http_url http:\/\/captive.v2ex.co\/generate_204\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">adb shell settings put global captive_portal_https_url https:\/\/captive.v2ex.co\/generate_204\n<\/span><\/span><\/code><\/pre><\/div><blockquote>\n<p>\u8f6c\u8f7d\u81ea <a class=\"link\" href=\"https:\/\/www.evil42.com\/index.php\/archives\/17\/\" target=\"_blank\" rel=\"noopener\"\n>\u539f\u751f\u5b89\u5353 WiFi \u4fe1\u53f7\u53bb\u53f9\u53f7\u53bb\u53c9\u6559\u7a0b 5.0-Android P<\/a>\uff0c\u4fb5\u5220<\/p>\n<\/blockquote>"},{"title":"Laravel \u4e2d\u89c6\u56fe view() \u4e0e\u91cd\u5b9a\u5411 redirect() \u7684\u4f7f\u7528","link":"https:\/\/blog.lv5.moe\/p\/use-of-view-and-redirect-in-laravel","pubDate":"Tue, 04 Sep 2018 12:46:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/use-of-view-and-redirect-in-laravel","description":"<h2 id=\"\u4e00-view-\u7684\u4f7f\u7528\">\u4e00\u3001 view() \u7684\u4f7f\u7528<\/h2>\n<ol>\n<li>\n<p>\u7b80\u5355\u7684\u8fd4\u56de\u89c6\u56fe<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u6240\u4f20\u7684\u53c2\u6570\u662fblade\u6a21\u677f\u7684\u8def\u5f84\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u5982\u679c\u76ee\u5f55\u662f resources\/views\/static_pages\/home.blade.php \u5219\u53ef\u4ee5\u4f7f\u7528\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">return<\/span> <span class=\"nx\">view<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;static_pages\/home&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nx\">\u6216<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">return<\/span> <span class=\"nx\">view<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;static_pages.home&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u5411\u89c6\u56fe\u4f20\u9012\u6570\u636e<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$title<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">&#39;Hello Laravel&#39;<\/span><span class=\"p\">;<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"nv\">$user<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">User<\/span><span class=\"o\">::<\/span><span class=\"na\">find<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ view() \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u63a5\u53d7\u4e00\u4e2a\u6570\u7ec4\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">return<\/span> <span class=\"nx\">view<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;static_pages\/home&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">compact<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;user&#39;<\/span><span class=\"p\">));<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"k\">return<\/span> <span class=\"nx\">view<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;articles.lists&#39;<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">with<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;title&#39;<\/span><span class=\"p\">,<\/span><span class=\"nv\">$title<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u6240\u4f20\u9012\u7684\u53d8\u91cf\u5728blade\u6a21\u677f\u4e2d\u7528 {{ $title }} \u6216 {!! $title !!} \u8f93\u51fa\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u524d\u8005\u4f5c\u4e3a\u6587\u672c\u8f93\u51fa\uff0c\u540e\u8005\u4f5c\u4e3a\u9875\u9762\u5143\u7d20\u6e32\u67d3\n<\/span><\/span><\/span><\/code><\/pre><\/div><\/li>\n<\/ol>\n<h2 id=\"\u4e8credirect-\u7684\u4f7f\u7528\">\u4e8c\u3001redirect() \u7684\u4f7f\u7528<\/h2>\n<ol>\n<li>\n<p>\u57fa\u4e8e Url \u7684\u91cd\u5b9a\u5411<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u5047\u8bbe\u6211\u4eec\u5f53\u524d\u7684\u57df\u540d\u4e3a\uff1ahttp:\/\/localhost \u5219\u91cd\u5b9a\u5411\u5230 http:\/\/localhost\/home\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u57fa\u4e8e\u8def\u7531\u7684\u91cd\u5b9a\u5411<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">route<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u57fa\u4e8e\u63a7\u5236\u5668\u7684\u91cd\u5b9a\u5411<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">action<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;UserController@index&#39;<\/span><span class=\"p\">)<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u4f20\u9012\u6570\u636e<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">with<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;title&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;Hello Laravel&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u5c06\u8868\u5355\u503c\u4fdd\u5b58\u5230 Session \u4e2d\uff0c\u53ef\u4ee5\u7528 {{ old(&#39;param&#39;) }} \u6765\u83b7\u53d6\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">withInput<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u63a5\u6536\u4e00\u4e2a\u5b57\u7b26\u4e32\u6216\u6570\u7ec4\uff0c\u4f20\u9012\u7684\u53d8\u91cf\u540d\u4e3a $errors\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"k\">return<\/span> <span class=\"nx\">redirect<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">withErrors<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Error&#39;<\/span><span class=\"p\">);<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u5176\u4ed6\u7528\u6cd5<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-php\" data-lang=\"php\"><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u8fd4\u56de\u767b\u5f55\u524d\u7684\u9875\u9762\uff0c\u53c2\u6570\u4e3a\u9ed8\u8ba4\u8df3\u8f6c\u7684\u9875\u9762\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"nx\">redirect<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">intended<\/span><span class=\"p\">(<\/span><span class=\"nx\">route<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;home&#39;<\/span><span class=\"p\">));<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\">\/\/ \u8fd4\u56de\u4e0a\u4e00\u4e2a\u9875\u9762\uff0c\u6ce8\u610f\u907f\u514d\u6b7b\u5faa\u73af\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"c1\"><\/span><span class=\"nx\">redirect<\/span><span class=\"p\">()<\/span><span class=\"o\">-&gt;<\/span><span class=\"na\">back<\/span><span class=\"p\">();<\/span>\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<\/ol>\n<h2 id=\"\u4e09\u4f7f\u7528-view-\u6216-redirect-\u7684\u9009\u62e9\">\u4e09\u3001\u4f7f\u7528 view() \u6216 redirect() \u7684\u9009\u62e9<\/h2>\n<h3 id=\"view-\u548c-redirect-\u7684\u5f02\u540c\">view() \u548c redirect() \u7684\u5f02\u540c<\/h3>\n<p>\u200b \u4f7f\u7528 <code>return view()<\/code> \u4e0d\u4f1a\u6539\u53d8\u5f53\u524d\u8bbf\u95ee\u7684 url \uff0c <code>return redirect()<\/code> \u4f1a\u6539\u53d8\u6539\u53d8\u5f53\u524d\u8bbf\u95ee\u7684 url<\/p>\n<p>\u200b \u4f7f\u7528 <code>return view()<\/code> \u4e0d\u4f1a\u4f7f\u5f53\u524d Session \u7684 Flash \u5931\u6548 \uff0c\u4f46\u662f <code>return redirect()<\/code> \u4f1a\u4f7f Flash \u5931\u6548<\/p>\n<p>\u200b \u5728 RESTful \u67b6\u6784\u4e2d\uff0c\u8bbf\u95ee <code>Get<\/code> \u65b9\u6cd5\u65f6\u63a8\u8350\u4f7f\u7528 <code>return view()<\/code> \uff0c\u8bbf\u95ee\u5176\u4ed6\u65b9\u6cd5\u63a8\u8350\u4f7f\u7528 <code>return redirect()<\/code><\/p>"},{"title":"MySQL \u5f00\u542f\u8fdc\u7a0b\u8bbf\u95ee\u5b8c\u5168\u89e3\u51b3\u65b9\u6848","link":"https:\/\/blog.lv5.moe\/p\/mysql-open-remote-access-complete-solution","pubDate":"Tue, 04 Sep 2018 11:02:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/mysql-open-remote-access-complete-solution","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/mysql-open-remote-access-complete-solution\/security-groups.jpg\" alt=\"Featured image of post MySQL \u5f00\u542f\u8fdc\u7a0b\u8bbf\u95ee\u5b8c\u5168\u89e3\u51b3\u65b9\u6848\" \/><h2 id=\"\u9002\u7528\u73af\u5883\">\u9002\u7528\u73af\u5883<\/h2>\n<ul>\n<li>MySQL 5.7<\/li>\n<li>Ubuntu 16.04<\/li>\n<\/ul>\n<p>( \u9002\u7528\u4f46\u4e0d\u9650\u4e8e\u4ee5\u4e0a\u73af\u5883 \uff09<\/p>\n<h2 id=\"\u64cd\u4f5c\u6b65\u9aa4\">\u64cd\u4f5c\u6b65\u9aa4<\/h2>\n<h3 id=\"\u4e00\u5f00\u542f-mysql-\u8fdc\u7a0b\u8bbf\u95ee\u6743\u9650\">\u4e00\u3001\u5f00\u542f MySQL \u8fdc\u7a0b\u8bbf\u95ee\u6743\u9650<\/h3>\n<p>\u5c06 mysql.host \u5b57\u6bb5\u7684\u503c\u6539\u4e3a % \u5c31\u8868\u793a\u80fd\u5728\u4efb\u4f55\u5ba2\u6237\u7aef\u673a\u5668\u4e0a\u767b\u5f55\u5230 MySQL \u670d\u52a1\u5668<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-sql\" data-lang=\"sql\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"n\">use<\/span><span class=\"w\"> <\/span><span class=\"n\">mysql<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"k\">Database<\/span><span class=\"w\"> <\/span><span class=\"n\">changed<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"k\">grant<\/span><span class=\"w\"> <\/span><span class=\"k\">all<\/span><span class=\"w\"> <\/span><span class=\"k\">privileges<\/span><span class=\"w\"> <\/span><span class=\"k\">on<\/span><span class=\"w\"> <\/span><span class=\"o\">*<\/span><span class=\"p\">.<\/span><span class=\"o\">*<\/span><span class=\"w\"> <\/span><span class=\"k\">to<\/span><span class=\"w\"> <\/span><span class=\"n\">username<\/span><span class=\"w\"> <\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;%&#39;<\/span><span class=\"w\"> <\/span><span class=\"n\">identified<\/span><span class=\"w\"> <\/span><span class=\"k\">by<\/span><span class=\"w\"> <\/span><span class=\"s2\">&#34;password&#34;<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">Query<\/span><span class=\"w\"> <\/span><span class=\"n\">OK<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"w\"> <\/span><span class=\"k\">rows<\/span><span class=\"w\"> <\/span><span class=\"n\">affected<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">00<\/span><span class=\"w\"> <\/span><span class=\"n\">sec<\/span><span class=\"p\">)<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"n\">flush<\/span><span class=\"w\"> <\/span><span class=\"k\">privileges<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">Query<\/span><span class=\"w\"> <\/span><span class=\"n\">OK<\/span><span class=\"p\">,<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"w\"> <\/span><span class=\"k\">rows<\/span><span class=\"w\"> <\/span><span class=\"n\">affected<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">00<\/span><span class=\"w\"> <\/span><span class=\"n\">sec<\/span><span class=\"p\">)<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"o\">\/\/<\/span><span class=\"err\">\u6216\u8005\u65b0\u5efa\u4e00\u4e2a\u7528\u6237\u5e76\u6388\u6743\uff0c\u53ea\u8981\u8bbe\u7f6e<\/span><span class=\"w\"> <\/span><span class=\"k\">host<\/span><span class=\"w\"> <\/span><span class=\"err\">\u4e3a<\/span><span class=\"w\"> <\/span><span class=\"o\">%<\/span><span class=\"w\"> <\/span><span class=\"err\">\u5373\u53ef<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"k\">CREATE<\/span><span class=\"w\"> <\/span><span class=\"k\">USER<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;username&#39;<\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;host&#39;<\/span><span class=\"w\"> <\/span><span class=\"n\">IDENTIFIED<\/span><span class=\"w\"> <\/span><span class=\"k\">BY<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;password&#39;<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"k\">GRANT<\/span><span class=\"w\"> <\/span><span class=\"k\">ALL<\/span><span class=\"w\"> <\/span><span class=\"k\">privileges<\/span><span class=\"w\"> <\/span><span class=\"k\">ON<\/span><span class=\"w\"> <\/span><span class=\"n\">databasename<\/span><span class=\"p\">.<\/span><span class=\"n\">tablename<\/span><span class=\"w\"> <\/span><span class=\"k\">TO<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;username&#39;<\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;host&#39;<\/span><span class=\"p\">;<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">flush<\/span><span class=\"w\"> <\/span><span class=\"k\">privileges<\/span><span class=\"p\">;<\/span><span class=\"o\">\/\/<\/span><span class=\"err\">\u5982\u679c\u6388\u6743\u672a\u751f\u6548\u624b\u52a8\u91cd\u542f<\/span><span class=\"w\"> <\/span><span class=\"n\">mysql<\/span><span class=\"w\"> <\/span><span class=\"err\">\u670d\u52a1\u5373\u53ef<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u4fee\u6539\u5bc6\u7801\u7684\u65b9\u6cd5\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-sql\" data-lang=\"sql\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">mysql<\/span><span class=\"o\">&gt;<\/span><span class=\"w\"> <\/span><span class=\"k\">SET<\/span><span class=\"w\"> <\/span><span class=\"n\">PASSWORD<\/span><span class=\"w\"> <\/span><span class=\"k\">FOR<\/span><span class=\"w\"> <\/span><span class=\"s1\">&#39;username&#39;<\/span><span class=\"o\">@<\/span><span class=\"s1\">&#39;host&#39;<\/span><span class=\"w\"> <\/span><span class=\"o\">=<\/span><span class=\"w\"> <\/span><span class=\"n\">PASSWORD<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;newpass&#39;<\/span><span class=\"p\">);<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><h3 id=\"\u4e8c-\u68c0\u67e5-mysql-\u914d\u7f6e\">\u4e8c\u3001 \u68c0\u67e5 MySQL \u914d\u7f6e<\/h3>\n<p>\u67e5\u770b MySQL \u670d\u52a1\u7ed1\u5b9a\u7684\u5730\u5740\uff1a<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-sql\" data-lang=\"sql\"><span class=\"line\"><span class=\"cl\"><span class=\"n\">ubuntu<\/span><span class=\"p\">:<\/span><span class=\"o\">~<\/span><span class=\"err\">$<\/span><span class=\"w\"> <\/span><span class=\"n\">netstat<\/span><span class=\"w\"> <\/span><span class=\"o\">-<\/span><span class=\"n\">ano<\/span><span class=\"w\"> <\/span><span class=\"o\">|<\/span><span class=\"w\"> <\/span><span class=\"n\">grep<\/span><span class=\"w\"> <\/span><span class=\"mi\">3306<\/span><span class=\"w\">\n<\/span><\/span><\/span><span class=\"line\"><span class=\"cl\"><span class=\"w\"><\/span><span class=\"n\">tcp<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">:<\/span><span class=\"mi\">3306<\/span><span class=\"w\"> <\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">0<\/span><span class=\"p\">:<\/span><span class=\"o\">*<\/span><span class=\"w\"> <\/span><span class=\"k\">LISTEN<\/span><span class=\"w\"> <\/span><span class=\"k\">off<\/span><span class=\"w\"> <\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">.<\/span><span class=\"mi\">00<\/span><span class=\"o\">\/<\/span><span class=\"mi\">0<\/span><span class=\"o\">\/<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span><span class=\"w\">\n<\/span><\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c\u4e0d\u662f\u5982\u4e0a\u6240\u793a\uff08\u7ed1\u5b9a\u5728 0.0.0.0:3306\uff09\uff0c\u90a3\u4e48\u5c31\u9700\u8981\u66f4\u6539 <code>\/etc\/my.cnf<\/code> \u4e2d\u7684\u914d\u7f6e\uff0c\u4fee\u6539\u4e0b\u9762\u4e00\u884c<\/p>\n<p><code>bind-address = 0.0.0.0<\/code><\/p>\n<h3 id=\"\u4e09-\u68c0\u67e5\u9632\u706b\u5899\u914d\u7f6e\">\u4e09\u3001 \u68c0\u67e5\u9632\u706b\u5899\u914d\u7f6e<\/h3>\n<ol>\n<li>\n<p>\u5728 <code>\u63a7\u5236\u9762\u677f\\\u7cfb\u7edf\u548c\u5b89\u5168\\Windows Defender \u9632\u706b\u5899<\/code> \u4e2d\u5173\u6389 Windows \u9632\u706b\u5899<\/p>\n<\/li>\n<li>\n<p>\u68c0\u67e5\u670d\u52a1\u5668\u4e0a\u7684\u9632\u706b\u5899<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">ubuntu:~$ sudo iptables -L -n\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Chain INPUT <span class=\"o\">(<\/span>policy ACCEPT<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">target prot opt <span class=\"nb\">source<\/span> destination\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT all -- 0.0.0.0\/0 0.0.0.0\/0\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT all -- 0.0.0.0\/0 0.0.0.0\/0 state RELATED,ESTABLISHED\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:22\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:21\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:2111\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpts:5500:5600\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:80\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:443\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT tcp -- 0.0.0.0\/0 0.0.0.0\/0 tcp dpt:3306\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ACCEPT icmp -- 0.0.0.0\/0 0.0.0.0\/0 icmptype <span class=\"m\">8<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Chain FORWARD <span class=\"o\">(<\/span>policy ACCEPT<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">target prot opt <span class=\"nb\">source<\/span> destination\n<\/span><\/span><span class=\"line\"><span class=\"cl\">\n<\/span><\/span><span class=\"line\"><span class=\"cl\">Chain OUTPUT <span class=\"o\">(<\/span>policy ACCEPT<span class=\"o\">)<\/span>\n<\/span><\/span><span class=\"line\"><span class=\"cl\">target prot opt <span class=\"nb\">source<\/span> destination\n<\/span><\/span><\/code><\/pre><\/div><p>\u5982\u679c MySQL \u76d1\u542c\u7684\u7aef\u53e3\uff08\u9ed8\u8ba4 3306\uff09\u88ab\u8bbe\u7f6e\u6210 DROP \u5219\u9700\u8981\u6539\u6210 ACCEPT<\/p>\n<div class=\"highlight\"><pre tabindex=\"0\" class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"line\"><span class=\"cl\">ubuntu:~$ sudo vim \/etc\/iptables.rules\n<\/span><\/span><span class=\"line\"><span class=\"cl\">ubuntu:~$ sudo iptables-restore &lt; \/etc\/iptables.rules\n<\/span><\/span><\/code><\/pre><\/div><\/li>\n<li>\n<p>\u68c0\u67e5\u670d\u52a1\u5546\u63d0\u4f9b\u7684\u5b89\u5168\u7ec4\u8bbe\u7f6e\uff0c\u5f00\u653e\u5bf9\u5e94\u7684\u7aef\u53e3<\/p>\n<\/li>\n<\/ol>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 424;\nflex-basis: 1018px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/mysql-open-remote-access-complete-solution\/security-groups.jpg\" data-size=\"1455x343\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/mysql-open-remote-access-complete-solution\/security-groups.jpg\"\nwidth=\"1455\"\nheight=\"343\"\nloading=\"lazy\"\nalt=\"\u5b89\u5168\u7ec4\">\n<\/a>\n<figcaption>\u5b89\u5168\u7ec4<\/figcaption>\n<\/figure><\/p>"},{"title":"Android 7.0 \u4e4b\u540e\u6293\u5305 unknown \u548c\u8bc1\u4e66\u65e0\u6548\u7684\u89e3\u51b3\u65b9\u6848","link":"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7","pubDate":"Fri, 30 Mar 2018 14:04:00 +0800","guid":"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7","description":"<img src=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/ssl-handshake-failed.jpg\" alt=\"Featured image of post Android 7.0 \u4e4b\u540e\u6293\u5305 unknown \u548c\u8bc1\u4e66\u65e0\u6548\u7684\u89e3\u51b3\u65b9\u6848\" \/><h2 id=\"\u80cc\u666f\">\u80cc\u666f<\/h2>\n<p>\u4f7f\u7528\u6293\u5305\u8f6f\u4ef6\uff08\u4ee5 Charles \u4e3a\u4f8b\uff09\u6293\u53d6 APP \u7684 https \u8bf7\u6c42\u65f6\uff0cAndroid \u548c Charles \u90fd\u6b63\u786e\u5b89\u88c5\u4e86\u8bc1\u4e66\u5374\u51fa\u73b0\u6293\u5305\u5931\u8d25\uff0c\u62a5\u9519\uff1a<\/p>\n<p>Client SSL handshake failed: An unknown issue occurred processing the certificate (certificate_unknown)<br \/>\n<figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 164;\nflex-basis: 394px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/ssl-handshake-failed.jpg\" data-size=\"1147x698\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/ssl-handshake-failed.jpg\"\nwidth=\"1147\"\nheight=\"698\"\nloading=\"lazy\"\nalt=\"\u6293\u5305\u5931\u8d25\">\n<\/a>\n<figcaption>\u6293\u5305\u5931\u8d25<\/figcaption>\n<\/figure><\/p>\n<h2 id=\"\u539f\u56e0\">\u539f\u56e0<\/h2>\n<p>Android7.0 \u4e4b\u540e\u9ed8\u8ba4\u4e0d\u4fe1\u4efb\u7528\u6237\u6dfb\u52a0\u5230\u7cfb\u7edf\u7684 CA \u8bc1\u4e66\uff1a<\/p>\n<blockquote>\n<p>To provide a more consistent and more secure experience across the Android ecosystem, beginning with Android Nougat, compatible devices trust only the standardized system CAs maintained in AOSP.\uff08<a class=\"link\" href=\"https:\/\/android-developers.googleblog.com\/2016\/07\/changes-to-trusted-certificate.html\" target=\"_blank\" rel=\"noopener\"\n>\u6587\u6863\u94fe\u63a5<\/a>\uff09<\/p>\n<\/blockquote>\n<p>\u4e5f\u5c31\u662f\u8bf4\u5bf9\u57fa\u4e8e SDK24 \u53ca\u4ee5\u4e0a\u7684 APP \u6765\u8bf4\uff0c\u5373\u4f7f\u4f60\u5728\u624b\u673a\u4e0a\u5b89\u88c5\u4e86\u6293\u5305\u5de5\u5177\u7684\u8bc1\u4e66\u4e5f\u65e0\u6cd5\u6293\u53d6 https \u8bf7\u6c42<\/p>\n<h2 id=\"\u89e3\u51b3\u65b9\u6848\">\u89e3\u51b3\u65b9\u6848<\/h2>\n<h3 id=\"\u4e00\u5b98\u65b9\u89e3\u51b3\u65b9\u6848\u9700\u4fee\u6539\u4ee3\u7801\">\u4e00\u3001\u5b98\u65b9\u89e3\u51b3\u65b9\u6848\uff08\u9700\u4fee\u6539\u4ee3\u7801\uff09<\/h3>\n<ul>\n<li>\u5b98\u65b9\u6587\u6863\uff1ahttps:\/\/developer.android.google.cn\/training\/articles\/security-config.html<\/li>\n<li>\u8be6\u7ec6\u6f14\u793a\uff1ahttps:\/\/blog.csdn.net\/mrxiagc\/article\/details\/75329629<\/li>\n<\/ul>\n<h3 id=\"\u4e8c\u5c06\u6293\u5305\u8f6f\u4ef6\u7684\u8bc1\u4e66\u5b89\u88c5\u6210\u7cfb\u7edf\u8bc1\u4e66\u9700-root\">\u4e8c\u3001\u5c06\u6293\u5305\u8f6f\u4ef6\u7684\u8bc1\u4e66\u5b89\u88c5\u6210\u7cfb\u7edf\u8bc1\u4e66\uff08\u9700 ROOT\uff09<\/h3>\n<p>\u7cfb\u7edf\u8bc1\u4e66\u76ee\u5f55\uff1a<code>\/system\/etc\/security\/cacerts\/<\/code><\/p>\n<p>\u5176\u4e2d\u7684\u6bcf\u4e2a\u8bc1\u4e66\u7684\u547d\u540d\u89c4\u5219\u5982\u4e0b\uff1a<br \/>\n<code>&lt;Certificate_Hash&gt;.&lt;Number&gt; <\/code><br \/>\n\u6587\u4ef6\u540d\u662f\u4e00\u4e2a Hash \u503c\uff0c\u800c\u540e\u7f00\u662f\u4e00\u4e2a\u6570\u5b57\u3002<\/p>\n<p>\u6587\u4ef6\u540d\u53ef\u4ee5\u7528\u4e0b\u9762\u7684\u547d\u4ee4\u8ba1\u7b97\u51fa\u6765\uff1a<\/p>\n<p><code>openssl x509 -subject_hash_old -in &lt;Certificate_File&gt;<\/code><\/p>\n<p>\u540e\u7f00\u540d\u7684\u6570\u5b57\u662f\u4e3a\u4e86\u9632\u6b62\u6587\u4ef6\u540d\u51b2\u7a81\u7684\uff0c\u6bd4\u5982\u5982\u679c\u4e24\u4e2a\u8bc1\u4e66\u7b97\u51fa\u7684 Hash \u503c\u662f\u4e00\u6837\u7684\u8bdd\uff0c\u90a3\u4e48\u4e00\u4e2a\u8bc1\u4e66\u7684\u540e\u7f00\u540d\u6570\u5b57\u53ef\u4ee5\u8bbe\u7f6e\u6210 0\uff0c\u800c\u53e6\u4e00\u4e2a\u8bc1\u4e66\u7684\u540e\u7f00\u540d\u6570\u5b57\u53ef\u4ee5\u8bbe\u7f6e\u6210 1<\/p>\n<h4 id=\"\u64cd\u4f5c\u6b65\u9aa4\">\u64cd\u4f5c\u6b65\u9aa4\uff1a<\/h4>\n<p>\u5c06\u6293\u5305\u8f6f\u4ef6\u7684\u8bc1\u4e66\u7528\u4e0a\u8ff0\u547d\u4ee4\u8ba1\u7b97\u51fa Hash \u503c\uff0c\u5c06\u5176\u6539\u540d\u5e76\u590d\u5236\u5230\u7cfb\u7edf\u8bc1\u4e66\u76ee\u5f55<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 429;\nflex-basis: 1031px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/cal-hash.jpg\" data-size=\"460x107\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/cal-hash.jpg\"\nwidth=\"460\"\nheight=\"107\"\nloading=\"lazy\"\nalt=\"\u8ba1\u7b97 Hash \u503c\">\n<\/a>\n<figcaption>\u8ba1\u7b97 Hash \u503c<\/figcaption>\n<\/figure><\/p>\n<p>\u6b64\u65f6\u4f60\u5e94\u8be5\u53ef\u4ee5\u5728 \u8bbe\u7f6e-&gt;\u5b89\u5168-&gt;\u52a0\u5bc6\u4e0e\u51ed\u636e-&gt;\u4fe1\u4efb\u7684\u51ed\u636e \u7684\u7cfb\u7edf\u6807\u7b7e\u9875\u770b\u5230\u4f60\u65b0\u52a0\u5165\u7684\u8bc1\u4e66\uff0c\u5c06\u5176\u542f\u7528\u5373\u53ef\u987a\u5229\u6293\u5305<\/p>\n<p><figure\nclass=\"gallery-image\"\nstyle=\"\nflex-grow: 58;\nflex-basis: 140px\"\n>\n<a href=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/install-ca-certificate.jpg\" data-size=\"280x477\">\n<img src=\"https:\/\/blog.lv5.moe\/p\/solutions-to-certificate-invalidation-after-android-7\/install-ca-certificate.jpg\"\nwidth=\"280\"\nheight=\"477\"\nloading=\"lazy\"\nalt=\"\u5b89\u88c5\u597d\u7684CA\u8bc1\u4e66\">\n<\/a>\n<figcaption>\u5b89\u88c5\u597d\u7684CA\u8bc1\u4e66<\/figcaption>\n<\/figure><\/p>"}]}}