Explorar el Código

1.添加mq监控端模块

lsl hace 2 años
padre
commit
d355ebffff

+ 119 - 0
mq-monitor/pom.xml

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>cn.com.moonspeak.rabbitmq.monitor</groupId>
+    <artifactId>mq-monitor</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <build>
+        <finalName>app</finalName>
+        <resources>
+            <!-- 配置文件复制到target目录下,不然开发调试的时候会报错 -->
+            <resource>
+                <!-- 资源文件的路径,不配置的话默认位于src/main/resources/目录下,  -->
+                <directory>src/main/resources</directory>
+                <!-- 是否对资源文件进行过滤 -->
+                <filtering>true</filtering>
+                <!-- 这里没有配置targetPath,默认复制到outputDirectory目录下  -->
+            </resource>
+            <!-- 配置文件放在target/config目录下 -->
+            <resource>
+                <directory>src/main/resources</directory>
+                <targetPath>${project.build.directory}/config</targetPath>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>cn.com.moonspeak.rabbitmq.monitor.Application</mainClass>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>lib/</classpathPrefix>
+                            <useUniqueVersions>false</useUniqueVersions>
+                        </manifest>
+                        <!-- 配置文件外置,需要把配置文件目录加入到classpath -->
+                        <manifestEntries>
+                            <Class-Path>config/</Class-Path>
+                        </manifestEntries>
+                    </archive>
+                    <includes>
+                        <include>**</include>
+                    </includes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>2.10</version>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 解决资源文件的编码问题 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.11.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.0</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 124 - 0
mq-monitor/src/main/java/cn/com/moonspeak/rabbitmq/monitor/Application.java

