{"id":1708,"date":"2025-12-27T23:45:50","date_gmt":"2025-12-27T15:45:50","guid":{"rendered":"https:\/\/eve2333.top\/?p=1708"},"modified":"2025-12-27T23:45:51","modified_gmt":"2025-12-27T15:45:51","slug":"%e5%8a%a8%e6%80%81%e7%ba%bf%e7%a8%8b%e6%b1%a0onethread%e7%b3%bb%e7%bb%9f-%e7%ac%ac%e5%8d%81%e4%b8%80%e9%83%a8%e5%88%86-%e7%ba%bf%e7%a8%8b%e6%b1%a0%e7%9b%91%e6%8e%a7","status":"publish","type":"post","link":"https:\/\/eve2333.top\/?p=1708","title":{"rendered":"\u52a8\u6001\u7ebf\u7a0b\u6c60oneThread\u7cfb\u7edf \u2014 \u7b2c\u5341\u4e00\u90e8\u5206 \u7ebf\u7a0b\u6c60\u76d1\u63a7"},"content":{"rendered":"\n<p>\u867d\u7136\u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7<strong>\u62d2\u7edd\u7b56\u7565\u544a\u8b66\u3001\u7ebf\u7a0b\u6d3b\u8dc3\u5ea6\u544a\u8b66\u3001\u961f\u5217\u4f7f\u7528\u7387\u544a\u8b66<\/strong> \u7b49\u673a\u5236\u53ca\u65f6\u53d1\u73b0\u90e8\u5206\u5f02\u5e38\uff0c\u4f46<strong>\u5982\u679c\u7f3a\u4e4f\u5bf9\u7ebf\u7a0b\u6c60\u8fd0\u884c\u72b6\u6001\u7684\u6301\u7eed\u89c2\u6d4b\u4e0e\u6570\u636e\u5206\u6790\u80fd\u529b<\/strong> \uff0c\u5f88\u591a\u95ee\u9898\u4f9d\u7136\u96be\u4ee5\u6df1\u5165\u7406\u89e3\u3002\u8fd9\u4e9b\u90fd\u9700\u8981\u4f9d\u8d56<strong>\u7ec6\u7c92\u5ea6\u7684\u6307\u6807\u76d1\u63a7\u548c\u8d8b\u52bf\u5206\u6790<\/strong>\u6240\u4ee5\u6211\u4eec\u5f3a\u8c03\uff0c\u7ebf\u7a0b\u6c60\u76d1\u63a7\u4e0d\u662f\u53ea\u4e3a\u4e86\u62a5\u8b66\uff0c\u5b83\u66f4\u91cd\u8981\u7684\u4ef7\u503c\u5728\u4e8e\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6d1e\u5bdf\u7cfb\u7edf\u74f6\u9888<\/strong> \uff1a\u6bd4\u5982\u662f\u5426\u5b58\u5728\u67d0\u4e9b\u4efb\u52a1\u6267\u884c\u65f6\u95f4\u5f02\u5e38\u62c9\u957f\uff0c\u5f71\u54cd\u6574\u4f53\u8c03\u5ea6\u6548\u7387\u3002<\/li>\n\n\n\n<li><strong>\u8f85\u52a9\u5b9a\u4f4d\u95ee\u9898<\/strong> \uff1a\u51fa\u6545\u969c\u65f6\uff0c\u80fd\u770b\u5230\u662f\u7ebf\u7a0b\u6570\u6253\u6ee1\u4e86\uff0c\u8fd8\u662f\u961f\u5217\u5806\u79ef\u4e86\uff1b<\/li>\n\n\n\n<li><strong>\u652f\u6301\u5bb9\u91cf\u89c4\u5212<\/strong> \uff1a\u901a\u8fc7\u957f\u671f\u8d8b\u52bf\u5224\u65ad\u7ebf\u7a0b\u6c60\u914d\u7f6e\u662f\u5426\u5408\u7406\uff1b<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u6838\u5fc3\u67b6\u6784\u5206\u5c42\u89e3\u6790<\/h3>\n\n\n\n<p>\u6839\u636e\u4f60\u63d0\u4f9b\u7684\u67b6\u6784\u56fe\uff0c\u6211\u4eec\u5c06\u4ee3\u7801\u62c6\u5206\u4e3a\u4e09\u4e2a\u4e3b\u8981\u5c42\u6b21\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"629\" src=\"https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766817274-image.png\" alt=\"\" class=\"wp-image-1714\" srcset=\"https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766817274-image.png 722w, https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766817274-image-300x261.png 300w\" sizes=\"auto, (max-width: 722px) 100vw, 722px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">A. \u76d1\u63a7\u914d\u7f6e\u5c42 (Configuration Layer)<\/h4>\n\n\n\n<p><strong>\u4ee3\u7801\u6587\u4ef6<\/strong>\uff1a<code>BootstrapConfigProperties.java<\/code><br><strong>\u4f5c\u7528<\/strong>\uff1a\u63a7\u5236\u76d1\u63a7\u7684\u201c\u5f00\u5173\u201d\u548c\u201c\u8282\u594f\u201d\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u8bbe\u8ba1\u601d\u8def<\/strong>\uff1a<\/li>\n\n\n\n<li><strong>\u5f00\u5173 (<code>enable<\/code>)<\/strong>\uff1a\u751f\u4ea7\u73af\u5883\u5982\u679c\u538b\u529b\u6781\u5927\uff0c\u53ef\u80fd\u9700\u8981\u4e00\u952e\u5173\u95ed\u76d1\u63a7\uff0c\u907f\u514d\u989d\u5916\u5f00\u9500\u3002<\/li>\n\n\n\n<li><strong>\u9891\u7387 (<code>collectInterval<\/code>)<\/strong>\uff1a\u9ed8\u8ba4 5 \u79d2\u4e00\u6b21\u3002\u8fd9\u4e2a\u65f6\u95f4\u662f\u6743\u8861\u8fc7\u7684\u2014\u2014\u592a\u5feb\uff08\u5982 1s\uff09\u4f1a\u9891\u7e41\u62a2\u5360\u9501\uff0c\u5f71\u54cd\u4e1a\u52a1\u6027\u80fd\uff1b\u592a\u6162\uff08\u5982 1min\uff09\u5219\u6355\u6349\u4e0d\u5230\u77ac\u65f6\u6d41\u91cf\u6d2a\u5cf0\u3002<\/li>\n\n\n\n<li><strong>\u7c7b\u578b (<code>collectType<\/code>)<\/strong>\uff1a\u76ee\u524d\u652f\u6301 <code>log<\/code>\uff08\u672c\u5730\u65e5\u5fd7\uff09\uff0c\u9884\u7559\u4e86 <code>micrometer<\/code>\uff08Prometheus\/Grafana\uff09\uff0c\u65b9\u4fbf\u672a\u6765\u6269\u5c55\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84<\/strong>: <code>core\/src\/main\/java\/com\/nageoffer\/onethread\/core\/config\/BootstrapConfigProperties.java<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.core.config;\n\nimport lombok.Data;\n\n\/**\n * \u542f\u52a8\u914d\u7f6e\u5c5e\u6027\n *\/\n@Data\npublic class BootstrapConfigProperties {\n\n    \/\/ ... \u539f\u6709\u7684\u5c5e\u6027 ...\n\n    \/**\n     * \u76d1\u63a7\u914d\u7f6e\n     *\/\n    private MonitorConfig monitorConfig;\n\n    \/\/ \u5355\u4f8b\u6a21\u5f0f\u5b9e\u73b0\uff08\u914d\u5408\u4ee3\u7801\u4e2d\u7684 getInstance \u4f7f\u7528\uff09\n    private static final BootstrapConfigProperties INSTANCE = new BootstrapConfigProperties();\n\n    public static BootstrapConfigProperties getInstance() {\n        return INSTANCE;\n    }\n\n    @Data\n    public static class MonitorConfig {\n        \/**\n         * \u662f\u5426\u5f00\u542f\u76d1\u63a7\n         *\/\n        private Boolean enable = true;\n\n        \/**\n         * \u91c7\u96c6\u7c7b\u578b\uff1alog, micrometer\n         *\/\n        private String collectType = \"log\";\n\n        \/**\n         * \u91c7\u96c6\u95f4\u9694\uff08\u5355\u4f4d\uff1a\u79d2\uff09\n         *\/\n        private Long collectInterval = 5L;\n    }\n}<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>\u6ce8\u610f<\/strong>\uff1a\u5982\u679c\u4f60\u7684\u9879\u76ee\u662f\u7eaf Spring \u73af\u5883\uff0c\u901a\u5e38\u901a\u8fc7 <code>@ConfigurationProperties<\/code> \u6ce8\u5165\u3002\u4f46\u4e3a\u4e86\u9002\u914d\u4f60\u63d0\u4f9b\u7684 <code>ThreadPoolMonitor<\/code> \u4ee3\u7801\u4e2d <code>BootstrapConfigProperties.getInstance()<\/code> \u7684\u5199\u6cd5\uff0c\u8fd9\u91cc\u4fdd\u7559\u4e86\u5355\u4f8b\u8bbf\u95ee\u65b9\u5f0f\u3002\u5728 Spring \u542f\u52a8\u65f6\uff0c\u4f60\u9700\u8981\u786e\u4fdd\u5c06\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u503c\u6ce8\u5165\u5230\u8fd9\u4e2a\u5355\u4f8b\u5bf9\u8c61\u4e2d\uff08\u53ef\u4ee5\u5728 <code>ConfigParser<\/code> \u6216 AutoConfiguration \u4e2d\u5904\u7406\uff09\u3002<\/p>\n<\/blockquote>\n\n\n\n<p>\u5b9e\u73b0\u76d1\u63a7\u6838\u5fc3\u903b\u8f91 (<code>ThreadPoolMonitor.java<\/code>)\uff1b\u8fd9\u662f\u6838\u5fc3\u8c03\u5ea6\u7c7b\uff0c\u8d1f\u8d23\u5b9a\u65f6\u91c7\u96c6\u6570\u636e\u5e76\u8f93\u51fa\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84<\/strong>: <code>core\/src\/main\/java\/com\/nageoffer\/onethread\/core\/monitor\/ThreadPoolMonitor.java<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.core.monitor;\n\nimport com.alibaba.fastjson2.JSON;\nimport com.nageoffer.onethread.core.config.BootstrapConfigProperties;\nimport com.nageoffer.onethread.core.executor.OneThreadExecutor;\nimport com.nageoffer.onethread.core.executor.OneThreadRegistry;\nimport com.nageoffer.onethread.core.executor.ThreadPoolExecutorHolder;\nimport com.nageoffer.onethread.core.toolkit.ThreadFactoryBuilder;\nimport lombok.SneakyThrows;\nimport lombok.extern.slf4j.Slf4j;\n\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.*;\n\n\/**\n * \u7ebf\u7a0b\u6c60\u76d1\u63a7\u6267\u884c\u5668\n *\/\n@Slf4j\npublic class ThreadPoolMonitor {\n\n    private ScheduledExecutorService scheduler;\n    \/\/ \u9884\u7559\u7ed9 Micrometer \u7684\u7f13\u5b58\uff0c\u6682\u672a\u4f7f\u7528\n    private Map&lt;String, ThreadPoolRuntimeInfo&gt; micrometerMonitorCache;\n\n    \/**\n     * \u542f\u52a8\u5b9a\u65f6\u68c0\u67e5\u4efb\u52a1\n     *\/\n    public void start() {\n        BootstrapConfigProperties.MonitorConfig monitorConfig =\n                BootstrapConfigProperties.getInstance().getMonitorConfig();\n\n        \/\/ \u9ed8\u8ba4\u5f00\u542f\uff0c\u5982\u679c\u914d\u7f6e\u663e\u5f0f\u5173\u95ed\u5219\u8fd4\u56de\n        if (monitorConfig != null &amp;&amp; Boolean.FALSE.equals(monitorConfig.getEnable())) {\n            return;\n        }\n\n        \/\/ \u9632\u5fa1\u6027\u7f16\u7a0b\uff1a\u5982\u679c\u672a\u914d\u7f6e\uff0c\u7ed9\u4e2a\u9ed8\u8ba4\u503c\n        long interval = (monitorConfig != null &amp;&amp; monitorConfig.getCollectInterval() != null) \n                        ? monitorConfig.getCollectInterval() : 5L;\n        String collectType = (monitorConfig != null &amp;&amp; monitorConfig.getCollectType() != null) \n                        ? monitorConfig.getCollectType() : \"log\";\n\n        \/\/ \u521d\u59cb\u5316\u76d1\u63a7\u76f8\u5173\u8d44\u6e90\n        micrometerMonitorCache = new ConcurrentHashMap&lt;&gt;();\n        scheduler = Executors.newScheduledThreadPool(\n                1,\n                ThreadFactoryBuilder.builder()\n                        .prefix(\"scheduler-thread-pool-monitor\")\n                        .daemon(true)\n                        .build()\n        );\n\n        \/\/ \u6bcf\u6307\u5b9a\u65f6\u95f4\u68c0\u67e5\u4e00\u6b21\uff0c\u521d\u59cb\u5ef6\u8fdf0\u79d2\n        scheduler.scheduleWithFixedDelay(() -&gt; {\n            try {\n                Collection&lt;ThreadPoolExecutorHolder&gt; holders = OneThreadRegistry.getAllHolders();\n                for (ThreadPoolExecutorHolder holder : holders) {\n                    ThreadPoolRuntimeInfo runtimeInfo = buildThreadPoolRuntimeInfo(holder);\n\n                    \/\/ \u6839\u636e\u91c7\u96c6\u7c7b\u578b\u5224\u65ad\n                    if (Objects.equals(collectType, \"log\")) {\n                        logMonitor(runtimeInfo);\n                    } else if (Objects.equals(collectType, \"micrometer\")) {\n                        micrometerMonitor(runtimeInfo);\n                    }\n                }\n            } catch (Exception e) {\n                log.error(\"ThreadPool monitor check failed.\", e);\n            }\n        }, 0, interval, TimeUnit.SECONDS);\n    }\n\n    private void logMonitor(ThreadPoolRuntimeInfo runtimeInfo) {\n        log.info(\"&#91;ThreadPool Monitor] {} | Content: {}\",\n                runtimeInfo.getThreadPoolId(),\n                JSON.toJSONString(runtimeInfo));\n    }\n\n    private void micrometerMonitor(ThreadPoolRuntimeInfo runtimeInfo) {\n        \/\/ TODO: \u5bf9\u63a5 Micrometer \u76d1\u63a7\n    }\n\n    @SneakyThrows\n    private ThreadPoolRuntimeInfo buildThreadPoolRuntimeInfo(ThreadPoolExecutorHolder holder) {\n        ThreadPoolExecutor executor = holder.getExecutor();\n        BlockingQueue&lt;?&gt; queue = executor.getQueue();\n\n        long rejectCount = -1L;\n        \/\/ \u5982\u679c\u662f OneThreadExecutor \u7c7b\u578b\uff0c\u53ef\u4ee5\u83b7\u53d6\u62d2\u7edd\u6b21\u6570\n        if (executor instanceof OneThreadExecutor) {\n            rejectCount = ((OneThreadExecutor) executor).getRejectCount();\n        }\n\n        int workQueueSize = queue.size();\n        int remainingCapacity = queue.remainingCapacity();\n\n        return ThreadPoolRuntimeInfo.builder()\n                .threadPoolId(holder.getThreadPoolId())\n                .corePoolSize(executor.getCorePoolSize())\n                .maximumPoolSize(executor.getMaximumPoolSize())\n                .activePoolSize(executor.getActiveCount())  \/\/ API \u6709\u9501\uff0c\u907f\u514d\u9ad8\u9891\u7387\u8c03\u7528\n                .currentPoolSize(executor.getPoolSize())  \/\/ API \u6709\u9501\uff0c\u907f\u514d\u9ad8\u9891\u7387\u8c03\u7528\n                .completedTaskCount(executor.getCompletedTaskCount())  \/\/ API \u6709\u9501\uff0c\u907f\u514d\u9ad8\u9891\u7387\u8c03\u7528\n                .largestPoolSize(executor.getLargestPoolSize())  \/\/ API \u6709\u9501\uff0c\u907f\u514d\u9ad8\u9891\u7387\u8c03\u7528\n                .workQueueName(queue.getClass().getSimpleName())\n                .workQueueSize(workQueueSize)\n                .workQueueRemainingCapacity(remainingCapacity)\n                .workQueueCapacity(workQueueSize + remainingCapacity)\n                .rejectedHandlerName(executor.getRejectedExecutionHandler().toString())\n                .rejectCount(rejectCount)\n                .build();\n    }\n}<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>\u4fee\u6b63\u8bf4\u660e<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>getRejectCount()<\/code>: \u8bf7\u786e\u4fdd <code>OneThreadExecutor<\/code> \u7c7b\u4e2d\u6709\u6b64\u65b9\u6cd5\u3002\u5982\u679c\u662f <code>AtomicLong<\/code> \u7c7b\u578b\uff0c\u9700\u8981\u8c03\u7528 <code>.get()<\/code>\u3002<\/li>\n\n\n\n<li><code>ThreadFactoryBuilder<\/code>: \u5047\u8bbe <code>core\/toolkit<\/code> \u4e0b\u5df2\u6709\u6b64\u5de5\u5177\u7c7b\uff08\u76ee\u5f55\u7ed3\u6784\u4e2d\u5b58\u5728\uff09\u3002<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\">B. \u76d1\u63a7\u8c03\u5ea6\u5c42 (Scheduling Layer)<\/h4>\n\n\n\n<p><strong>\u4ee3\u7801\u6587\u4ef6<\/strong>\uff1a<code>ThreadPoolMonitor.java<\/code><br><strong>\u4f5c\u7528<\/strong>\uff1a\u76d1\u63a7\u7cfb\u7edf\u7684\u201c\u5fc3\u810f\u201d\uff0c\u8d1f\u8d23\u5468\u671f\u6027\u5730\u9a71\u52a8\u91c7\u96c6\u4efb\u52a1\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6838\u5fc3\u903b\u8f91<\/strong>\uff1a<\/li>\n\n\n\n<li>\u4f7f\u7528 JDK \u7684 <code>ScheduledExecutorService<\/code>\u3002\u4e3a\u4ec0\u4e48\u4e0d\u7528 Spring \u7684 <code>@Scheduled<\/code>\uff1f\n<ul class=\"wp-block-list\">\n<li><strong>\u72ec\u7acb\u6027<\/strong>\uff1a\u6211\u4eec\u9700\u8981\u4e00\u4e2a\u5b8c\u5168\u72ec\u7acb\u3001\u4e0d\u53d7\u4e1a\u52a1\u7ebf\u7a0b\u6c60\u5f71\u54cd\u7684\u7ebf\u7a0b\uff08\u547d\u540d\u4e3a <code>scheduler-thread-pool-monitor<\/code>\uff09\u3002\u5373\u4f7f\u4e1a\u52a1\u7ebf\u7a0b\u6c60\u7206\u6ee1\u4e86\uff0c\u76d1\u63a7\u7ebf\u7a0b\u4f9d\u7136\u80fd\u5b58\u6d3b\u5e76\u6253\u5370\u65e5\u5fd7\uff0c\u8fd9\u624d\u662f\u76d1\u63a7\u5b58\u5728\u7684\u610f\u4e49\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>scheduleWithFixedDelay<\/code><\/strong>\uff1a\u4f7f\u7528\u201c\u56fa\u5b9a\u5ef6\u8fdf\u201d\u800c\u4e0d\u662f\u201c\u56fa\u5b9a\u9891\u7387\u201d\u3002\u5982\u679c\u67d0\u6b21\u91c7\u96c6\u5361\u4f4f\u4e86\uff0c\u4e0b\u4e00\u6b21\u91c7\u96c6\u4f1a\u987a\u5ef6\uff0c\u9632\u6b62\u4efb\u52a1\u65e0\u9650\u5806\u79ef\u628a\u5185\u5b58\u6491\u7206\u3002<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">C. \u6570\u636e\u91c7\u96c6\u4e0e\u9002\u914d\u5c42 (Collection &amp; Adapter Layer)<\/h4>\n\n\n\n<p><strong>\u4ee3\u7801\u6587\u4ef6<\/strong>\uff1a<code>ThreadPoolMonitor.java<\/code> (\u4e2d\u7684 <code>buildThreadPoolRuntimeInfo<\/code> \u65b9\u6cd5)<br><strong>\u4f5c\u7528<\/strong>\uff1a\u53bb\u5404\u4e2a\u7ebf\u7a0b\u6c60\u91cc\u201c\u6284\u6c34\u8868\u201d\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5bf9\u63a5\u6ce8\u518c\u4e2d\u5fc3<\/strong>\uff1a\u901a\u8fc7 <code>OneThreadRegistry.getAllHolders()<\/code> \u83b7\u53d6\u5f53\u524d\u7cfb\u7edf\u4e2d\u6240\u6709\u88ab\u7ba1\u7406\u7684\u52a8\u6001\u7ebf\u7a0b\u6c60\u3002<\/li>\n\n\n\n<li><strong>\u6570\u636e\u6807\u51c6\u5316<\/strong>\uff1a\u65e0\u8bba\u5e95\u5c42\u662f JDK \u7684 <code>ThreadPoolExecutor<\/code> \u8fd8\u662f\u4f60\u81ea\u5b9a\u4e49\u7684\u5305\u88c5\u7c7b\uff0c\u90fd\u7edf\u4e00\u8f6c\u6362\u4e3a <code>ThreadPoolRuntimeInfo<\/code> \u5bf9\u8c61\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u5b9a\u4e49\u7528\u4e8e\u5b58\u50a8\u548c\u6253\u5370\u7684\u7ebf\u7a0b\u6c60\u8fd0\u884c\u65f6\u6307\u6807\u6a21\u578b\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84<\/strong>: <code>core\/src\/main\/java\/com\/nageoffer\/onethread\/core\/monitor\/ThreadPoolRuntimeInfo.java<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.core.monitor;\n\nimport lombok.Builder;\nimport lombok.Data;\n\n\/**\n * \u7ebf\u7a0b\u6c60\u8fd0\u884c\u65f6\u4fe1\u606f\u5b9e\u4f53\n *\/\n@Data\n@Builder\npublic class ThreadPoolRuntimeInfo {\n    private String threadPoolId;           \/\/ \u7ebf\u7a0b\u6c60\u552f\u4e00\u6807\u8bc6\n    private Integer corePoolSize;          \/\/ \u6838\u5fc3\u7ebf\u7a0b\u6570\n    private Integer maximumPoolSize;       \/\/ \u6700\u5927\u7ebf\u7a0b\u6570\n    private Integer currentPoolSize;       \/\/ \u5f53\u524d\u7ebf\u7a0b\u6570\n    private Integer activePoolSize;        \/\/ \u6d3b\u8dc3\u7ebf\u7a0b\u6570\n    private Integer largestPoolSize;       \/\/ \u5386\u53f2\u6700\u5927\u7ebf\u7a0b\u6570\n    private Long completedTaskCount;       \/\/ \u5df2\u5b8c\u6210\u4efb\u52a1\u6570\n    private String workQueueName;          \/\/ \u961f\u5217\u7c7b\u578b\n    private Integer workQueueCapacity;     \/\/ \u961f\u5217\u5bb9\u91cf\n    private Integer workQueueSize;         \/\/ \u961f\u5217\u5f53\u524d\u5927\u5c0f\n    private Integer workQueueRemainingCapacity; \/\/ \u961f\u5217\u5269\u4f59\u5bb9\u91cf\n    private String rejectedHandlerName;    \/\/ \u62d2\u7edd\u7b56\u7565\u540d\u79f0\n    private Long rejectCount;              \/\/ \u62d2\u7edd\u6b21\u6570\n}<\/code><\/pre>\n\n\n\n<p>\u9700\u8981\u5728 Spring \u542f\u52a8\u65f6\u521d\u59cb\u5316 <code>ThreadPoolMonitor<\/code> \u5e76\u8c03\u7528\u5176 <code>start()<\/code> \u65b9\u6cd5\u3002\u6211\u4eec\u9700\u8981\u4fee\u6539 <code>spring-base<\/code> \u6216 <code>starter<\/code> \u6a21\u5757\u4e0b\u7684\u81ea\u52a8\u914d\u7f6e\u7c7b\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84<\/strong>: <code>starter\/src\/main\/java\/com\/nageoffer\/onethread\/starter\/config\/CommonAutoConfiguration.java<\/code> (\u6216\u8005 <code>spring-base<\/code> \u4e0b\u7684\u914d\u7f6e\u7c7b\uff0c\u89c6\u4f60\u7684 Bean \u52a0\u8f7d\u903b\u8f91\u800c\u5b9a)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.starter.config;<br><br>import com.nageoffer.onethread.core.monitor.ThreadPoolMonitor;<br>import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;<br>import org.springframework.context.annotation.Bean;<br>import org.springframework.context.annotation.Configuration;<br><br>@Configuration<br>public class CommonAutoConfiguration {<br><br>    \/\/ ... \u539f\u6709\u7684 Bean \u5b9a\u4e49 ...<br><br>    @Bean<br>    @ConditionalOnMissingBean<br>    public ThreadPoolMonitor threadPoolMonitor() {<br>        ThreadPoolMonitor monitor = new ThreadPoolMonitor();<br>        \/\/ \u53ef\u4ee5\u5728\u8fd9\u91cc\u8c03\u7528 start\uff0c\u6216\u8005\u5728 ThreadPoolMonitor \u4e2d\u4f7f\u7528 @PostConstruct<br>        monitor.start();<br>        return monitor;<br>    }<br>}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u5173\u952e\u4ee3\u7801\u7ec6\u8282\u4e0e\u6027\u80fd\u8003\u91cf<\/h3>\n\n\n\n<p>\u5728\u5b9e\u73b0\u8fc7\u7a0b\u4e2d\uff0c\u6709\u51e0\u4e2a\u7ec6\u8282\u662f\u4e25\u683c\u9075\u5faa\u4f60\u63d0\u5230\u7684\u201c\u6027\u80fd\u4f18\u5148\u201d\u539f\u5219\u7684\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u2460 \u9501\u7684\u4ee3\u4ef7 (Lock Awareness)<\/h4>\n\n\n\n<p>\u5728\u4ee3\u7801\u6ce8\u91ca\u4e2d\uff0c\u6211\u4eec\u660e\u786e\u6807\u6ce8\u4e86\u54ea\u4e9bAPI\u8c03\u7528\u662f\u6709\u9501\u7684\uff0c\u8fd9\u63d0\u9192\u5f00\u53d1\u8005\u5728\u8bbe\u8ba1\u76d1\u63a7\u9891\u7387\u65f6\u8981\u8003\u8651\u6027\u80fd\u5f71\u54cd\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6709\u9501API<\/strong> \uff1a<code>getActiveCount()<\/code>\u3001<code>getPoolSize()<\/code>\u3001<code>getCompletedTaskCount()<\/code>\u7b49\u3002<\/li>\n\n\n\n<li><strong>\u65e0\u9501API<\/strong> \uff1a<code>getCorePoolSize()<\/code>\u3001<code>getMaximumPoolSize()<\/code>\u7b49\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u5728 <code>buildThreadPoolRuntimeInfo<\/code> \u65b9\u6cd5\u4e2d\uff0c\u6211\u7279\u610f\u4fdd\u7559\u4e86\u6ce8\u91ca\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ API \u6709\u9501\uff0c\u907f\u514d\u9ad8\u9891\u7387\u8c03\u7528\n.activePoolSize(executor.getActiveCount()) \n.currentPoolSize(executor.getPoolSize())<\/code><\/pre>\n\n\n\n<p><strong>\u8bb2\u89e3<\/strong>\uff1a<br>JDK \u539f\u751f\u7ebf\u7a0b\u6c60\u7684 <code>getActiveCount()<\/code> \u7b49\u65b9\u6cd5\u5185\u90e8\u662f\u5305\u542b <code>mainLock<\/code> \u5168\u5c40\u9501\u7684\u3002\u867d\u7136\u8fd9\u4e2a\u9501\u7ade\u4e89\u901a\u5e38\u4e0d\u6fc0\u70c8\uff0c\u4f46\u5728\u9ad8\u5e76\u53d1\u573a\u666f\u4e0b\uff0c\u5982\u679c\u76d1\u63a7\u9891\u7387\u8fc7\u9ad8\uff08\u6bd4\u5982 100ms \u4e00\u6b21\uff09\uff0c\u786e\u5b9e\u4f1a\u8f7b\u5fae\u5f71\u54cd\u4e1a\u52a1\u4efb\u52a1\u7684\u63d0\u4ea4\u548c\u6267\u884c\u3002<br><strong>\u4f18\u5316\u65b9\u6848<\/strong>\uff1a\u6240\u4ee5\u6211\u4eec\u5c06\u91c7\u96c6\u95f4\u9694\u9ed8\u8ba4\u8bbe\u4e3a 5 \u79d2\uff0c\u8fd9\u662f\u4e00\u4e2a\u5b89\u5168\u7684\u201c\u751c\u70b9\u533a\u95f4\u201d\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u2461 \u9632\u5fa1\u6027\u7f16\u7a0b<\/h4>\n\n\n\n<p>\u5728\u8c03\u5ea6\u5faa\u73af\u4e2d\uff0c\u6211\u6dfb\u52a0\u4e86 <code>try-catch<\/code>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>try {\n    \/\/ \u91c7\u96c6\u903b\u8f91\n} catch (Exception e) {\n    log.error(\"ThreadPool monitor check failed.\", e);\n}<\/code><\/pre>\n\n\n\n<p><strong>\u8bb2\u89e3<\/strong>\uff1a<br>\u8fd9\u662f\u4e3a\u4e86\u9632\u6b62\u67d0\u4e2a\u7ebf\u7a0b\u6c60\u7684\u72b6\u6001\u5f02\u5e38\uff08\u6bd4\u5982\u88ab\u9500\u6bc1\u4e86\u4f46\u8fd8\u6ca1\u6ce8\u9500\uff09\u629b\u51fa\u5f02\u5e38\uff0c\u5bfc\u81f4\u6574\u4e2a\u76d1\u63a7\u5b9a\u65f6\u4efb\u52a1\u5d29\u6e83\u505c\u6b62\u3002\u76d1\u63a7\u7cfb\u7edf\u5fc5\u987b\u6bd4\u4e1a\u52a1\u7cfb\u7edf\u66f4\u201c\u575a\u5f3a\u201d\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u2462 \u62d2\u7edd\u7b56\u7565\u7684\u7edf\u8ba1<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>if (executor instanceof OneThreadExecutor) {\n    rejectCount = ((OneThreadExecutor) executor).getRejectCount();\n}<\/code><\/pre>\n\n\n\n<p><strong>\u8bb2\u89e3<\/strong>\uff1a<br>JDK \u539f\u751f\u7684\u7ebf\u7a0b\u6c60\u662f\u4e0d\u8bb0\u5f55\u603b\u62d2\u7edd\u6b21\u6570\u7684\u3002\u8fd9\u91cc\u5229\u7528\u4e86 <code>OneThreadExecutor<\/code> \u7684\u6269\u5c55\u80fd\u529b\u3002<strong>\u62d2\u7edd\u6b21\u6570\u662f\u76d1\u63a7\u4e2d\u6700\u6838\u5fc3\u7684\u6307\u6807<\/strong>\uff0c\u56e0\u4e3a\u4e00\u65e6\u51fa\u73b0\u62d2\u7edd\uff0c\u8bf4\u660e\u7cfb\u7edf\u5bb9\u91cf\u5df2\u7ecf\u4e0d\u591f\u4e86\uff0c\u9700\u8981\u7acb\u523b\u62a5\u8b66\u6216\u6269\u5bb9\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u76d1\u63a7\u91c7\u96c6\u7c7b\u578b\u7684\u5224\u65ad\u903b\u8f91\uff0c\u5176\u5b9e\u8fd8\u6709\u4f18\u5316\u7a7a\u95f4\u3002\u6bd4\u5982\u6211\u4eec\u73b0\u5728\u7684\u4e24\u79cd\u5b58\u50a8\u65b9\u5f0f\uff0c\u5176\u5b9e\u53ef\u4ee5\u62c6\u5206\u6210\u4e24\u4e2a\u72ec\u7acb\u7684\u5b9e\u73b0\u7c7b\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u5982\u679c\u540e\u7eed\u6846\u67b6\u6709\u8ba1\u5212\u652f\u6301\u66f4\u591a\u5b58\u50a8\u7b56\u7565\uff08\u6bd4\u5982 ElasticSearch \u7b49\uff09\uff0c\u5c31\u53ef\u4ee5\u5f15\u5165<strong>\u7b56\u7565\u6a21\u5f0f<\/strong> \uff0c\u5b9e\u73b0\u6309\u9700\u5207\u6362\uff0c\u7ed3\u6784\u66f4\u6e05\u6670\uff1b\u4f46\u5982\u679c\u5f53\u524d\u53ea\u6253\u7b97\u7528\u4e00\u79cd\u6216\u4e24\u79cd\u56fa\u5b9a\u65b9\u5f0f\uff0c\u90a3\u7528\u4e00\u4e2a<strong>\u7b80\u5355\u5de5\u5382\u6a21\u5f0f<\/strong> \u6765\u521b\u5efa\u4e5f\u66f4\u8f7b\u91cf\uff0c\u8db3\u591f\u5e94\u5bf9\uff0c\u6269\u5c55\u6210\u672c\u4e5f\u4f4e\u3002<\/p>\n\n\n\n<p>\u5f53\u524d\u5b9e\u73b0\u65b9\u6848\u4e2d\uff0c\u901a\u8fc7\u914d\u7f6e\u53c2\u6570<code>collectType<\/code>\u6765\u51b3\u5b9a\u4f7f\u7528\u54ea\u79cd\u76d1\u63a7\u7b56\u7565\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>log\u7b56\u7565<\/strong> \uff1a\u5c06\u76d1\u63a7\u4fe1\u606f\u8f93\u51fa\u5230\u672c\u5730\u65e5\u5fd7<\/li>\n\n\n\n<li><strong>micrometer\u7b56\u7565<\/strong> \uff1a\u5c06\u76d1\u63a7\u6307\u6807\u53d1\u9001\u5230Micrometer\u76d1\u63a7\u7cfb\u7edf<\/li>\n<\/ul>\n\n\n\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u4f7f\u5f97\u76d1\u63a7\u65b9\u5f0f\u7684\u9009\u62e9\u53d8\u5f97\u7075\u6d3b\uff0c\u672a\u6765\u53ef\u4ee5\u8f7b\u677e\u6269\u5c55\u5176\u4ed6\u76d1\u63a7\u7b56\u7565<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\u5728\u5b9a\u65f6\u4efb\u52a1\u8bbe\u8ba1\u4e2d\uff0c\u6211\u4eec\u91c7\u7528\u4e86\u4ee5\u4e0b\u4f18\u5316\u7b56\u7565\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5355\u7ebf\u7a0b\u8c03\u5ea6\u5668<\/strong> \uff1a\u4f7f\u7528 <code>newScheduledThreadPool(1)<\/code> \u786e\u4fdd\u76d1\u63a7\u4efb\u52a1\u4e32\u884c\u6267\u884c\uff0c\u907f\u514d\u5e76\u53d1\u95ee\u9898\u3002<\/li>\n\n\n\n<li><strong>\u56fa\u5b9a\u5ef6\u8fdf\u8c03\u5ea6<\/strong> \uff1a\u4f7f\u7528 <code>scheduleWithFixedDelay<\/code> \u800c\u4e0d\u662f <code>scheduleAtFixedRate<\/code>\uff0c\u907f\u514d\u4efb\u52a1\u5806\u79ef\u3002<\/li>\n\n\n\n<li><strong>\u53ef\u914d\u7f6e\u95f4\u9694<\/strong> \uff1a\u901a\u8fc7\u914d\u7f6e\u6587\u4ef6\u63a7\u5236\u76d1\u63a7\u9891\u7387\uff0c\u5e73\u8861\u76d1\u63a7\u7cbe\u5ea6\u548c\u6027\u80fd\u5f71\u54cd\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u6570\u636e\u6d41\u8f6c\u8fc7\u7a0b\u6f14\u793a<\/h3>\n\n\n\n<p>\u5047\u8bbe\u4f60\u7684\u5e94\u7528\u542f\u52a8\u4e86\uff0c\u6574\u4e2a\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u542f\u52a8\u9636\u6bb5<\/strong>\uff1aSpring Boot \u542f\u52a8 -> <code>CommonAutoConfiguration<\/code> \u52a0\u8f7d -> <code>ThreadPoolMonitor.start()<\/code> \u88ab\u8c03\u7528\u3002<\/li>\n\n\n\n<li><strong>\u521d\u59cb\u5316<\/strong>\uff1a\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a <code>scheduler-thread-pool-monitor<\/code> \u7684\u5b88\u62a4\u7ebf\u7a0b\u3002<\/li>\n\n\n\n<li><strong>\u8fd0\u884c\u9636\u6bb5<\/strong>\uff08\u6bcf 5 \u79d2\uff09\uff1a\n<ul class=\"wp-block-list\">\n<li>\u7ebf\u7a0b\u9192\u6765\uff0c\u53bb <code>OneThreadRegistry<\/code> \u62ff\u540d\u5355\uff08\u6bd4\u5982\u6709\u4e00\u4e2a\u53eb \"order-service-pool\" \u7684\u7ebf\u7a0b\u6c60\uff09\u3002<\/li>\n\n\n\n<li>\u68c0\u67e5\u8be5\u7ebf\u7a0b\u6c60\uff1a\n<ul class=\"wp-block-list\">\n<li>\u6838\u5fc3\u7ebf\u7a0b 10\uff0c\u6700\u5927 20\u3002<\/li>\n\n\n\n<li>\u5f53\u524d\u5728\u5e72\u6d3b\u7684\u7ebf\u7a0b 18 \u4e2a\uff08<strong>\u9ad8\u6c34\u4f4d\u9884\u8b66\uff01<\/strong>\uff09\u3002<\/li>\n\n\n\n<li>\u961f\u5217\u5bb9\u91cf 100\uff0c\u91cc\u9762\u5df2\u7ecf\u5806\u4e86 80 \u4e2a\u4efb\u52a1\uff08<strong>\u963b\u585e\u9884\u8b66\uff01<\/strong>\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u6253\u5305\u6210 <code>ThreadPoolRuntimeInfo<\/code> \u5bf9\u8c61\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8f93\u51fa\u9636\u6bb5<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u5224\u65ad <code>collectType = log<\/code>\u3002<\/li>\n\n\n\n<li>\u5e8f\u5217\u5316\u4e3a JSON\uff0c\u6253\u5370\u5230 <code>logback<\/code> \u6216 <code>log4j<\/code> \u6587\u4ef6\u4e2d\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u65e5\u5fd7\u957f\u4ec0\u4e48\u6837\uff1f<\/h3>\n\n\n\n<p>\u6700\u7ec8\u4f60\u5728\u65e5\u5fd7\u6587\u4ef6\u91cc\u770b\u5230\u7684\u4e00\u884c\u884c\u6570\u636e\uff0c\u5c31\u662f\u4f60\u6392\u67e5\u95ee\u9898\u7684\u201c\u9ed1\u5323\u5b50\u201d\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;ThreadPool Monitor] order-service-pool | Content: {\n  \"activePoolSize\": 18,\n  \"corePoolSize\": 10,\n  \"maximumPoolSize\": 20,\n  \"workQueueSize\": 80,\n  \"workQueueCapacity\": 100,\n  \"rejectCount\": 5,\n  \"threadPoolId\": \"order-service-pool\",\n  ...\n}<\/code><\/pre>\n\n\n\n<p><strong>\u600e\u4e48\u7528\u8fd9\u4e2a\u65e5\u5fd7\uff1f<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u770b\u8d8b\u52bf<\/strong>\uff1a\u5982\u679c <code>activePoolSize<\/code> \u957f\u671f\u7ef4\u6301\u5728 <code>maximumPoolSize<\/code> \u9644\u8fd1\uff0c\u8bf4\u660e\u9700\u8981\u6269\u5bb9\u3002<\/li>\n\n\n\n<li><strong>\u67e5\u6545\u969c<\/strong>\uff1a\u5982\u679c\u63a5\u53e3\u8d85\u65f6\uff0c\u770b\u540c\u4e00\u65f6\u95f4\u7684 <code>workQueueSize<\/code> \u662f\u5426\u5f88\u9ad8\uff0c\u5982\u679c\u662f\uff0c\u8bf4\u660e\u4efb\u52a1\u5728\u6392\u961f\uff0c\u800c\u4e0d\u662f\u5904\u7406\u6162\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u8fd9\u5957\u5b9e\u73b0\u65b9\u6848\u867d\u7136\u7b80\u5355\uff08\u57fa\u4e8e\u672c\u5730\u65e5\u5fd7\uff09\uff0c\u4f46\u5b83\u6784\u5efa\u4e86\u4e00\u4e2a\u5b8c\u6574\u7684<strong>\u95ed\u73af\u76d1\u63a7\u4f53\u7cfb<\/strong>\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Registry<\/strong> \u63d0\u4f9b\u4e86\u6570\u636e\u6e90\u3002<\/li>\n\n\n\n<li><strong>Monitor<\/strong> \u63d0\u4f9b\u4e86\u9a71\u52a8\u529b\u3002<\/li>\n\n\n\n<li><strong>Log\/JSON<\/strong> \u63d0\u4f9b\u4e86\u53ef\u89c6\u5316\u6570\u636e\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u540e\u7eed\u5982\u679c\u9700\u8981\u63a5\u5165 Prometheus + Grafana\uff0c\u53ea\u9700\u8981\u5728 <code>ThreadPoolMonitor<\/code> \u7684 <code>micrometerMonitor<\/code> \u65b9\u6cd5\u4e2d\uff0c\u628a <code>ThreadPoolRuntimeInfo<\/code> \u7684\u5b57\u6bb5\u585e\u5230 <code>Metrics.gauge<\/code> \u91cc\u5373\u53ef\uff0c\u67b6\u6784\u5b8c\u5168\u4e0d\u7528\u52a8\u3002<\/p>\n\n\n\n<p>\u5b8c\u6210\u4ee5\u4e0a\u6b65\u9aa4\u540e\uff0c\u9879\u76ee\u7ed3\u6784\u53d8\u52a8\u5982\u4e0b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Model<\/strong>: <code>ThreadPoolRuntimeInfo<\/code> (\u65b0\u589e)<\/li>\n\n\n\n<li><strong>Monitor<\/strong>: <code>ThreadPoolMonitor<\/code> (\u65b0\u589e)<\/li>\n\n\n\n<li><strong>Config<\/strong>: <code>BootstrapConfigProperties<\/code> (\u4fee\u6539\uff0c\u589e\u52a0 MonitorConfig)<\/li>\n\n\n\n<li><strong>AutoConfig<\/strong>: \u6ce8\u518c Bean \u5e76\u542f\u52a8\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u91cd\u65b0\u7f16\u8bd1\u5e76\u542f\u52a8\u5e94\u7528\u540e\uff0c\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff08enable=true, type=log\uff09\uff0c\u4f60\u5e94\u8be5\u80fd\u5728\u63a7\u5236\u53f0\u770b\u5230\u6bcf\u9694 5 \u79d2\u8f93\u51fa\u7684 <code>[ThreadPool Monitor]<\/code> \u65e5\u5fd7\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u901a\u8fc7Actuator\u5b9e\u73b0\u52a8\u6001\u7ebf\u7a0b\u6c60Metrics\u76d1\u63a7<\/h1>\n\n\n\n<p>\u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u7cfb\u7edf\u4e14\u4e13\u4e1a\u7684\u76d1\u63a7\u6539\u9020\u4efb\u52a1\u3002\u6839\u636e\u4f60\u63d0\u4f9b\u7684\u9879\u76ee\u7ed3\u6784\u548c\u524d\u6587\u7684\u8bbe\u8ba1\u7406\u5ff5\uff0c\u6211\u4eec\u9700\u8981\u5c06 Micrometer \u76d1\u63a7\u4f53\u7cfb\u878d\u5165\u5230\u73b0\u6709\u7684 <code>oneThread<\/code> \u6846\u67b6\u4e2d\u3002<\/p>\n\n\n\n<p>\u4e3a\u4e86\u6e05\u6670\u5730\u5b8c\u6210\u8fd9\u4e2a\u4efb\u52a1\uff0c\u6211\u5c06\u5206 <strong>\u4e09\u6b65\uff08\u4e09\u6b21\u56de\u7b54\uff09<\/strong> \u8be6\u7ec6\u8bb2\u89e3\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u7b2c\u4e00\u90e8\u5206\uff08\u672c\u6b21\uff09\uff1a\u4f9d\u8d56\u5206\u5c42\u67b6\u6784\u4e0e Core \u6838\u5fc3\u903b\u8f91\u5b9e\u73b0<\/strong>\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e8c\u90e8\u5206\uff1aStarter \u81ea\u52a8\u914d\u7f6e\u4e0e Spring Boot Actuator \u96c6\u6210<\/strong>\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e09\u90e8\u5206\uff1aPrometheus \u63a5\u5165\u5b9e\u6218\u4e0e Grafana \u9762\u677f\u9a8c\u8bc1<\/strong>\u3002<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u7b2c\u4e00\u90e8\u5206\uff1a\u4f9d\u8d56\u5206\u5c42\u67b6\u6784\u4e0e Core \u6838\u5fc3\u903b\u8f91\u5b9e\u73b0<\/h3>\n\n\n\n<p>\u8fd9\u90e8\u5206\u4e3b\u8981\u89e3\u51b3\u6846\u67b6\u5e95\u5c42\u7684\u80fd\u529b\u6784\u5efa\uff0c\u786e\u4fdd <code>core<\/code> \u6a21\u5757\u5177\u5907 Micrometer \u7684\u62bd\u8c61\u80fd\u529b\uff0c\u800c\u4e0d\u7ed1\u5b9a\u5177\u4f53\u7684\u76d1\u63a7\u5b9e\u73b0\uff08\u5982 Prometheus\uff09\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">1. \u4f9d\u8d56\u5206\u5c42\u6539\u9020 (Maven Dependencies)<\/h4>\n\n\n\n<p>\u6839\u636e\u6587\u7ae0\u7684\u201c\u4f9d\u8d56\u4f53\u7cfb\u89e3\u6790\u201d\uff0c\u6211\u4eec\u9700\u8981\u4fee\u6539 <code>pom.xml<\/code> \u6587\u4ef6\u3002<\/p>\n\n\n\n<p><strong>1.1 \u4fee\u6539 <code>core\/pom.xml<\/code><\/strong><br><code>core<\/code> \u6a21\u5757\u4f5c\u4e3a\u6846\u67b6\u6838\u5fc3\uff0c\u53ea\u5f15\u5165 <code>micrometer-core<\/code>\uff0c\u63d0\u4f9b\u76d1\u63a7\u7684\u62bd\u8c61\u5c42\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- onethread-core\/pom.xml --&gt;\n&lt;dependencies&gt;\n    &lt;!-- \u5176\u4ed6\u73b0\u6709\u4f9d\u8d56 --&gt;\n\n    &lt;!-- Micrometer \u6838\u5fc3\u4f9d\u8d56\uff1a\u63d0\u4f9b Metrics, Gauge \u7b49\u62bd\u8c61 API --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;io.micrometer&lt;\/groupId&gt;\n        &lt;artifactId&gt;micrometer-core&lt;\/artifactId&gt;\n        &lt;version&gt;1.11.0&lt;\/version&gt; &lt;!-- \u5efa\u8bae\u4f7f\u7528\u7a33\u5b9a\u7248\u672c\uff0c\u6216\u8005\u7531\u7236\u5de5\u7a0b\u7ba1\u7406 --&gt;\n        &lt;optional&gt;true&lt;\/optional&gt; &lt;!-- \u8bbe\u7f6e\u4e3a\u53ef\u9009\uff0c\u4e0d\u5f3a\u5236\u4e0b\u6e38\u5f15\u5165 --&gt;\n    &lt;\/dependency&gt;\n&lt;\/dependencies&gt;<\/code><\/pre>\n\n\n\n<p><strong>1.2 \u4fee\u6539 <code>starter\/pom.xml<\/code><\/strong><br><code>starter<\/code> \u6a21\u5757\u8d1f\u8d23 Spring Boot \u7684\u81ea\u52a8\u88c5\u914d\uff0c\u5f15\u5165 Actuator \u4ee5\u63d0\u4f9b\u57fa\u7840\u76d1\u63a7\u80fd\u529b\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!-- onethread-starter\/pom.xml --&gt;\n&lt;dependencies&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;com.nageoffer&lt;\/groupId&gt;\n        &lt;artifactId&gt;onethread-core&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- Spring Boot Actuator\uff1a\u63d0\u4f9b \/actuator \u7aef\u70b9\u548c\u6307\u6807\u6536\u96c6\u5668 --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-boot-starter-actuator&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n&lt;\/dependencies&gt;<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">2. Core \u6838\u5fc3\u76d1\u63a7\u903b\u8f91\u5b9e\u73b0<\/h4>\n\n\n\n<p>\u6838\u5fc3\u903b\u8f91\u4f4d\u4e8e <code>core<\/code> \u6a21\u5757\u3002\u6211\u4eec\u9700\u8981\u6539\u9020 <code>ThreadPoolMonitor<\/code> \u7c7b\uff0c\u589e\u52a0 Micrometer \u7684\u6307\u6807\u6ce8\u518c\u548c\u91c7\u96c6\u903b\u8f91\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84\uff1a<\/strong> <code>core\/src\/main\/java\/com\/nageoffer\/onethread\/core\/monitor\/ThreadPoolMonitor.java<\/code><\/p>\n\n\n\n<p>\u6211\u4eec\u9700\u8981\u505a\u4ee5\u4e0b\u6539\u52a8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5f15\u5165 Micrometer \u76f8\u5173\u7c7b\u3002<\/li>\n\n\n\n<li>\u589e\u52a0 <code>micrometerMonitor<\/code> \u65b9\u6cd5\u3002<\/li>\n\n\n\n<li>\u5b9e\u73b0\u7f13\u5b58\u673a\u5236\uff08<code>micrometerMonitorCache<\/code>\uff09\u907f\u514d\u91cd\u590d\u521b\u5efa\u5bf9\u8c61\u3002<\/li>\n\n\n\n<li>\u5728\u91c7\u96c6\u5165\u53e3\u8c03\u5ea6\u8be5\u65b9\u6cd5\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u4ee3\u7801\u5b9e\u73b0\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.core.monitor;\n\nimport com.nageoffer.onethread.core.config.ApplicationProperties;\nimport com.nageoffer.onethread.core.executor.ThreadPoolExecutorHolder;\nimport io.micrometer.core.instrument.Metrics;\nimport io.micrometer.core.instrument.Tag;\nimport io.micrometer.core.instrument.Tags;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.BeanUtils; \/\/ \u6216\u8005\u4f7f\u7528 Hutool \u7684 BeanUtil\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ScheduledThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\n\n\/**\n * \u7ebf\u7a0b\u6c60\u76d1\u63a7\u6838\u5fc3\u7ec4\u4ef6\n *\/\n@Slf4j\npublic class ThreadPoolMonitor {\n\n    private final ScheduledExecutorService scheduler;\n\n    \/\/ \u7f13\u5b58 Map\uff0cKey \u4e3a threadPoolId\uff0cValue \u4e3a\u8fd0\u884c\u65f6\u4fe1\u606f\u5bf9\u8c61\n    \/\/ \u4f5c\u7528\uff1a\u786e\u4fdd Micrometer \u7684 Gauge \u6307\u6807\u59cb\u7ec8\u5f15\u7528\u540c\u4e00\u4e2a\u5bf9\u8c61\u5730\u5740\n    private final Map&lt;String, ThreadPoolRuntimeInfo> micrometerMonitorCache = new ConcurrentHashMap&lt;>();\n\n    private static final String METRIC_NAME_PREFIX = \"dynamic.thread-pool\";\n    private static final String DYNAMIC_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + \".id\";\n    private static final String APPLICATION_NAME_TAG = \"application.name\";\n\n    public ThreadPoolMonitor() {\n        this.scheduler = new ScheduledThreadPoolExecutor(1, r -> {\n            Thread t = new Thread(r, \"onethread-monitor\");\n            t.setDaemon(true);\n            return t;\n        });\n    }\n\n    \/**\n     * \u542f\u52a8\u76d1\u63a7\u91c7\u96c6\n     * @param collectInterval \u91c7\u96c6\u95f4\u9694\uff08\u79d2\uff09\n     * @param collectType \u91c7\u96c6\u7c7b\u578b\uff08log \u6216 micrometer\uff09\n     *\/\n    public void start(int collectInterval, String collectType) {\n        scheduler.scheduleWithFixedDelay(() -> {\n            try {\n                \/\/ \u83b7\u53d6\u6240\u6709\u53d7\u7ba1\u7ebf\u7a0b\u6c60\u7684\u8fd0\u884c\u65f6\u4fe1\u606f\n                List&lt;ThreadPoolRuntimeInfo> runtimeInfos = ThreadPoolExecutorHolder.getThreadPoolRuntimeInfos();\n\n                for (ThreadPoolRuntimeInfo runtimeInfo : runtimeInfos) {\n                    if (\"micrometer\".equalsIgnoreCase(collectType)) {\n                        micrometerMonitor(runtimeInfo);\n                    } else {\n                        \/\/ \u4fdd\u7559\u539f\u6709\u7684\u65e5\u5fd7\u76d1\u63a7\u903b\u8f91\n                        logMonitor(runtimeInfo);\n                    }\n                }\n            } catch (Exception e) {\n                log.error(\"ThreadPool monitor execution failed.\", e);\n            }\n        }, 0, collectInterval, TimeUnit.SECONDS);\n    }\n\n    private void logMonitor(ThreadPoolRuntimeInfo runtimeInfo) {\n        \/\/ ... \u539f\u6709\u7684\u65e5\u5fd7\u6253\u5370\u903b\u8f91 ...\n        log.info(\"ThreadPool Status: &#91;Name: {}, Core: {}, Active: {}]\", \n                 runtimeInfo.getThreadPoolId(), runtimeInfo.getCorePoolSize(), runtimeInfo.getActivePoolSize());\n    }\n\n    \/**\n     * Micrometer \u76d1\u63a7\u6838\u5fc3\u5b9e\u73b0\n     * \u5b9e\u73b0\u4e86 \"\u5bf9\u8c61\u590d\u7528\" \u548c \"\u6307\u6807\u6ce8\u518c\"\n     *\/\n    private void micrometerMonitor(ThreadPoolRuntimeInfo runtimeInfo) {\n        String threadPoolId = runtimeInfo.getThreadPoolId();\n\n        \/\/ 1. \u7f13\u5b58\u5904\u7406\uff1a\u786e\u4fdd Gauge \u7ed1\u5b9a\u7684\u5bf9\u8c61\u5f15\u7528\u4e0d\u53d8\n        ThreadPoolRuntimeInfo existingRuntimeInfo = micrometerMonitorCache.get(threadPoolId);\n        if (existingRuntimeInfo != null) {\n            \/\/ \u5982\u679c\u7f13\u5b58\u5b58\u5728\uff0c\u5c06\u65b0\u91c7\u96c6\u7684\u6570\u636e copy \u5230\u65e7\u5bf9\u8c61\u4e2d\n            BeanUtils.copyProperties(runtimeInfo, existingRuntimeInfo);\n        } else {\n            \/\/ \u5982\u679c\u7f13\u5b58\u4e0d\u5b58\u5728\uff0c\u653e\u5165\u7f13\u5b58\u5e76\u8fdb\u884c\u6307\u6807\u6ce8\u518c\n            micrometerMonitorCache.put(threadPoolId, runtimeInfo);\n            existingRuntimeInfo = runtimeInfo; \/\/ \u7528\u4e8e\u4e0b\u65b9\u6ce8\u518c\n\n            \/\/ 2. \u53ea\u6709\u7b2c\u4e00\u6b21\u9047\u5230\u8be5\u7ebf\u7a0b\u6c60\u65f6\uff0c\u624d\u8fdb\u884c\u6307\u6807\u6ce8\u518c (\u907f\u514d\u91cd\u590d\u6ce8\u518c)\n            registerMetrics(existingRuntimeInfo);\n        }\n    }\n\n    \/**\n     * \u6ce8\u518c\u5177\u4f53\u7684 Gauge \u6307\u6807\n     *\/\n    private void registerMetrics(ThreadPoolRuntimeInfo runtimeInfo) {\n        String threadPoolId = runtimeInfo.getThreadPoolId();\n\n        \/\/ \u6784\u5efa\u6807\u7b7e\uff1aApp Name + ThreadPool ID\n        \/\/ \u6ce8\u610f\uff1aApplicationProperties \u9700\u8981\u80fd\u83b7\u53d6\u5230 spring.application.name\n        Iterable&lt;Tag> tags = Tags.of(\n            DYNAMIC_THREAD_POOL_ID_TAG, threadPoolId,\n            APPLICATION_NAME_TAG, ApplicationProperties.getApplicationName()\n        );\n\n        \/\/ \u6ce8\u518c\u6838\u5fc3\u7ebf\u7a0b\u6570\n        Metrics.gauge(metricName(\"core.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getCorePoolSize);\n        \/\/ \u6ce8\u518c\u6700\u5927\u7ebf\u7a0b\u6570\n        Metrics.gauge(metricName(\"maximum.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getMaximumPoolSize);\n        \/\/ \u6ce8\u518c\u5f53\u524d\u7ebf\u7a0b\u6570\n        Metrics.gauge(metricName(\"current.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getCurrentPoolSize);\n        \/\/ \u6ce8\u518c\u6d3b\u8dc3\u7ebf\u7a0b\u6570 (\u6700\u5173\u952e\u6307\u6807)\n        Metrics.gauge(metricName(\"active.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getActivePoolSize);\n        \/\/ \u6ce8\u518c\u5386\u53f2\u6700\u5927\u7ebf\u7a0b\u6570\n        Metrics.gauge(metricName(\"largest.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getLargestPoolSize);\n\n        \/\/ \u961f\u5217\u76f8\u5173\n        Metrics.gauge(metricName(\"queue.size\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getWorkQueueSize);\n        Metrics.gauge(metricName(\"queue.capacity\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getWorkQueueCapacity);\n        Metrics.gauge(metricName(\"queue.remaining.capacity\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getWorkQueueRemainingCapacity);\n\n        \/\/ \u4efb\u52a1\u7edf\u8ba1\n        Metrics.gauge(metricName(\"completed.task.count\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getCompletedTaskCount);\n        Metrics.gauge(metricName(\"reject.count\"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getRejectCount);\n    }\n\n    private String metricName(String name) {\n        return String.join(\".\", METRIC_NAME_PREFIX, name);\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>micrometer-core<\/strong> \uff08\u4f4d\u4e8e onethread-core \u5305\uff09\uff1a<\/p>\n\n\n\n<p>\u8fd9\u662f\u6574\u4e2a\u76d1\u63a7\u4f53\u7cfb\u7684<strong>\u57fa\u77f3<\/strong> \uff0c\u63d0\u4f9b\u4e86 Micrometer \u7684\u6838\u5fc3\u62bd\u8c61\u5c42\u3002\u5b83\u6700\u91cd\u8981\u7684\u4f5c\u7528\u662f\u5b9a\u4e49\u4e86\u7edf\u4e00\u7684\u6307\u6807 API\uff0c\u8ba9\u6211\u4eec\u7684\u6846\u67b6\u4ee3\u7801\u4e0d\u7528\u5173\u5fc3\u5e95\u5c42\u5230\u5e95\u7528\u7684\u662f Prometheus \u8fd8\u662f InfluxDB\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u8fd9\u884c\u4ee3\u7801\u80cc\u540e\uff0cmicrometer-core \u505a\u4e86\u4ec0\u4e48\uff1fMetrics.gauge(metricName(\"core.size\"), tags, runtimeInfo,ThreadPoolRuntimeInfo::getCorePoolSize);<\/code><\/pre>\n\n\n\n<p>\u5f53\u6211\u4eec\u8c03\u7528 <code>Metrics.gauge()<\/code> \u65f6\uff0cmicrometer-core \u4f1a\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>1.<strong>\u67e5\u627e\u53ef\u7528\u7684MeterRegistry<\/strong> \uff1a\u626b\u63cf classpath \u4e2d\u7684 Registry \u5b9e\u73b0\uff1b<\/li>\n\n\n\n<li>2.<strong>\u521b\u5efaGauge\u5b9e\u4f8b<\/strong> \uff1a\u6839\u636e\u6307\u6807\u540d\u79f0\u548c\u6807\u7b7e\u521b\u5efa\u552f\u4e00\u7684 Gauge \u5bf9\u8c61\uff1b<\/li>\n\n\n\n<li>3.<strong>\u5efa\u7acb\u5bf9\u8c61\u5f15\u7528<\/strong> \uff1a\u5c06 Gauge \u4e0e\u6211\u4eec\u7684 <code>runtimeInfo<\/code> \u5bf9\u8c61\u7ed1\u5b9a\uff1b<\/li>\n\n\n\n<li>4.<strong>\u6ce8\u518c\u5230\u5168\u5c40Registry<\/strong> \uff1a\u786e\u4fdd\u540e\u7eed\u53ef\u4ee5\u901a\u8fc7\u6307\u6807\u540d\u79f0\u627e\u5230\u8fd9\u4e2a Gauge\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u8bbe\u8ba1\u8003\u91cf<\/strong> \uff1a\u653e\u5728 onethread-core \u5305\u4e2d\uff0c\u610f\u5473\u7740\u6846\u67b6\u7684\u76d1\u63a7\u80fd\u529b\u662f\"\u5185\u7f6e\"\u7684\uff0c\u4e0d\u9700\u8981\u989d\u5916\u7684\u914d\u7f6e\u5c31\u80fd\u5de5\u4f5c\u3002\u4f46\u8fd9\u91cc\u6709\u4e2a\u5de7\u5999\u7684\u8bbe\u8ba1\uff1a\u5982\u679c classpath \u4e2d\u6ca1\u6709\u5177\u4f53\u7684 Registry \u5b9e\u73b0\uff08\u6bd4\u5982 prometheus registry\uff09\uff0c\u8fd9\u4e9b\u6307\u6807\u8c03\u7528\u4e0d\u4f1a\u62a5\u9519\uff0c\u800c\u662f\u4f1a\u88ab\"\u9759\u9ed8\u5ffd\u7565\"\u3002<\/p>\n\n\n\n<p><strong>spring-boot-starter-actuator<\/strong> \uff08\u4f4d\u4e8e onethread-common-spring-boot-starter \u5305\uff09\uff1a<\/p>\n\n\n\n<p>Actuator \u7684\u4f5c\u7528\u8fdc\u4e0d\u6b62\u66b4\u9732\u51e0\u4e2a HTTP \u7aef\u70b9\u90a3\u4e48\u7b80\u5355\uff0c\u5b83\u662f Spring Boot \u5e94\u7528<strong>\u751f\u4ea7\u5c31\u7eea<\/strong> \u7684\u6838\u5fc3\u7ec4\u4ef6\u3002<\/p>\n\n\n\n<p>\u5728\u76d1\u63a7\u65b9\u9762\uff0cActuator \u4e3b\u8981\u505a\u4e86\u8fd9\u51e0\u4ef6\u4e8b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>1.<strong>\u81ea\u52a8\u914d\u7f6eMeterRegistry<\/strong> \uff1a\u6839\u636e classpath \u4e2d\u7684\u4f9d\u8d56\u81ea\u52a8\u521b\u5efa\u5bf9\u5e94\u7684 Registry Bean\u3002<\/li>\n\n\n\n<li>2.<strong>\u6307\u6807\u6536\u96c6\u5668\u6ce8\u518c<\/strong> \uff1a\u81ea\u52a8\u6ce8\u518c JVM\u3001\u7cfb\u7edf\u3001Web \u7b49\u5404\u79cd\u5185\u7f6e\u6307\u6807\u6536\u96c6\u5668\u3002<\/li>\n\n\n\n<li>3.<strong>\u7aef\u70b9\u66b4\u9732<\/strong> \uff1a\u63d0\u4f9b <code>\/actuator\/metrics<\/code>\u3001<code>\/actuator\/prometheus<\/code> \u7b49\u7aef\u70b9\u3002<\/li>\n\n\n\n<li>4.<strong>\u5b89\u5168\u63a7\u5236<\/strong> \uff1a\u652f\u6301\u5bf9\u76d1\u63a7\u7aef\u70b9\u7684\u8bbf\u95ee\u63a7\u5236\u548c\u6743\u9650\u7ba1\u7406\u3002<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">3. \u8865\u5145\u8bf4\u660e\u4e0e\u68c0\u67e5\u70b9<\/h4>\n\n\n\n<p>\u4e3a\u4e86\u8ba9\u4e0a\u8ff0\u4ee3\u7801\u6b63\u5e38\u5de5\u4f5c\uff0c\u4f60\u9700\u8981\u786e\u4fdd <code>core<\/code> \u6a21\u5757\u4e2d\u7684 <code>ApplicationProperties<\/code> \u80fd\u591f\u83b7\u53d6\u5230\u5e94\u7528\u540d\u79f0\u3002<\/p>\n\n\n\n<p><strong>\u68c0\u67e5\u6587\u4ef6\uff1a<\/strong> <code>core\/src\/main\/java\/com\/nageoffer\/onethread\/core\/config\/ApplicationProperties.java<\/code><\/p>\n\n\n\n<p>\u5982\u679c\u76ee\u524d\u8be5\u7c7b\u662f\u7a7a\u7684\u6216\u8005\u6ca1\u6709\u9759\u6001\u65b9\u6cd5\uff0c\u9700\u8981\u8865\u5145\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.core.config;\n\n\/**\n * \u5168\u5c40\u5e94\u7528\u5c5e\u6027\u6301\u6709\u8005\n *\/\npublic class ApplicationProperties {\n\n    \n}<\/code><\/pre>\n\n\n\n<p>\u8fd9\u4e2a <code>applicationName<\/code> \u7684\u503c\uff0c\u6211\u4eec\u5c06\u5728\u4e0b\u4e00\u90e8\u5206\uff08Spring \u96c6\u6210\uff09\u4e2d\uff0c\u901a\u8fc7 Spring \u7684 <code>Environment<\/code> \u81ea\u52a8\u6ce8\u5165\u8fdb\u53bb\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>\u7b2c\u4e00\u90e8\u5206\u603b\u7ed3\uff1a<\/strong><br>\u6211\u4eec\u5b8c\u6210\u4e86\u5730\u57fa\u7684\u642d\u5efa\u3002<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>POM \u4f9d\u8d56<\/strong>\uff1a<code>core<\/code> \u5f15\u5165\u4e86 <code>micrometer-core<\/code>\uff0c<code>starter<\/code> \u5f15\u5165\u4e86 <code>actuator<\/code>\u3002<\/li>\n\n\n\n<li><strong>\u76d1\u63a7\u903b\u8f91<\/strong>\uff1a\u5728 <code>ThreadPoolMonitor<\/code> \u4e2d\u5b9e\u73b0\u4e86\u57fa\u4e8e\u7f13\u5b58\u7684 Gauge \u6307\u6807\u6ce8\u518c\u903b\u8f91\uff0c\u89e3\u51b3\u4e86\u5bf9\u8c61\u5f15\u7528\u53d8\u66f4\u5bfc\u81f4\u7684\u6570\u636e\u91c7\u96c6\u5931\u6548\u95ee\u9898\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u4e0b\u4e00\u6b65\uff08\u7b2c\u4e8c\u90e8\u5206\uff09<\/strong>\uff0c\u6211\u4eec\u5c06\u8bb2\u89e3\u5982\u4f55\u4fee\u6539 <code>starter<\/code> \u6a21\u5757\u7684\u81ea\u52a8\u914d\u7f6e\uff0c\u5c06 Spring \u73af\u5883\u4e2d\u7684\u5e94\u7528\u540d\u79f0\u6ce8\u5165\u5230 Core\uff0c\u5e76\u914d\u7f6e Actuator \u7aef\u70b9\u3002<\/p>\n\n\n\n<p>\u597d\u7684\uff0c\u6211\u4eec\u8fdb\u5165 <strong>\u7b2c\u4e8c\u90e8\u5206\uff1aStarter \u81ea\u52a8\u914d\u7f6e\u4e0e Spring Boot Actuator \u96c6\u6210<\/strong>\u3002<\/p>\n\n\n\n<p>\u8fd9\u4e00\u90e8\u5206\u7684\u91cd\u70b9\u662f\u5c06 Core \u6a21\u5757\u4e2d\u5199\u597d\u7684\u76d1\u63a7\u903b\u8f91\uff08<code>ThreadPoolMonitor<\/code>\uff09\u4e0e Spring Boot \u7684\u751f\u6001\u73af\u5883\u8fde\u63a5\u8d77\u6765\u3002\u6211\u4eec\u9700\u8981\u505a\u4e09\u4ef6\u4e8b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u914d\u7f6e\u6620\u5c04<\/strong>\uff1a\u8ba9\u7528\u6237\u80fd\u5728 <code>application.yml<\/code> \u4e2d\u914d\u7f6e\u76d1\u63a7\u53c2\u6570\uff08\u5f00\u542f\/\u5173\u95ed\u3001\u91c7\u96c6\u7c7b\u578b\u3001\u95f4\u9694\uff09\u3002<\/li>\n\n\n\n<li><strong>\u73af\u5883\u6ce8\u5165<\/strong>\uff1a\u81ea\u52a8\u83b7\u53d6 Spring \u5e94\u7528\u540d\u79f0\uff08<code>spring.application.name<\/code>\uff09\u5e76\u6ce8\u5165\u5230 Core \u6a21\u5757\u3002<\/li>\n\n\n\n<li><strong>Bean \u88c5\u914d<\/strong>\uff1a\u5728 Spring \u542f\u52a8\u65f6\u81ea\u52a8\u521d\u59cb\u5316\u76d1\u63a7\u7ec4\u4ef6\u3002<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u6269\u5c55\u914d\u7f6e\u5c5e\u6027\u7c7b (Properties)<\/h3>\n\n\n\n<p>\u9996\u5148\uff0c\u6211\u4eec\u9700\u8981\u5728 Starter \u6a21\u5757\u4e2d\u5b9a\u4e49\u76d1\u63a7\u76f8\u5173\u7684\u914d\u7f6e\u5c5e\u6027\u3002\u6839\u636e\u524d\u6587\u7684\u8bbe\u8ba1\uff0c\u914d\u7f6e\u524d\u7f00\u4e3a <code>onethread.monitor<\/code>\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84\uff1a<\/strong> <code>starter\/src\/main\/java\/com\/nageoffer\/onethread\/starter\/config\/BootstrapCoreProperties.java<\/code><\/p>\n\n\n\n<p><strong>\u4ee3\u7801\u4fee\u6539\uff1a<\/strong><br>\u6211\u4eec\u5728\u73b0\u6709\u7684 <code>BootstrapCoreProperties<\/code> \u4e2d\u589e\u52a0 <code>Monitor<\/code> \u5185\u90e8\u7c7b\uff0c\u6216\u8005\u76f4\u63a5\u6dfb\u52a0\u5b57\u6bb5\u3002\u4e3a\u4e86\u7ed3\u6784\u6e05\u6670\uff0c\u5efa\u8bae\u589e\u52a0\u5185\u90e8\u7c7b\u7ed3\u6784\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.starter.config;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationProperties;\n\n\/**\n * \u6846\u67b6\u6838\u5fc3\u914d\u7f6e\u7c7b\n *\/\n@Data\n@ConfigurationProperties(prefix = \"onethread\")\npublic class BootstrapCoreProperties {\n\n    \/\/ ... \u5176\u4ed6\u5df2\u6709\u914d\u7f6e ...\n\n    \/**\n     * \u76d1\u63a7\u76f8\u5173\u914d\u7f6e\n     *\/\n    private Monitor monitor = new Monitor();\n\n    @Data\n    public static class Monitor {\n        \/**\n         * \u662f\u5426\u5f00\u542f\u76d1\u63a7\n         *\/\n        private boolean enable = true;\n\n        \/**\n         * \u91c7\u96c6\u7c7b\u578b\uff1alog \u6216 micrometer\n         *\/\n        private String collectType = \"micrometer\";\n\n        \/**\n         * \u91c7\u96c6\u95f4\u9694\uff08\u79d2\uff09\n         *\/\n        private int collectInterval = 10;\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u6539\u9020\u81ea\u52a8\u914d\u7f6e\u7c7b (AutoConfiguration)<\/h3>\n\n\n\n<p>\u63a5\u4e0b\u6765\uff0c\u4fee\u6539\u81ea\u52a8\u914d\u7f6e\u7c7b\uff0c\u5b9e\u4f8b\u5316 <code>ThreadPoolMonitor<\/code> \u5e76\u542f\u52a8\u5b83\u3002\u8fd9\u91cc\u6709\u4e00\u4e2a\u5173\u952e\u70b9\uff1a<strong>\u5e94\u7528\u540d\u79f0\u7684\u6ce8\u5165<\/strong>\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84\uff1a<\/strong> <code>starter\/src\/main\/java\/com\/nageoffer\/onethread\/starter\/config\/DynamicThreadPoolAutoConfiguration.java<\/code><\/p>\n\n\n\n<p><strong>\u4ee3\u7801\u4fee\u6539\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package com.nageoffer.onethread.starter.config;\n\nimport com.nageoffer.onethread.core.config.ApplicationProperties;\nimport com.nageoffer.onethread.core.monitor.ThreadPoolMonitor;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\nimport org.springframework.boot.context.properties.EnableConfigurationProperties;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\nimport org.springframework.util.StringUtils;\n\n\/**\n * \u52a8\u6001\u7ebf\u7a0b\u6c60\u81ea\u52a8\u914d\u7f6e\u7c7b\n *\/\n@Slf4j\n@Configuration\n@EnableConfigurationProperties(BootstrapCoreProperties.class)\npublic class DynamicThreadPoolAutoConfiguration {\n\n    \/\/ ... \u5176\u4ed6 Bean \u5b9a\u4e49 (\u5982 ConfigParser \u7b49) ...\n\n    \/**\n     * \u6ce8\u518c\u76d1\u63a7\u7ec4\u4ef6\n     * \u4ec5\u5f53 onethread.monitor.enable = true (\u6216\u4e0d\u586b\u9ed8\u8ba4 true) \u65f6\u52a0\u8f7d\n     *\/\n    @Bean\n    @ConditionalOnProperty(prefix = \"onethread.monitor\", name = \"enable\", havingValue = \"true\", matchIfMissing = true)\n    public ThreadPoolMonitor threadPoolMonitor(Environment environment, BootstrapCoreProperties properties) {\n        \/\/ 1. \u83b7\u53d6 Spring \u5e94\u7528\u540d\u79f0\n        String appName = environment.getProperty(\"spring.application.name\", \"default-application\");\n\n        \/\/ 2. \u6ce8\u5165\u5230 Core \u6a21\u5757\u7684\u5168\u5c40\u914d\u7f6e\u4e2d\n        \/\/ \u8fd9\u6837 Core \u6a21\u5757\u5728\u6253 Tag \u65f6\u5c31\u80fd\u83b7\u53d6\u5230 application.name\n        ApplicationProperties.setApplicationName(appName);\n\n        \/\/ 3. \u521b\u5efa\u76d1\u63a7\u7ec4\u4ef6\n        ThreadPoolMonitor monitor = new ThreadPoolMonitor();\n\n        \/\/ 4. \u6839\u636e\u914d\u7f6e\u542f\u52a8\u76d1\u63a7 (micrometer \u6216 log)\n        BootstrapCoreProperties.Monitor monitorConfig = properties.getMonitor();\n        monitor.start(\n            monitorConfig.getCollectInterval(), \n            monitorConfig.getCollectType()\n        );\n\n        log.info(\"OneThread Monitor initialized. Type: {}, Interval: {}s\", \n                 monitorConfig.getCollectType(), monitorConfig.getCollectInterval());\n\n        return monitor;\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u7406\u89e3 Starter \u7684\u804c\u8d23\u8fb9\u754c<\/h3>\n\n\n\n<p>\u5230\u76ee\u524d\u4e3a\u6b62\uff0cStarter \u6a21\u5757\u5df2\u7ecf\u5b8c\u6210\u4e86\u5b83\u7684\u4f7f\u547d\u3002\u8fd9\u91cc\u6709\u4e00\u4e2a\u975e\u5e38\u91cd\u8981\u7684\u8bbe\u8ba1\u7ec6\u8282\u9700\u8981\u56de\u987e\uff1a<\/p>\n\n\n\n<p><strong>Starter \u5f15\u5165\u4e86\u4ec0\u4e48\uff1f<\/strong><br>\u5728 Part 1 \u4e2d\uff0c\u6211\u4eec\u5728 <code>starter\/pom.xml<\/code> \u4e2d\u5f15\u5165\u4e86 <code>spring-boot-starter-actuator<\/code>\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-actuator&lt;\/artifactId&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n\n\n\n<p><strong>Starter \u6ca1\u6709\u5f15\u5165\u4ec0\u4e48\uff1f<\/strong><br>Starter <strong>\u6ca1\u6709<\/strong> \u5f15\u5165 <code>micrometer-registry-prometheus<\/code>\u3002<\/p>\n\n\n\n<p><strong>\u4e3a\u4ec0\u4e48\uff1f<\/strong><br>\u8fd9\u662f\u4e3a\u4e86\u4fdd\u6301\u6846\u67b6\u7684\u4e2d\u7acb\u6027\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ThreadPoolMonitor<\/code> (\u5728 Core \u4e2d) \u901a\u8fc7 <code>micrometer-core<\/code> \u7684 API \u6ce8\u518c\u6307\u6807\uff08<code>Metrics.gauge<\/code>\uff09\u3002<\/li>\n\n\n\n<li><code>Metrics.globalRegistry<\/code> \u662f\u4e00\u4e2a\u7ec4\u5408\u6ce8\u518c\u8868\u3002<\/li>\n\n\n\n<li>\u5982\u679c\u7528\u6237\u5728\u5e94\u7528\u5c42\uff08\u5982 <code>example<\/code> \u6a21\u5757\uff09\u5f15\u5165\u4e86 Prometheus\uff0cMicrometer \u4f1a\u81ea\u52a8\u53d1\u73b0\u5e76\u5c06\u6307\u6807\u8f93\u51fa\u4e3a Prometheus \u683c\u5f0f\u3002<\/li>\n\n\n\n<li>\u5982\u679c\u7528\u6237\u5f15\u5165\u7684\u662f InfluxDB\uff0c\u5c31\u4f1a\u8f93\u51fa\u4e3a InfluxDB \u683c\u5f0f\u3002<\/li>\n\n\n\n<li>\u5982\u679c\u7528\u6237\u4ec0\u4e48\u90fd\u6ca1\u5f15\uff0cActuator \u4f9d\u7136\u80fd\u5de5\u4f5c\uff0c\u4f46\u4e0d\u4f1a\u6709\u7279\u5b9a\u7684\u540e\u7aef\u5b58\u50a8\u683c\u5f0f\uff0c\u53ea\u4f1a\u663e\u793a\u5728 <code>\/actuator\/metrics<\/code> \u63a5\u53e3\u4e2d\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u8ba9 <code>oneThread<\/code> \u6846\u67b6\u53ef\u4ee5\u7075\u6d3b\u9002\u5e94\u5404\u79cd\u76d1\u63a7\u73af\u5883\u3002<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>spring-boot-starter-actuator<\/strong> \uff08\u4f4d\u4e8e onethread-common-spring-boot-starter \u5305\uff09\uff1a<\/p>\n\n\n\n<p>Actuator \u7684\u4f5c\u7528\u8fdc\u4e0d\u6b62\u66b4\u9732\u51e0\u4e2a HTTP \u7aef\u70b9\u90a3\u4e48\u7b80\u5355\uff0c\u5b83\u662f Spring Boot \u5e94\u7528<strong>\u751f\u4ea7\u5c31\u7eea<\/strong> \u7684\u6838\u5fc3\u7ec4\u4ef6\u3002<\/p>\n\n\n\n<p>\u5728\u76d1\u63a7\u65b9\u9762\uff0cActuator \u4e3b\u8981\u505a\u4e86\u8fd9\u51e0\u4ef6\u4e8b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>1.<strong>\u81ea\u52a8\u914d\u7f6eMeterRegistry<\/strong> \uff1a\u6839\u636e classpath \u4e2d\u7684\u4f9d\u8d56\u81ea\u52a8\u521b\u5efa\u5bf9\u5e94\u7684 Registry Bean\u3002<\/li>\n\n\n\n<li>2.<strong>\u6307\u6807\u6536\u96c6\u5668\u6ce8\u518c<\/strong> \uff1a\u81ea\u52a8\u6ce8\u518c JVM\u3001\u7cfb\u7edf\u3001Web \u7b49\u5404\u79cd\u5185\u7f6e\u6307\u6807\u6536\u96c6\u5668\u3002<\/li>\n\n\n\n<li>3.<strong>\u7aef\u70b9\u66b4\u9732<\/strong> \uff1a\u63d0\u4f9b <code>\/actuator\/metrics<\/code>\u3001<code>\/actuator\/prometheus<\/code> \u7b49\u7aef\u70b9\u3002<\/li>\n\n\n\n<li>4.<strong>\u5b89\u5168\u63a7\u5236<\/strong> \uff1a\u652f\u6301\u5bf9\u76d1\u63a7\u7aef\u70b9\u7684\u8bbf\u95ee\u63a7\u5236\u548c\u6743\u9650\u7ba1\u7406\u3002<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Actuator \u81ea\u52a8\u914d\u7f6e\u7684\u6838\u5fc3\u903b\u8f91\uff08\u7b80\u5316\u7248\uff09@ConditionalOnClass(PrometheusMeterRegistry.class)@AutoConfigurationpublicclassPrometheusMetricsExportAutoConfiguration{@Bean@ConditionalOnMissingBeanpublicPrometheusMeterRegistryprometheusMeterRegistry(){returnnewPrometheusMeterRegistry(PrometheusConfig.DEFAULT);}}<\/code><\/pre>\n\n\n\n<p><strong>\u4e3a\u4ec0\u4e48\u653e\u5728\u516c\u5171starter\u5305\uff1f<\/strong> \u56e0\u4e3a Actuator \u63d0\u4f9b\u7684\u662f<strong>\u57fa\u7840\u76d1\u63a7\u80fd\u529b<\/strong> \uff0c\u6bd4\u5982\u52a8\u6001\u7ebf\u7a0b\u6c60\u76d1\u63a7\u6307\u6807\u3001JVM \u5185\u5b58\u4f7f\u7528\u3001GC \u60c5\u51b5\u3001HTTP \u8bf7\u6c42\u7edf\u8ba1\u7b49\uff0c\u8fd9\u4e9b\u662f Apollo\u3001Nacos \u7ec4\u4ef6\u5305\u90fd\u9700\u8981\u7684\u3002\u628a\u5b83\u653e\u5728\u516c\u5171\u5305\u4e2d\uff0c\u610f\u5473\u7740\u6240\u6709\u4f7f\u7528 oneThread \u7684\u5e94\u7528\u90fd\u4f1a\u81ea\u52a8\u83b7\u5f97\u8fd9\u4e9b\u57fa\u7840\u76d1\u63a7\u80fd\u529b\u3002<\/p>\n\n\n\n<p><strong>micrometer-registry-prometheus<\/strong> \uff08\u4f4d\u4e8e onethread-nacos-cloud-example \u5305\uff09\uff1a<\/p>\n\n\n\n<p>\u8fd9\u4e2a\u4f9d\u8d56\u662f<strong>\u76d1\u63a7\u540e\u7aef\u7684\u5177\u4f53\u5b9e\u73b0<\/strong> \uff0c\u5b83\u7684\u4f5c\u7528\u662f\u5c06 Micrometer \u7684\u901a\u7528\u6307\u6807\u683c\u5f0f\u8f6c\u6362\u4e3a Prometheus \u7279\u6709\u7684\u683c\u5f0f\u3002<\/p>\n\n\n\n<p>\u6df1\u5165\u6765\u770b\uff0c\u8fd9\u4e2a Registry \u505a\u4e86\u4ee5\u4e0b\u51e0\u4ef6\u4e8b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>1.<strong>\u683c\u5f0f\u8f6c\u6362<\/strong> \uff1a\u5c06 Micrometer \u7684 Gauge\u3001Counter \u7b49\u8f6c\u6362\u4e3a Prometheus \u7684 metric \u683c\u5f0f\uff1b<\/li>\n\n\n\n<li>2.<strong>\u6807\u7b7e\u5904\u7406<\/strong> \uff1a\u5904\u7406\u6807\u7b7e\u7684\u547d\u540d\u89c4\u8303\uff08\u6bd4\u5982\u5c06 <code>.<\/code> \u8f6c\u6362\u4e3a <code>_<\/code>\uff09\uff1b<\/li>\n\n\n\n<li>3.<strong>\u6570\u636e\u66b4\u9732<\/strong> \uff1a\u901a\u8fc7 <code>\/actuator\/prometheus<\/code> \u7aef\u70b9\u4ee5 Prometheus \u683c\u5f0f\u66b4\u9732\u6307\u6807\u6570\u636e\uff1b<\/li>\n\n\n\n<li>4.<strong>\u91c7\u96c6\u4f18\u5316<\/strong> \uff1a\u652f\u6301 Prometheus \u7684 scrape \u673a\u5236\uff0c\u4f18\u5316\u6570\u636e\u91c7\u96c6\u6027\u80fd\u3002<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"914\" height=\"1024\" src=\"https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766843714-image-914x1024.png\" alt=\"\" class=\"wp-image-1730\" srcset=\"https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766843714-image-914x1024.png 914w, https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766843714-image-268x300.png 268w, https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766843714-image-768x861.png 768w, https:\/\/eve2333.top\/wp-content\/uploads\/2025\/12\/1766843714-image.png 1153w\" sizes=\"auto, (max-width: 914px) 100vw, 914px\" \/><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u7b2c\u4e8c\u90e8\u5206\u603b\u7ed3<\/h3>\n\n\n\n<p>\u6211\u4eec\u5728\u8fd9\u4e00\u6b65\u5b8c\u6210\u4e86\u6846\u67b6\u4e0e Spring Boot \u7684\u201c\u63e1\u624b\u201d\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u914d\u7f6e<\/strong>\uff1a\u7528\u6237\u53ef\u4ee5\u901a\u8fc7 <code>onethread.monitor.collect-type=micrometer<\/code> \u6765\u5f00\u542f Micrometer \u6a21\u5f0f\u3002<\/li>\n\n\n\n<li><strong>\u6ce8\u5165<\/strong>\uff1a\u5229\u7528 <code>Environment<\/code> \u5c06 <code>spring.application.name<\/code> \u4f20\u9012\u7ed9\u4e86\u5e95\u5c42\u3002<\/li>\n\n\n\n<li><strong>\u542f\u52a8<\/strong>\uff1a<code>ThreadPoolMonitor<\/code> \u5728 Spring \u5bb9\u5668\u542f\u52a8\u65f6\u88ab\u6b63\u786e\u521d\u59cb\u5316\u548c\u8fd0\u884c\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u4e0b\u4e00\u6b65\uff08\u7b2c\u4e09\u90e8\u5206\uff09\uff1a<\/strong><br>\u6211\u4eec\u5c06\u8fdb\u5165 <strong>Prometheus \u63a5\u5165\u5b9e\u6218<\/strong>\u3002\u8fd9\u4e00\u6b65\u662f\u5728\u5177\u4f53\u7684\u5e94\u7528\u6a21\u5757\uff08\u5982 <code>example<\/code> \u6216 <code>spring-base<\/code>\uff09\u4e2d\u8fdb\u884c\u7684\u3002\u6211\u4eec\u5c06\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5f15\u5165 <code>micrometer-registry-prometheus<\/code> \u4f9d\u8d56\u3002<\/li>\n\n\n\n<li>\u914d\u7f6e <code>application.yml<\/code> \u66b4\u9732 Actuator \u7aef\u70b9\u3002<\/li>\n\n\n\n<li>\u6f14\u793a\u5982\u4f55\u9a8c\u8bc1 Prometheus \u6570\u636e\u683c\u5f0f\u3002<\/li>\n\n\n\n<li>\uff08\u53ef\u9009\uff09\u7b80\u8ff0 Grafana \u7684\u914d\u7f6e\u601d\u8def\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u597d\u7684\uff0c\u6211\u4eec\u8fdb\u5165 <strong>\u7b2c\u4e09\u90e8\u5206\uff1aPrometheus \u63a5\u5165\u5b9e\u6218\u4e0e\u9a8c\u8bc1<\/strong>\u3002<\/p>\n\n\n\n<p>\u8fd9\u4e00\u90e8\u5206\u662f\u201c\u4e34\u95e8\u4e00\u811a\u201d\uff0c\u6211\u4eec\u5c06\u4ee5\u9879\u76ee\u4e2d\u7684 <code>example<\/code> \u6a21\u5757\u4e3a\u4f8b\uff0c\u6a21\u62df\u771f\u5b9e\u4e1a\u52a1\u5e94\u7528\u5982\u4f55\u63a5\u5165 <code>oneThread<\/code> \u7684\u76d1\u63a7\u4f53\u7cfb\uff0c\u5e76\u6700\u7ec8\u770b\u5230 Prometheus \u683c\u5f0f\u7684\u6570\u636e\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u5f15\u5165 Prometheus \u9002\u914d\u5668\u4f9d\u8d56<\/h3>\n\n\n\n<p>\u5728\u5177\u4f53\u5e94\u7528\u6a21\u5757\uff08\u8fd9\u91cc\u662f <code>example<\/code> \u6a21\u5757\uff09\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u660e\u786e\u544a\u8bc9 Micrometer\uff1a\u201c\u8bf7\u628a\u6307\u6807\u6570\u636e\u8f6c\u6362\u6210 Prometheus \u80fd\u770b\u61c2\u7684\u683c\u5f0f\u201d\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84\uff1a<\/strong> <code>example\/pom.xml<\/code><\/p>\n\n\n\n<p><strong>\u4ee3\u7801\u4fee\u6539\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependencies&gt;\n    &lt;!-- \u5f15\u5165 oneThread starter (\u524d\u9762\u6b65\u9aa4\u5df2\u5b8c\u6210) --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;com.nageoffer&lt;\/groupId&gt;\n        &lt;artifactId&gt;onethread-starter&lt;\/artifactId&gt;\n        &lt;version&gt;${project.version}&lt;\/version&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- \u6838\u5fc3\u6b65\u9aa4\uff1a\u5f15\u5165 Prometheus \u6ce8\u518c\u8868\u5b9e\u73b0 --&gt;\n    &lt;!-- \u8fd9\u4f1a\u8ba9 Actuator \u81ea\u52a8\u914d\u7f6e PrometheusMeterRegistry --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;io.micrometer&lt;\/groupId&gt;\n        &lt;artifactId&gt;micrometer-registry-prometheus&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n\n    &lt;!-- Spring Web (Actuator \u66b4\u9732\u7aef\u70b9\u9700\u8981 Web \u73af\u5883) --&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n        &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n    &lt;\/dependency&gt;\n&lt;\/dependencies&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u914d\u7f6e Actuator \u7aef\u70b9\u66b4\u9732<\/h3>\n\n\n\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cSpring Boot Actuator \u53ea\u66b4\u9732 <code>\/health<\/code> \u7aef\u70b9\u3002\u6211\u4eec\u9700\u8981\u4fee\u6539\u914d\u7f6e\u6587\u4ef6\uff0c\u5141\u8bb8\u5916\u90e8\u8bbf\u95ee Prometheus \u6570\u636e\u7aef\u70b9\u3002<\/p>\n\n\n\n<p><strong>\u6587\u4ef6\u8def\u5f84\uff1a<\/strong> <code>example\/src\/main\/resources\/application.yml<\/code><\/p>\n\n\n\n<p><strong>\u914d\u7f6e\u5185\u5bb9\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spring:\n  application:\n    name: onethread-example-app # \u8fd9\u4e2a\u540d\u5b57\u4f1a\u88ab\u81ea\u52a8\u6253\u5230\u6807\u7b7e application.name \u4e0a\n\nserver:\n  port: 8080\n\n# oneThread \u6846\u67b6\u914d\u7f6e\nonethread:\n  monitor:\n    enable: true             # \u5f00\u542f\u76d1\u63a7\n    collect-type: micrometer # \u6307\u5b9a\u4f7f\u7528 Micrometer \u6a21\u5f0f\n    collect-interval: 5      # \u4e3a\u4e86\u6d4b\u8bd5\u65b9\u4fbf\uff0c\u95f4\u9694\u8bbe\u77ed\u4e00\u70b9\uff0c\u6bd4\u5982 5\u79d2\n\n# Actuator \u7aef\u70b9\u914d\u7f6e\nmanagement:\n  endpoints:\n    web:\n      exposure:\n        include: \"*\" # \u751f\u4ea7\u73af\u5883\u5efa\u8bae\u53ea\u5f00\u542f \"prometheus,health,metrics\"\n  metrics:\n    tags:\n      application: ${spring.application.name} # \u989d\u5916\u4fdd\u969c\uff1a\u4e3a\u6240\u6709\u901a\u7528\u6307\u6807\u52a0\u5e94\u7528\u6807\u7b7e\n    export:\n      prometheus:\n        enabled: true<\/code><\/pre>\n\n\n\n<p>Prometheus \u548c Grafana \u4e5f\u6709\u7c7b\u4f3c\u7684\u544a\u8b66\u673a\u5236\uff0c\u57fa\u4e8e Micrometer \u6307\u6807\uff0c\u53ef\u4ee5\u8bbe\u8ba1\u4ee5\u4e0b\u544a\u8b66\u89c4\u5219\uff1a<\/p>\n\n\n\n<p><strong>\u7ebf\u7a0b\u6c60\u6d3b\u8dc3\u5ea6\u544a\u8b66<\/strong> \uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u6d3b\u8dc3\u7ebf\u7a0b\u6570\u8d85\u8fc7\u6700\u5927\u7ebf\u7a0b\u6570\u7684 80%\n(dynamic_thread_pool_active_size \/ dynamic_thread_pool_maximum_size) &gt; 0.8<\/code><\/pre>\n\n\n\n<p><strong>\u961f\u5217\u5806\u79ef\u544a\u8b66<\/strong> \uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u961f\u5217\u4f7f\u7528\u7387\u8d85\u8fc7 70%\n(dynamic_thread_pool_queue_size \/ dynamic_thread_pool_queue_capacity) &gt; 0.7<\/code><\/pre>\n\n\n\n<p><strong>\u62d2\u7edd\u7b56\u7565\u89e6\u53d1\u544a\u8b66<\/strong> \uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 5 \u5206\u949f\u5185\u62d2\u7edd\u6b21\u6570\u589e\u957f\u8d85\u8fc7 10 \u6b21\nincrease(dynamic_thread_pool_reject_count&#91;5m]) &gt; 10<\/code><\/pre>\n\n\n\n<p>\u7ed3\u5408\u5f53\u524d\u5148\u6709\u544a\u8b66\u80fd\u529b\uff0c\u5728 oneThread \u4e2d\u53ef\u4ee5\u5b9a\u4e49\u57fa\u7840\u544a\u8b66\u6307\u6807\uff0c\u5176\u4ed6\u4e2a\u6027\u5316\u6216\u8005\u4e34\u65f6\u544a\u8b66\u6307\u6807\u53ef\u4ee5\u5728\u76d1\u63a7\u4e2d\u95f4\u4ef6\u4e2d\u914d\u7f6e\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u542f\u52a8\u9a8c\u8bc1\u4e0e\u6570\u636e\u6838\u5bf9<\/h3>\n\n\n\n<p>\u73b0\u5728\uff0c\u542f\u52a8 <code>example<\/code> \u6a21\u5757\u7684\u4e3b\u7a0b\u5e8f\u3002<\/p>\n\n\n\n<p><strong>\u9a8c\u8bc1\u6b65\u9aa4\uff1a<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u8bbf\u95ee Prometheus \u7aef\u70b9<\/strong>\uff1a<br>\u6253\u5f00\u6d4f\u89c8\u5668\u6216\u4f7f\u7528\u7ec8\u7aef\u8bbf\u95ee\uff1a<code>http:\/\/localhost:8080\/actuator\/prometheus<\/code><\/li>\n\n\n\n<li><strong>\u641c\u7d22\u5173\u952e\u5b57<\/strong>\uff1a<br>\u5728\u8fd4\u56de\u7684\u832b\u832b\u591a\u6587\u672c\u4e2d\uff0c\u641c\u7d22 <code>dynamic_thread_pool<\/code>\uff08\u6ce8\u610f\uff1aMicrometer \u4f1a\u81ea\u52a8\u628a\u6211\u4eec\u4ee3\u7801\u91cc\u7684 <code>.<\/code> \u8f6c\u6362\u4e3a <code>_<\/code> \u4ee5\u7b26\u5408 Prometheus \u89c4\u8303\uff09\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u9884\u671f\u7ed3\u679c\uff1a<\/strong><br>\u4f60\u5e94\u8be5\u80fd\u770b\u5230\u7c7b\u4f3c\u4e0b\u9762\u7684\u8f93\u51fa\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># HELP dynamic_thread_pool_core_size \n# TYPE dynamic_thread_pool_core_size gauge\ndynamic_thread_pool_core_size{application_name=\"onethread-example-app\",dynamic_thread_pool_id=\"message-consume-executor\",} 4.0\n\n# HELP dynamic_thread_pool_active_size \n# TYPE dynamic_thread_pool_active_size gauge\ndynamic_thread_pool_active_size{application_name=\"onethread-example-app\",dynamic_thread_pool_id=\"message-consume-executor\",} 0.0\n\n# HELP dynamic_thread_pool_queue_size \n# TYPE dynamic_thread_pool_queue_size gauge\ndynamic_thread_pool_queue_size{application_name=\"onethread-example-app\",dynamic_thread_pool_id=\"message-consume-executor\",} 0.0<\/code><\/pre>\n\n\n\n<p><strong>\u539f\u7406\u89e3\u6790\uff1a<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u540d\u79f0\u8f6c\u6362<\/strong>\uff1aJava \u4ee3\u7801\u4e2d\u7684 <code>dynamic.thread-pool.core.size<\/code> \u53d8\u6210\u4e86 <code>dynamic_thread_pool_core_size<\/code>\u3002<\/li>\n\n\n\n<li><strong>\u6807\u7b7e\u6ce8\u5165<\/strong>\uff1a<code>application_name<\/code> \u662f\u6211\u4eec\u5728 Starter \u81ea\u52a8\u914d\u7f6e\u4e2d\u6ce8\u5165\u8fdb\u53bb\u7684\uff0c<code>dynamic_thread_pool_id<\/code> \u662f Core \u6a21\u5757\u8fd0\u884c\u65f6\u83b7\u53d6\u7684\u3002<\/li>\n\n\n\n<li><strong>\u6570\u503c<\/strong>\uff1a\u540e\u9762\u7684 <code>4.0<\/code>, <code>0.0<\/code> \u5c31\u662f\u901a\u8fc7 <code>Metrics.gauge<\/code> \u7ed1\u5b9a\u7684\u5b9e\u65f6\u503c\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">1. \u600e\u4e48\u627e\uff1f\u2014\u2014\u5c42\u6b21\u5316\u547d\u540d\uff08Naming\uff09<\/h3>\n\n\n\n<p><strong>\u4ee3\u7801\uff1a<\/strong>&nbsp;dynamic.thread-pool&nbsp;+&nbsp;name<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u75db\u70b9<\/strong>\uff1a\u5982\u679c\u4f60\u7684\u6307\u6807\u53eb\u00a0active_count\uff0c\u90a3\u4e48\u6570\u636e\u5e93\u8fde\u63a5\u6c60\u6709\u8fd9\u4e2a\u6307\u6807\uff0cTomcat \u7ebf\u7a0b\u6c60\u6709\uff0c\u4f60\u7684\u4e1a\u52a1\u7ebf\u7a0b\u6c60\u4e5f\u6709\u3002\u5728 Grafana \u91cc\u4e00\u641c\uff0c\u5168\u4e71\u5957\u4e86\u3002<\/li>\n\n\n\n<li><strong>\u901a\u900f\u7406\u89e3<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u8fd9\u5c31\u50cf\u7ed9\u6307\u6807\u52a0\u4e86\u4e2a**\u201c\u59d3\u6c0f\u201d**\u3002<\/li>\n\n\n\n<li>dynamic.thread-pool\u00a0\u662f\u59d3\uff0ccore.size\u00a0\u662f\u540d\u3002<\/li>\n\n\n\n<li><strong>\u597d\u5904<\/strong>\uff1a\u4f60\u5728 Grafana \u641c\u7d22\u680f\u8f93\u5165\u00a0dynamic.thread-pool\uff0c\u6240\u6709\u76f8\u5173\u7684\u76d1\u63a7\u9879\uff08\u6838\u5fc3\u7ebf\u7a0b\u6570\u3001\u961f\u5217\u5927\u5c0f\u3001\u6d3b\u8dc3\u6570\uff09\u77ac\u95f4\u50cf\u4e00\u4e2a\u6587\u4ef6\u5939\u4e00\u6837\u5c55\u793a\u5728\u4f60\u9762\u524d\uff0c\u65e2\u4e0d\u4f1a\u8ddf\u522b\u7684\u7ec4\u4ef6\u51b2\u7a81\uff0c\u53c8\u65b9\u4fbf\u4e00\u952e\u751f\u6210\u5927\u76d8\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. \u600e\u4e48\u770b\uff1f\u2014\u2014Gauge \u6307\u6807\u7684\u9009\u62e9\uff08Type\uff09<\/h3>\n\n\n\n<p><strong>\u9009\u62e9\uff1a<\/strong>&nbsp;Gauge\uff08\u4eea\u8868\u76d8\/\u89c4\uff09 vs.&nbsp;Counter\uff08\u8ba1\u6570\u5668\uff09<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u75db\u70b9<\/strong>\uff1a\u5f88\u591a\u521d\u5b66\u8005\u5206\u4e0d\u6e05\u4ec0\u4e48\u65f6\u5019\u7528\u4ec0\u4e48\u3002<\/li>\n\n\n\n<li><strong>\u901a\u900f\u7406\u89e3<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>Counter \u662f\u201c\u91cc\u7a0b\u8868\u201d<\/strong>\uff1a\u5b83\u53ea\u80fd\u4e00\u76f4\u6da8\uff0c\u4e0d\u80fd\u8dcc\u3002\u6bd4\u5982\u201c\u5904\u7406\u8fc7\u7684\u4efb\u52a1\u603b\u6570\u201d\uff0c\u6628\u5929100\uff0c\u4eca\u5929200\uff0c\u5b83\u8bb0\u5f55\u7684\u662f\u7d2f\u8ba1\u503c\u3002<\/li>\n\n\n\n<li><strong>Gauge \u662f\u201c\u901f\u5ea6\u8868\/\u6cb9\u8868\u201d<\/strong>\uff1a\u5b83\u53ef\u4ee5\u6da8\u4e5f\u53ef\u4ee5\u8dcc\uff0c\u53cd\u6620\u7684\u662f<strong>\u5f53\u4e0b\u7684\u72b6\u6001<\/strong>\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u4e3a\u4ec0\u4e48\u9009 Gauge\uff1f<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u7ebf\u7a0b\u6c60\u7684\u573a\u666f\u662f\uff1a\u73b0\u5728\u6709\u51e0\u4e2a\u7ebf\u7a0b\u5728\u5e72\u6d3b\uff1f\u73b0\u5728\u961f\u5217\u91cc\u5806\u4e86\u51e0\u4e2a\u4efb\u52a1\uff1f<\/li>\n\n\n\n<li>\u4e0a\u4e00\u79d2\u662f 10 \u4e2a\uff0c\u4e0b\u4e00\u79d2\u53ef\u80fd\u662f 5 \u4e2a\u3002\u6211\u4eec\u9700\u8981\u7684\u662f<strong>\u77ac\u65f6\u5feb\u7167<\/strong>\uff0c\u800c\u4e0d\u662f\u7d2f\u8ba1\u503c\u3002\u6240\u4ee5\u5fc5\u987b\u9009 Gauge\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u673a\u5236<\/strong>\uff1aGauge \u5c31\u50cf\u4e00\u4e2a\u201c\u63a2\u9488\u201d\uff0cPrometheus \u6bcf\u9694\u51e0\u79d2\u6765\u95ee\u5b83\u4e00\u4e0b\uff1a\u201c\u73b0\u5728\u7684\u6570\u503c\u662f\u591a\u5c11\uff1f\u201d\uff0c\u5b83\u5c31\u8bfb\u4e00\u4e0b\u5f53\u524d\u7684\u5185\u5b58\u503c\u544a\u8bc9 Prometheus\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u600e\u4e48\u7ec6\u5206\uff1f\u2014\u2014\u591a\u7ef4\u5ea6\u6807\u7b7e\uff08Tags\uff09<\/h3>\n\n\n\n<p><strong>\u6838\u5fc3\u6807\u7b7e\uff1a<\/strong>&nbsp;application.name\uff08\u54ea\u4e2a\u5e94\u7528\uff09 +&nbsp;thread-pool.id\uff08\u54ea\u4e2a\u6c60\u5b50\uff09<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u75db\u70b9<\/strong>\uff1a\u5982\u679c\u53ea\u6709\u6307\u6807\u540d\uff0c\u4f60\u53d1\u73b0\u00a0active_count = 100\uff0c\u4f60\u614c\u4e86\u3002\u4f46\u4f60\u4e0d\u77e5\u9053\u662f\u201c\u8ba2\u5355\u670d\u52a1\u201d\u70b8\u4e86\uff0c\u8fd8\u662f\u201c\u652f\u4ed8\u670d\u52a1\u201d\u70b8\u4e86\uff1f\u662f\u201cVIP\u7ebf\u7a0b\u6c60\u201d\u6ee1\u4e86\uff0c\u8fd8\u662f\u201c\u65e5\u5fd7\u7ebf\u7a0b\u6c60\u201d\u6ee1\u4e86\uff1f<\/li>\n\n\n\n<li><strong>\u901a\u900f\u7406\u89e3<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u6807\u7b7e\u5c31\u662f**\u201c\u5207\u86cb\u7cd5\u7684\u5200\u201d**\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e00\u5200\uff08\u5e94\u7528\u7ea7\uff09<\/strong>\uff1aapplication.name\u3002\u7528\u4e8e\u770b\u54ea\u4e2a\u5fae\u670d\u52a1\u8d1f\u8f7d\u9ad8\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e8c\u5200\uff08\u5b9e\u4f8b\u7ea7\uff09<\/strong>\uff1athread-pool.id\u3002\u7528\u4e8e\u770b\u670d\u52a1\u5185\u90e8\u5177\u4f53\u54ea\u4e2a\u7ebf\u7a0b\u6c60\u5728\u5fd9\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u5b9e\u6218\u5a01\u529b\uff08PromQL\uff09<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><em>\u60f3\u770b\u6574\u4e2a\u7cfb\u7edf\u7684\u62e5\u5835\u60c5\u51b5\uff1f<\/em>\u00a0<code>\u2192\u2192<\/code>\u00a0\u5ffd\u7565 ID\uff0c\u6309\u5e94\u7528\u805a\u5408\uff08sum by application\uff09\u3002<\/li>\n\n\n\n<li><em>\u60f3\u5b9a\u4f4d\u5177\u4f53\u6545\u969c\u70b9\uff1f<\/em>\u00a0<code>\u2192\u2192<\/code>\u00a0\u52a0\u4e0a ID \u8fc7\u6ee4\uff08id=\"payment-processor\"\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u6269\u5c55\u6027<\/strong>\uff1a\u6587\u4e2d\u63d0\u5230\u7684\u00a0environment\uff08\u751f\u4ea7\/\u6d4b\u8bd5\uff09\u548c\u00a0cluster\uff08\u673a\u623f\uff09\u6807\u7b7e\uff0c\u662f\u4e3a\u4e86\u5728\u66f4\u5927\u89c4\u6a21\u67b6\u6784\u4e0b\uff0c\u80fd\u4ece\u4e0a\u5e1d\u89c6\u89d2\u5feb\u901f\u4e0b\u94bb\u5230\u5c40\u90e8\u7ec6\u8282\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. \u600e\u4e48\u5b58\uff1f\u2014\u2014\u7f13\u5b58\u4e0e\u5f15\u7528\u7684\u827a\u672f\uff08\u6700\u5173\u952e\u7684\u6280\u672f\u70b9\uff09<\/h3>\n\n\n\n<p>\u8fd9\u662f\u6587\u4e2d<strong>\u6700\u786c\u6838<\/strong>\u7684\u90e8\u5206\uff0c\u4e5f\u662f\u6700\u5bb9\u6613\u51fa Bug \u7684\u5730\u65b9\u3002<\/p>\n\n\n\n<p><strong>\u95ee\u9898\u6839\u6e90\uff1a<\/strong><br>Micrometer \u7684&nbsp;Gauge&nbsp;\u6ce8\u518c\u673a\u5236\u662f**\u201c\u57fa\u4e8e\u5f15\u7528\u7684\u201d**\u3002<br>\u4f60\u53ef\u4ee5\u60f3\u8c61 Micrometer \u662f\u4e00\u4e2a\u89c2\u5bdf\u8005\uff0c\u4f60\u7ed9\u5b83\u4e00\u4e2a\u5bf9\u8c61\uff08Object A\uff09\uff0c\u544a\u8bc9\u5b83\uff1a\u201c\u76ef\u7740 A \u91cc\u7684&nbsp;activeCount&nbsp;\u5c5e\u6027\u770b\u201d\u3002<\/p>\n\n\n\n<p><strong>\u5982\u679c\u4e0d\u52a0\u7f13\u5b58\uff08\u9519\u8bef\u7684\u5199\u6cd5\uff09\uff1a<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u4f60\u6bcf\u9694 5 \u79d2\u91c7\u96c6\u4e00\u6b21\u6570\u636e\u3002<\/li>\n\n\n\n<li>\u4f60\u00a0new\u00a0\u4e86\u4e00\u4e2a\u65b0\u7684\u5bf9\u8c61\u00a0Info_B\uff0c\u91cc\u9762\u88c5\u7740\u6700\u65b0\u7684\u6570\u636e\u3002<\/li>\n\n\n\n<li>\u4f60\u628a\u00a0Info_B\u00a0\u6254\u7ed9 Micrometer\u3002<\/li>\n\n\n\n<li><strong>\u7ed3\u679c<\/strong>\uff1aMicrometer \u8fd8\u662f\u6b7b\u6b7b\u76ef\u7740\u539f\u6765\u7684\u00a0Info_A\uff08\u56e0\u4e3a Gauge \u6ce8\u518c\u540e\u5c31\u4e0d\u6362\u76ee\u6807\u4e86\uff09\uff0c\u800c\u00a0Info_A\u00a0\u65e9\u5c31\u8fc7\u65f6\u4e86\u6216\u8005\u88ab\u5783\u573e\u56de\u6536\uff08GC\uff09\u4e86\u3002<\/li>\n\n\n\n<li><strong>\u73b0\u8c61<\/strong>\uff1aPrometheus \u6293\u5230\u7684\u6570\u636e\u5168\u662f\u00a0NaN\uff08Not a Number\uff09\u6216\u8005\u6c38\u8fdc\u4e0d\u53d8\u5316\u7684\u8001\u6570\u636e\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u52a0\u4e86\u7f13\u5b58\u7684\u8bbe\u8ba1\uff08\u6b63\u786e\u7684\u5199\u6cd5\uff09\uff1a<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Map \u7f13\u5b58<\/strong>\uff1aMap&lt;\u7ebf\u7a0b\u6c60ID, Info\u5bf9\u8c61>\u3002<\/li>\n\n\n\n<li><strong>\u6d41\u7a0b<\/strong>\uff1a\n<ol class=\"wp-block-list\">\n<li>\u91c7\u96c6\u6570\u636e\u65f6\uff0c\u5148\u53bb Map \u91cc\u67e5\uff1a\u8fd9\u4e2a\u7ebf\u7a0b\u6c60\u4ee5\u524d\u6ce8\u518c\u8fc7\u5417\uff1f<\/li>\n\n\n\n<li><strong>\u5982\u679c\u662f\u65b0\u5ba2<\/strong>\uff1a\u521b\u5efa\u4e00\u4e2a\u00a0Info\u00a0\u5bf9\u8c61\uff0c\u5b58\u5165 Map\uff0c\u5e76\u6ce8\u518c\u7ed9 Micrometer\u3002<\/li>\n\n\n\n<li><strong>\u5982\u679c\u662f\u8001\u5ba2<\/strong>\uff1a<strong>\u4e0d\u8981\u521b\u5efa\u65b0\u5bf9\u8c61\uff0c\u4e5f\u4e0d\u8981\u91cd\u65b0\u6ce8\u518c\uff01<\/strong>\u00a0\u800c\u662f\u628a\u6700\u65b0\u91c7\u96c6\u5230\u7684\u6570\u503c\uff0c<strong>\u62f7\u8d1d\uff08Copy Properties\uff09<\/strong>\u00a0\u5230 Map \u91cc\u90a3\u4e2a<strong>\u65e7\u7684\u00a0Info\u00a0\u5bf9\u8c61<\/strong>\u4e2d\u3002<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li><strong>\u901a\u900f\u7406\u89e3\uff08\u9ed1\u677f\u64e6\u6bd4\u55bb\uff09<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li><strong>\u6ca1\u6709\u7f13\u5b58<\/strong>\uff1a\u4f60\u6bcf\u6b21\u90fd\u62ff\u4e00\u5757\u65b0\u9ed1\u677f\u5199\u4e0a\u6570\u5b57\uff0c\u4e3e\u7ed9 Micrometer \u770b\u3002Micrometer \u8bf4\uff1a\u201c\u6211\u53ea\u8ba4\u7b2c\u4e00\u5757\u9ed1\u677f\uff0c\u540e\u9762\u7684\u6211\u4e0d\u770b\u3002\u201d<\/li>\n\n\n\n<li><strong>\u6709\u7f13\u5b58<\/strong>\uff1a\u4f60\u53ea\u6709\u4e00\u5757\u9ed1\u677f\uff08\u6302\u5728 Map \u91cc\uff09\u3002\u6bcf\u6b21\u6570\u636e\u53d8\u4e86\uff0c\u4f60\u62ff\u9ed1\u677f\u64e6\u628a\u65e7\u6570\u5b57\u64e6\u6389\uff0c\u5199\u4e0a\u65b0\u6570\u5b57\u3002Micrometer \u4e00\u76f4\u76ef\u7740\u8fd9\u5757\u9ed1\u677f\uff0c\u81ea\u7136\u5c31\u80fd\u770b\u5230\u6700\u65b0\u7684\u53d8\u5316\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>ConcurrentHashMap \u7684\u4f5c\u7528\uff1a<\/strong><br>\u867d\u7136\u76ee\u524d\u662f\u5355\u7ebf\u7a0b\u91c7\u96c6\uff0c\u4f46\u4f5c\u4e3a\u5e95\u5c42\u6846\u67b6\uff0c\u5fc5\u987b\u4fdd\u8bc1\u7ebf\u7a0b\u5b89\u5168\u3002\u4e07\u4e00\u4ee5\u540e\u53d8\u6210\u591a\u7ebf\u7a0b\u5e76\u884c\u91c7\u96c6\u591a\u4e2a\u7ebf\u7a0b\u6c60\u7684\u6570\u636e\uff0c\u7528 HashMap \u5c31\u4f1a\u5bfc\u81f4\u6b7b\u5faa\u73af\u6216\u6570\u636e\u8986\u76d6\uff0cConcurrentHashMap \u662f\u4e3a\u4e86<strong>\u515c\u5e95\u5b89\u5168<\/strong>\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. Grafana \u53ef\u89c6\u5316\uff08\u52a0\u5206\u9879\uff09<\/h3>\n\n\n\n<p>\u867d\u7136\u4e0d\u9700\u8981\u5199\u4ee3\u7801\uff0c\u4f46\u4e86\u89e3\u5982\u4f55\u5728 Grafana \u4e2d\u5c55\u793a\u662f\u8fd9\u4e2a\u529f\u80fd\u7684\u6700\u7ec8\u95ed\u73af\u3002<\/p>\n\n\n\n<p><strong>\u64cd\u4f5c\u6d41\u7a0b\uff1a<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Prometheus Server<\/strong>\uff1a\u914d\u7f6e <code>prometheus.yml<\/code>\uff0c\u6dfb\u52a0\u4e00\u4e2a job \u6293\u53d6 <code>localhost:8080\/actuator\/prometheus<\/code>\u3002<\/li>\n\n\n\n<li><strong>Grafana \u6570\u636e\u6e90<\/strong>\uff1a\u6dfb\u52a0 Prometheus \u6570\u636e\u6e90\u3002<\/li>\n\n\n\n<li><strong>\u521b\u5efa Dashboard<\/strong>\uff1a\u65b0\u5efa\u9762\u677f\uff0c\u6dfb\u52a0 Query\u3002<\/li>\n<\/ol>\n\n\n\n<p><strong>\u793a\u4f8b PromQL (\u67e5\u8be2\u8bed\u53e5)\uff1a<\/strong> <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u67e5\u770b\u67d0\u7ebf\u7a0b\u6c60\u6d3b\u8dc3\u5ea6\u8d70\u52bf\uff1a<\/strong> <code>dynamic_thread_pool_active_size{application_name=\"onethread-example-app\", dynamic_thread_pool_id=\"message-consume-executor\"}<\/code><\/li>\n\n\n\n<li><strong>\u67e5\u770b\u961f\u5217\u5806\u79ef\u60c5\u51b5\uff1a<\/strong> <code>dynamic_thread_pool_queue_size<\/code><\/li>\n\n\n\n<li><strong>\u8ba1\u7b97\u961f\u5217\u4f7f\u7528\u7387 (\u767e\u5206\u6bd4)\uff1a<\/strong><br><code>promql (dynamic_thread_pool_queue_size \/ dynamic_thread_pool_queue_capacity) * 100<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\u603b\u7ed3<\/h3>\n\n\n\n<p>\u81f3\u6b64\uff0c\u6211\u4eec\u5c06\u6574\u4e2a Micrometer \u76d1\u63a7\u4f53\u7cfb\u96c6\u6210\u5230\u4e86 <code>oneThread<\/code> \u6846\u67b6\u4e2d\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Core \u5c42<\/strong>\uff1a\u63d0\u4f9b\u4e86\u4e0d\u4f9d\u8d56\u5177\u4f53\u5b9e\u73b0\u7684\u76d1\u63a7\u62bd\u8c61 (<code>Metrics.gauge<\/code>) \u548c\u7f13\u5b58\u673a\u5236\u3002<\/li>\n\n\n\n<li><strong>Starter \u5c42<\/strong>\uff1a\u5229\u7528 Spring Boot \u673a\u5236\u5b9e\u73b0\u4e86\u81ea\u52a8\u914d\u7f6e\u3001\u73af\u5883\u53c2\u6570\u6ce8\u5165 (<code>application.name<\/code>)\u3002<\/li>\n\n\n\n<li><strong>Example \u5c42<\/strong>\uff1a\u901a\u8fc7\u5f15\u5165 <code>micrometer-registry-prometheus<\/code> \u5b9e\u73b0\u4e86\u201c\u63d2\u4ef6\u5f0f\u201d\u7684\u76d1\u63a7\u540e\u7aef\u63a5\u5165\u3002<\/li>\n<\/ol>\n\n\n\n<p>\u8fd9\u79cd\u67b6\u6784\u8bbe\u8ba1\u4fdd\u8bc1\u4e86\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5982\u679c\u7528\u6237\u4e0d\u60f3\u7528 Prometheus\uff0c\u6539\u7528 InfluxDB\uff0c\u53ea\u9700\u8981\u5728 <code>example\/pom.xml<\/code> \u6362\u4e00\u4e2a\u4f9d\u8d56\uff0c\u6846\u67b6\u6838\u5fc3\u4ee3\u7801\u4e00\u884c\u4e0d\u7528\u6539\u3002<\/li>\n\n\n\n<li>\u5982\u679c\u7528\u6237\u5b8c\u5168\u4e0d\u60f3\u8981\u76d1\u63a7\uff0c\u914d\u7f6e <code>onethread.monitor.enable=false<\/code>\uff0c\u6574\u4e2a\u76d1\u63a7\u7ebf\u7a0b\u90fd\u4e0d\u4f1a\u542f\u52a8\uff0c\u96f6\u5f00\u9500\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u8fd9\u5c31\u662f\u4e00\u4e2a<strong>\u751f\u4ea7\u7ea7<\/strong>\u5f00\u6e90\u6846\u67b6\u5e94\u6709\u7684\u6269\u5c55\u6027\u4e0e\u5065\u58ee\u6027\u8bbe\u8ba1\u3002<\/p>\n\n\n\n<p><strong>\u6838\u5fc3\u4eae\u70b9\u603b\u7ed3<\/strong> \uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6574\u5957 Micrometer \u76d1\u63a7\u65b9\u6848\u7684\u6700\u5927\u4ef7\u503c\u5728\u4e8e<strong>\u6807\u51c6\u5316\u548c\u6613\u7528\u6027<\/strong> \u3002\u901a\u8fc7\u7edf\u4e00\u7684\u6307\u6807\u683c\u5f0f\uff0c\u53ef\u4ee5\u76f4\u63a5\u5bf9\u63a5 Prometheus\u3001Grafana \u8fd9\u4e9b\u6210\u719f\u7684\u76d1\u63a7\u5de5\u5177\uff0c\u4e0d\u7528\u81ea\u5df1\u9020\u8f6e\u5b50\u3002\u540c\u65f6\u901a\u8fc7\u5e94\u7528\u540d\u79f0\u548c\u7ebf\u7a0b\u6c60 ID \u4e24\u4e2a\u6807\u7b7e\u7ef4\u5ea6\uff0c\u65e2\u80fd\u770b\u6574\u4f53\u60c5\u51b5\uff0c\u4e5f\u80fd\u6df1\u5165\u5230\u5177\u4f53\u7ebf\u7a0b\u6c60\u7684\u7ec6\u8282\u3002<\/li>\n\n\n\n<li>\u5728\u6027\u80fd\u65b9\u9762\uff0c\u901a\u8fc7\u7f13\u5b58\u673a\u5236\u548c Micrometer \u81ea\u8eab\u7684\u4f18\u5316\u7279\u6027\uff0c\u786e\u4fdd\u76d1\u63a7\u672c\u8eab\u4e0d\u4f1a\u6210\u4e3a\u7cfb\u7edf\u8d1f\u62c5\u3002\u800c\u4e14\u6574\u4e2a\u8bbe\u8ba1\u9884\u7559\u4e86\u6269\u5c55\u7a7a\u95f4\uff0c\u540e\u7eed\u53ef\u4ee5\u6839\u636e\u9700\u8981\u6dfb\u52a0\u66f4\u591a\u6807\u7b7e\u7ef4\u5ea6\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u5b9e\u8df5\u5efa\u8bae<\/strong> \uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u751f\u4ea7\u73af\u5883\u5efa\u8bae\u4f18\u5148\u4f7f\u7528 Micrometer \u76d1\u63a7\uff0c\u914d\u5408 Prometheus + Grafana \u7684\u7ec4\u5408\uff0c\u8fd9\u662f\u76ee\u524d\u6700\u6210\u719f\u7684\u76d1\u63a7\u65b9\u6848\u3002\u5f00\u53d1\u73af\u5883\u53ef\u4ee5\u540c\u65f6\u5f00\u542f\u65e5\u5fd7\u76d1\u63a7\uff0c\u65b9\u4fbf\u672c\u5730\u8c03\u8bd5\u3002\u76d1\u63a7\u9891\u7387\u5efa\u8bae\u8bbe\u7f6e\u4e3a 10-30 \u79d2\uff0c\u65e2\u80fd\u53ca\u65f6\u53d1\u73b0\u95ee\u9898\uff0c\u53c8\u4e0d\u4f1a\u5bf9\u6027\u80fd\u9020\u6210\u660e\u663e\u5f71\u54cd\u3002<\/li>\n\n\n\n<li>\u901a\u8fc7 Micrometer \u76d1\u63a7\uff0coneThread \u6846\u67b6\u771f\u6b63\u5b9e\u73b0\u4e86\"\u53ef\u89c2\u6d4b\u6027\"\u7684\u76ee\u6807\u2014\u2014\u4e0d\u4ec5\u80fd\u770b\u5230\u7ebf\u7a0b\u6c60\u5728\u505a\u4ec0\u4e48\uff0c\u8fd8\u80fd\u5206\u6790\u5b83\u505a\u5f97\u600e\u4e48\u6837\uff0c\u4e3a\u751f\u4ea7\u73af\u5883\u7684\u7a33\u5b9a\u8fd0\u884c\u63d0\u4f9b\u4e86\u4fdd\u969c\u3002<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u867d\u7136\u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u62d2\u7edd\u7b56\u7565\u544a\u8b66\u3001\u7ebf\u7a0b\u6d3b\u8dc3\u5ea6\u544a\u8b66\u3001\u961f\u5217\u4f7f\u7528\u7387\u544a\u8b66 \u7b49\u673a\u5236\u53ca\u65f6\u53d1\u73b0\u90e8\u5206\u5f02\u5e38\uff0c\u4f46\u5982\u679c\u7f3a\u4e4f\u5bf9\u7ebf\u7a0b\u6c60\u8fd0\u884c\u72b6\u6001\u7684\u6301\u7eed\u89c2\u6d4b\u4e0e\u6570 &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[3],"tags":[19,20],"class_list":["post-1708","post","type-post","status-publish","format-standard","hentry","category-3","tag-java","tag-20"],"_links":{"self":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1708"}],"version-history":[{"count":24,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1708\/revisions"}],"predecessor-version":[{"id":1735,"href":"https:\/\/eve2333.top\/index.php?rest_route=\/wp\/v2\/posts\/1708\/revisions\/1735"}],"wp:attachment":[{"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eve2333.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}