在微服务架构中,为了应对突发流量,我们通常会引入 动态线程池(如 Hippo4j, DynamicTP 或自研框架),利用 Nacos 或 Apollo 等配置中心在不重启服务的情况下动态调整核心线程数和队列容量。

然而,单纯的“修改配置”存在一个监控盲区:

配置变更不可见:运维或开发人员在 Nacos 改了参数,其他人不知道。

缺乏留痕:什么时候改的?改了多少?没有实时的推送通知。

为了解决这个问题,本文将介绍如何接入 钉钉自定义机器人,在检测到 Nacos 配置变更时,发送一条格式精美、对比清晰的 Markdown 通知消息。

动态线程池实际的报警逻辑 需要依赖于钉钉机器人(也可以是企业微信这里只是一个思路)

下面给出我在开发线程池变更的时候是如何把消息推送到钉钉的
首先可以看钉钉机器人的文档

下面给我我在开发的时候的代码逻辑:
/**
* 消息变更通知模板(md格式)
*/
public static final String CHANGE_MESSAGE_TEXT = “”"
【通知】%s - 动态线程池配置调整

---

> 🛠 **基础信息** <br>
> <font color='#708090'>线程池ID:</font> **%s** <br>
> <font color='#708090'>应用实例:</font> %s

> 🧵 **核心参数** <br>
> <font color='#708090'>核心线程:</font> <font color='#FF0000'><b>%s</b></font> <br>
> <font color='#708090'>最大线程:</font> <font color='#FF0000'><b>%s</b></font> <br>
> <font color='#708090'>线程存活:</font> **%s** 秒

> 📥 **队列配置** <br>
> <font color='#708090'>队列类型:</font> %s <br>
> <font color='#708090'>队列容量:</font> <font color='#FF0000'><b>%s</b></font>

> 🚨 **拒绝策略变更** <br>
> <font color='#708090'>变更前:</font> <font color='#808080'><strike>%s</strike></font> <br>
> <font color='#708090'>变更后:</font> <font color='#2a9d8f'><b>%s</b></font>

---

<font color='#708090'>🕒 变更时间:</font>%s
""";

我们采用md文档的格式
在这里插入图片描述

 // 1. 准备高亮显示的变更字符串 (使用你定义的分隔符 "%s ➜ %s")
            String coreSizeChange = String.format(CHANGE_DELIMITER, originalProperties.getCorePoolSize(), remoteProperties.getCorePoolSize());
            String maxSizeChange = String.format(CHANGE_DELIMITER, originalProperties.getMaximumPoolSize(), remoteProperties.getMaximumPoolSize());
            String keepAliveChange = String.format(CHANGE_DELIMITER, originalProperties.getKeepAliveTime(), remoteProperties.getKeepAliveTime());
            String queueCapacityChange = String.format(CHANGE_DELIMITER, originalProperties.getQueueCapacity(), remoteProperties.getQueueCapacity());

            // 2. 获取当前时间
            String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            //todo
            // 3. 这里的 applicationName 需要你从 Spring Environment 或配置中获取
            String applicationName = "Unknown-Instance"; // 示例占位,建议注入 Environment 获取 spring.application.name + port

            // 4. 生成最终的 Markdown 消息内容
            String notificationContent = String.format(CHANGE_MESSAGE_TEXT,
                    // 标题中的 %s
                    threadPoolId,

                    // 基础信息
                    threadPoolId,        // 线程池ID
                    applicationName,     // 应用实例

                    // 核心参数 (填入 "旧值 ➜ 新值" 的字符串)
                    coreSizeChange,      // 核心线程
                    maxSizeChange,       // 最大线程
                    keepAliveChange,     // 线程存活

                    // 队列配置
                    remoteProperties.getWorkQueue(), // 队列类型 (通常不变更,直接取新值)
                    queueCapacityChange,             // 队列容量变更

                    // 拒绝策略变更 (模板里这部分有两个 %s,分别对应旧值和新值)
                    originalProperties.getRejectedHandler(), // 变更前
                    remoteProperties.getRejectedHandler(),   // 变更后

                    // 底部时间
                    currentTime
            );

            SendMessageService.sendChangeMessage(notificationContent);

        }

发送消息逻辑:

//动态线程池通知
    public static void sendChangeMessage(String info){
        Map<String, Object> md = new HashMap<>();
        md.put("title", "动态线程池通知");
        md.put("text", info);
        Map<String, Object> request = new HashMap<>();
        //指定md格式 接口文档https://open.dingtalk.com/document/development/custom-robots-send-group-messages
        request.put("msgtype", "markdown");
        request.put("markdown", md);

        try {
            String serverUrl = BootstrapConfigProperties.getInstance().getNotificationMessageConfiguration().getUrl();
            String responseBody = HttpUtil.post(serverUrl, JSON.toJSONString(request));
            Response response = JSON.parseObject(responseBody, Response.class);
            if (response.getErrcode() != 0) {
                log.error("发送失败: {}", response.errmsg);
            }
        } catch (Exception ex) {
            log.error("发送错误", ex);
        }

    }

效果如下
在这里插入图片描述
当我们修改nacos的配置的时候 提供自动检测系统

对具体代码有兴趣的可以关注我的GitHub开源地址
https://github.com/gaoxiaolei-s59/ElasticExecutor?tab=readme-ov-file

目前还在开发中

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