@@ -0,0 +1,124 @@
+package cn.com.moonspeak.rabbitmq.monitor;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.resource.Resource;
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.mail.MailAccount;
+import cn.hutool.extra.mail.MailUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.setting.Setting;
+import lombok.SneakyThrows;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * mq堆积监控
+ *
+ * start.sh {host} {userName} {passWord} {mail}
+ *
+ * @author lisl
+ * @version 1.0 - 2023/2/28
+ * @class: MqQuery
+ * @date 2023/2/28
+ * @see
+ */
+public class Application {
+
+    private static String baseUrl;
+    private static String userName;
+    private static String passWord;
+    private static List<String> mails=new ArrayList<>();
+    private static Integer thresholdCount;
+
+    @SneakyThrows
+    public static void main(String[] args) {
+//      初始化全局配置(具备自动更新能力)
+        Setting setting = createDefaultSetting();
+        baseUrl = setting.getStr("baseUrl", "http://120.26.55.29:15672/api");
+        userName = setting.getStr("userName", "admin");
+        passWord = setting.getStr("passWord", "admin");
+        String mailArg = setting.getStr("baseUrl", "791120662@qq.com");
+        if (StrUtil.isNotBlank(mailArg)) {
+            List<String> strings = StrUtil.splitTrim(mailArg, ",");
+            if (CollUtil.isNotEmpty(strings)) {
+                mails.addAll(strings);
+            }
+        }
+        thresholdCount = Convert.toInt(setting.getStr("thresholdCount", "10"));
+//      接口文档:http://120.26.55.29:15672/api/index.html#pagination
+//      /queues 查询全部队列
+//      /api/queues/(vhost)/(name)
+        while (true) {
+            String request = request("/queues?page=1&page_size=100&name=1_rates&use_regex=false&pagination=true");
+            if (StrUtil.isBlank(request)) {
+                sendMail("接口队列响应为空!可能出现异常,请检查!");
+                return;
+            }
+            MqQueueItemPageInfo result = JSONUtil.toBean(request, MqQueueItemPageInfo.class);
+            MqQueueItemPageInfo.ItemsDTO itemsDTO = result.getItems().get(0);
+            Integer itemCount = (itemsDTO.getMessagesReady() + itemsDTO.getMessagesUnacknowledged());
+            System.out.println(StrUtil.format("{} {} {}",
+                    itemsDTO.getMessagesReady(), itemsDTO.getMessagesUnacknowledged(),
+                    itemCount
+            ));
+            if (itemCount > thresholdCount) {
+                sendMail(StrUtil.format("接口队列处理堆积过大,目前为{},请处理!", itemCount));
+            }
+            ThreadUtil.safeSleep(3000);
+        }
+    }
+
+    public static final String[] GLOBAL_SETTING_PATHS = new String[]{"config/mq.setting","file:mq.setting","file:/config/mq.setting", "mq.setting"};
+
+    public static  Setting createDefaultSetting() {
+        for (String settingPath : GLOBAL_SETTING_PATHS) {
+            try {
+                Setting setting = new Setting(settingPath);
+                //在配置文件变更时自动加载
+                setting.autoLoad(true);
+                return setting;
+            } catch (Exception ignore) {
+                //ignore
+//                ignore.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 邮件批量发送
+     *
+     * @param content 邮件内容
+     */
+    public static void sendMail(String content) {
+        MailUtil.send(mails, "酒店预警邮件", content, false, null);
+    }
+
+    /**
+     * 发送请求
+     *
+     * @param url
+     * @return
+     */
+    public static String request(String url) {
+        String json = null;
+        try {
+            HttpRequest httpRequest = HttpRequest.get(baseUrl + url);
+            httpRequest.basicAuth(userName, passWord);
+            HttpResponse response = httpRequest.execute();
+            json = response.body();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return json;
+    }
+
+}

+ 291 - 0
mq-monitor/src/main/java/cn/com/moonspeak/rabbitmq/monitor/MqQueueItemPageInfo.java

@@ -0,0 +1,291 @@
+package cn.com.moonspeak.rabbitmq.monitor;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 队列明细
+ * @see https://www.rabbitmq.com/rabbitmqctl.8.html
+ * @author lisl
+ * @version 1.0 - 2023/3/1
+ * @class: MqQueueItemInfo
+ * @date 2023/3/1
+ * @see
+ */
+@NoArgsConstructor
+@Data
+public class MqQueueItemPageInfo {
+
+    @JsonProperty("filtered_count")
+    private Integer filteredCount;
+    @JsonProperty("item_count")
+    private Integer itemCount;
+    @JsonProperty("items")
+    private List<ItemsDTO> items;
+    @JsonProperty("page")
+    private Integer page;
+    @JsonProperty("page_count")
+    private Integer pageCount;
+    @JsonProperty("page_size")
+    private Integer pageSize;
+    @JsonProperty("total_count")
+    private Integer totalCount;
+
+    @NoArgsConstructor
+    @Data
+    public static class ItemsDTO {
+        @JsonProperty("arguments")
+        private ArgumentsDTO arguments;
+        @JsonProperty("auto_delete")
+        private Boolean autoDelete;
+        @JsonProperty("backing_queue_status")
+        private BackingQueueStatusDTO backingQueueStatus;
+        @JsonProperty("consumer_capacity")
+        private Integer consumerCapacity;
+        @JsonProperty("consumer_utilisation")
+        private Integer consumerUtilisation;
+        @JsonProperty("consumers")
+        private Integer consumers;
+        @JsonProperty("durable")
+        private Boolean durable;
+        @JsonProperty("effective_policy_definition")
+        private EffectivePolicyDefinitionDTO effectivePolicyDefinition;
+        @JsonProperty("exclusive")
+        private Boolean exclusive;
+        @JsonProperty("exclusive_consumer_tag")
+        private Object exclusiveConsumerTag;
+        @JsonProperty("garbage_collection")
+        private GarbageCollectionDTO garbageCollection;
+        @JsonProperty("head_message_timestamp")
+        private Object headMessageTimestamp;
+        @JsonProperty("memory")
+        private Integer memory;
+        @JsonProperty("message_bytes")
+        private Integer messageBytes;
+        @JsonProperty("message_bytes_paged_out")
+        private Integer messageBytesPagedOut;
+        @JsonProperty("message_bytes_persistent")
+        private Integer messageBytesPersistent;
+        @JsonProperty("message_bytes_ram")
+        private Integer messageBytesRam;
+        @JsonProperty("message_bytes_ready")
+        private Integer messageBytesReady;
+        @JsonProperty("message_bytes_unacknowledged")
+        private Integer messageBytesUnacknowledged;
+        @JsonProperty("message_stats")
+        private MessageStatsDTO messageStats;
+        @JsonProperty("messages")
+        private Integer messages;
+        @JsonProperty("messages_details")
+        private MessagesDetailsDTO messagesDetails;
+        @JsonProperty("messages_paged_out")
+        private Integer messagesPagedOut;
+        @JsonProperty("messages_persistent")
+        private Integer messagesPersistent;
+        @JsonProperty("messages_ram")
+        private Integer messagesRam;
+        @JsonProperty("messages_ready")
+        private Integer messagesReady;
+        @JsonProperty("messages_ready_details")
+        private MessagesReadyDetailsDTO messagesReadyDetails;
+        @JsonProperty("messages_ready_ram")
+        private Integer messagesReadyRam;
+        @JsonProperty("messages_unacknowledged")
+        private Integer messagesUnacknowledged;
+        @JsonProperty("messages_unacknowledged_details")
+        private MessagesUnacknowledgedDetailsDTO messagesUnacknowledgedDetails;
+        @JsonProperty("messages_unacknowledged_ram")
+        private Integer messagesUnacknowledgedRam;
+        @JsonProperty("name")
+        private String name;
+        @JsonProperty("node")
+        private String node;
+        @JsonProperty("operator_policy")
+        private Object operatorPolicy;
+        @JsonProperty("policy")
+        private Object policy;
+        @JsonProperty("recoverable_slaves")
+        private Object recoverableSlaves;
+        @JsonProperty("reductions")
+        private Long reductions;
+        @JsonProperty("reductions_details")
+        private ReductionsDetailsDTO reductionsDetails;
+        @JsonProperty("single_active_consumer_tag")
+        private Object singleActiveConsumerTag;
+        @JsonProperty("state")
+        private String state;
+        @JsonProperty("type")
+        private String type;
+        @JsonProperty("vhost")
+        private String vhost;
+        @JsonProperty("idle_since")
+        private String idleSince;
+
+        @NoArgsConstructor
+        @Data
+        public static class ArgumentsDTO {
+            @JsonProperty("x-queue-type")
+            private String xqueuetype;
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class BackingQueueStatusDTO {
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class EffectivePolicyDefinitionDTO {
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class GarbageCollectionDTO {
+            @JsonProperty("fullsweep_after")
+            private Integer fullsweepAfter;
+            @JsonProperty("max_heap_size")
+            private Integer maxHeapSize;
+            @JsonProperty("min_bin_vheap_size")
+            private Integer minBinVheapSize;
+            @JsonProperty("min_heap_size")
+            private Integer minHeapSize;
+            @JsonProperty("minor_gcs")
+            private Integer minorGcs;
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class MessageStatsDTO {
+            @JsonProperty("ack")
+            private Integer ack;
+            @JsonProperty("ack_details")
+            private AckDetailsDTO ackDetails;
+            @JsonProperty("deliver")
+            private Integer deliver;
+            @JsonProperty("deliver_details")
+            private DeliverDetailsDTO deliverDetails;
+            @JsonProperty("deliver_get")
+            private Integer deliverGet;
+            @JsonProperty("deliver_get_details")
+            private DeliverGetDetailsDTO deliverGetDetails;
+            @JsonProperty("deliver_no_ack")
+            private Integer deliverNoAck;
+            @JsonProperty("deliver_no_ack_details")
+            private DeliverNoAckDetailsDTO deliverNoAckDetails;
+            @JsonProperty("get")
+            private Integer get;
+            @JsonProperty("get_details")
+            private GetDetailsDTO getDetails;
+            @JsonProperty("get_empty")
+            private Integer getEmpty;
+            @JsonProperty("get_empty_details")
+            private GetEmptyDetailsDTO getEmptyDetails;
+            @JsonProperty("get_no_ack")
+            private Integer getNoAck;
+            @JsonProperty("get_no_ack_details")
+            private GetNoAckDetailsDTO getNoAckDetails;
+            @JsonProperty("publish")
+            private Integer publish;
+            @JsonProperty("publish_details")
+            private PublishDetailsDTO publishDetails;
+            @JsonProperty("redeliver")
+            private Integer redeliver;
+            @JsonProperty("redeliver_details")
+            private RedeliverDetailsDTO redeliverDetails;
+
+            @NoArgsConstructor
+            @Data
+            public static class AckDetailsDTO {
+                @JsonProperty("rate")
+                private Double rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class DeliverDetailsDTO {
+                @JsonProperty("rate")
+                private Double rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class DeliverGetDetailsDTO {
+                @JsonProperty("rate")
+                private Double rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class DeliverNoAckDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class GetDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class GetEmptyDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class GetNoAckDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class PublishDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+
+            @NoArgsConstructor
+            @Data
+            public static class RedeliverDetailsDTO {
+                @JsonProperty("rate")
+                private Integer rate;
+            }
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class MessagesDetailsDTO {
+            @JsonProperty("rate")
+            private Integer rate;
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class MessagesReadyDetailsDTO {
+            @JsonProperty("rate")
+            private Integer rate;
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class MessagesUnacknowledgedDetailsDTO {
+            @JsonProperty("rate")
+            private Integer rate;
+        }
+
+        @NoArgsConstructor
+        @Data
+        public static class ReductionsDetailsDTO {
+            @JsonProperty("rate")
+            private Integer rate;
+        }
+    }
+}

+ 26 - 0
mq-monitor/src/main/resources/mail.setting

@@ -0,0 +1,26 @@
+# 邮件服务器的SMTP地址
+host = smtp.qq.com
+# 邮件服务器的SMTP端口
+port = 465
+# 发件人(必须正确,否则发送失败)
+from = 791120662@qq.com
+# 用户名(注意:如果使用foxmail邮箱,此处user为qq号)
+user = 791120662@qq.com
+# 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助)
+pass = ifhstopkjapgbdeh
+# 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。
+starttlsEnable = true
+
+# 使用SSL安全连接
+sslEnable = true
+# 指定实现javax.net.SocketFactory接口的类的名称,这个类将被用于创建SMTP的套接字
+socketFactoryClass = javax.net.ssl.SSLSocketFactory
+# 如果设置为true,未能创建一个套接字使用指定的套接字工厂类将导致使用java.net.Socket创建的套接字类, 默认值为true
+socketFactoryFallback = true
+# 指定的端口连接到在使用指定的套接字工厂。如果没有设置,将使用默认端口456
+socketFactoryPort = 465
+
+# SMTP超时时长,单位毫秒,缺省值不超时
+timeout = 0
+# Socket连接超时值,单位毫秒,缺省值不超时
+connectionTimeout = 0

+ 10 - 0
mq-monitor/src/main/resources/mq.setting

@@ -0,0 +1,10 @@
+# mq接口地址
+baseUrl = http://120.26.55.29:15672/api
+# 用户名
+userName = admin
+# 密码
+passWord = admin
+# 接收邮件地址,多个逗号分割
+mails = 791120662@qq.com
+# 消息阈值,超过这个数会预警提示
+thresholdCount = 50

+ 1 - 0
mq-monitor/start.bat

@@ -0,0 +1 @@
+java -jar target/app.jar

+ 2 - 1
pom.xml

@@ -15,6 +15,7 @@
         <module>common</module>
         <module>gateway</module>
         <module>web-manager</module>
+        <module>mq-monitor</module>
     </modules>
 
     <!--统一管理jar包版本-->
@@ -169,4 +170,4 @@
             </plugins>
         </pluginManagement>
     </build>
-</project>
+</project>