From 598d6e248115de8dcfd54ddfdff4ee0354936382 Mon Sep 17 00:00:00 2001 From: zuojunlin Date: Mon, 20 Nov 2023 11:36:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:2.5.0=201=E3=80=81https://gitee.com/aizuda?= =?UTF-8?q?/easy-retry/issues/I8CKC8=202=E3=80=81=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=80=89=E6=9D=A1=E4=BB=B6=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E8=81=94=E5=8A=A8=203=E3=80=81=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E6=96=B0=E5=A2=9E=E4=BF=AE=E6=94=B9=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20=20=20.=E9=80=9A=E7=9F=A5=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E6=96=B0=E5=A2=9E=E4=BB=BB=E5=8A=A1=E9=87=8D=E8=AF=95?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E8=B6=85=E8=BF=87=E9=98=88=E5=80=BC=E3=80=81?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=A4=B1=E8=B4=A5=E8=BF=9B=E5=85=A5=E6=AD=BB?= =?UTF-8?q?=E4=BF=A1=E9=98=9F=E5=88=97=20=20=20.=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=99=90=E5=88=B6=E6=B5=81=E7=8A=B6=E6=80=81=E3=80=81=E6=AF=8F?= =?UTF-8?q?=E7=A7=92=E9=99=90=E6=B5=81=E9=98=88=E5=80=BC=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=20=20=20.=E9=92=89=E9=92=89=E5=92=8C=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=B1=9E=E6=80=A7=E6=96=B0=E5=A2=9E=E8=A2=AB?= =?UTF-8?q?@=E8=81=94=E7=B3=BB=E4=BA=BA=204=E3=80=81mysql=E3=80=81postgre?= =?UTF-8?q?=E5=BA=93=E7=9A=84=20notify=5Fconfig=E8=A1=A8=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=9C=BA=E6=99=AF=E5=90=8D=E7=A7=B0=E3=80=81=E9=99=90?= =?UTF-8?q?=E6=B5=81=E7=8A=B6=E6=80=81=E3=80=81=E6=AF=8F=E7=A7=92=E9=99=90?= =?UTF-8?q?=E6=B5=81=E9=98=88=E5=80=BC=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/sql/easy_retry_mysql.sql | 5 +- doc/sql/easy_retry_postgre.sql | 6 + .../datasource/access/ConfigAccess.java | 19 ++ .../access/config/AbstractConfigAccess.java | 20 ++ .../persistence/po/NotifyConfig.java | 7 +- .../persistence/po/SceneConfig.java | 5 + .../RetryErrorMoreThresholdAlarmSchedule.java | 62 +++--- .../RetryTaskMoreThresholdAlarmSchedule.java | 52 ++--- .../model/request/NotifyConfigRequestVO.java | 6 + .../response/NotifyConfigResponseVO.java | 6 + .../service/impl/NotifyConfigServiceImpl.java | 4 +- frontend/src/config/router.config.js | 2 +- frontend/src/utils/retryEnum.js | 22 ++- frontend/src/views/task/NotifyList.vue | 100 ++++++---- .../src/views/task/RetryDeadLetterList.vue | 8 +- frontend/src/views/task/RetryLogList.vue | 8 +- frontend/src/views/task/RetryTaskList.vue | 6 +- frontend/src/views/task/SceneList.vue | 37 +++- frontend/src/views/task/form/NotifyFrom.vue | 185 +++++++++++++----- frontend/src/views/task/form/SceneFrom.vue | 5 +- 20 files changed, 393 insertions(+), 172 deletions(-) diff --git a/doc/sql/easy_retry_mysql.sql b/doc/sql/easy_retry_mysql.sql index 77f63d63..2a90e929 100644 --- a/doc/sql/easy_retry_mysql.sql +++ b/doc/sql/easy_retry_mysql.sql @@ -26,11 +26,14 @@ CREATE TABLE `notify_config` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `group_name` varchar(64) NOT NULL COMMENT '组名称', - `notify_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '组状态 0、未启用 1、启用', + `scene_name` varchar(64) NOT NULL COMMENT '场景名称', + `notify_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '通知状态 0、未启用 1、启用', `notify_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '通知类型 1、钉钉 2、邮件 3、企业微信', `notify_attribute` varchar(512) NOT NULL COMMENT '配置属性', `notify_threshold` int(11) NOT NULL DEFAULT '0' COMMENT '通知阈值', `notify_scene` tinyint(4) NOT NULL DEFAULT '0' COMMENT '通知场景', + `rate_limiter_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '限流状态 0、未启用 1、启用', + `rate_limiter_threshold` int(11) NOT NULL DEFAULT '0' COMMENT '每秒限流阈值', `description` varchar(256) NOT NULL DEFAULT '' COMMENT '描述', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', diff --git a/doc/sql/easy_retry_postgre.sql b/doc/sql/easy_retry_postgre.sql index 32c4854d..43d3475b 100644 --- a/doc/sql/easy_retry_postgre.sql +++ b/doc/sql/easy_retry_postgre.sql @@ -34,11 +34,14 @@ CREATE TABLE notify_config ( id BIGSERIAL PRIMARY KEY, group_name VARCHAR(64) NOT NULL, + scene_name VARCHAR(64) NOT NULL, notify_status SMALLINT NOT NULL DEFAULT 0, notify_type SMALLINT NOT NULL DEFAULT 0, notify_attribute VARCHAR(512) NOT NULL, notify_threshold INT NOT NULL DEFAULT 0, notify_scene SMALLINT NOT NULL DEFAULT 0, + rate_limiter_status SMALLINT NOT NULL DEFAULT 0, + rate_limiter_threshold INT NOT NULL DEFAULT 0, description VARCHAR(256) NOT NULL DEFAULT '', create_dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, update_dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP @@ -48,11 +51,14 @@ CREATE INDEX idx_group_name ON notify_config (group_name); COMMENT ON COLUMN "notify_config"."id" IS '主键'; COMMENT ON COLUMN "notify_config"."group_name" IS '组名称'; +COMMENT ON COLUMN "notify_config"."scene_name" IS '场景名称'; COMMENT ON COLUMN "notify_config"."notify_status" IS '通知状态 0、未启用 1、启用'; COMMENT ON COLUMN "notify_config"."notify_type" IS '通知类型 1、钉钉 2、邮件 3、企业微信'; COMMENT ON COLUMN "notify_config"."notify_attribute" IS '配置属性'; COMMENT ON COLUMN "notify_config"."notify_threshold" IS '通知阈值'; COMMENT ON COLUMN "notify_config"."notify_scene" IS '通知场景'; +COMMENT ON COLUMN "notify_config"."rate_limiter_status" IS '限流状态 0、未启用 1、启用'; +COMMENT ON COLUMN "notify_config"."rate_limiter_threshold" IS '每秒限流阈值'; COMMENT ON COLUMN "notify_config"."description" IS '描述'; COMMENT ON COLUMN "notify_config"."create_dt" IS '创建时间'; COMMENT ON COLUMN "notify_config"."update_dt" IS '修改时间'; diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/ConfigAccess.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/ConfigAccess.java index d8bc0931..d3f1556f 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/ConfigAccess.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/ConfigAccess.java @@ -52,6 +52,17 @@ public interface ConfigAccess extends Access { */ List getNotifyConfigByGroupName(String groupName, Integer notifyScene); + + /** + * 获取通知配置 + * + * @param groupName 组名称 + * @param groupName 场景名称 + * @param notifyScene {@link NotifySceneEnum} 场景类型 + * @return {@link NotifyConfig} 场景配置 + */ + List getNotifyConfigByGroupNameAndSceneName(String groupName,String sceneName, Integer notifyScene); + /** * 获取通知配置 * @@ -88,6 +99,14 @@ public interface ConfigAccess extends Access { */ List getAllConfigGroupList(); + + /** + * 获取所有场景配置信息 + * + * @return 场景配置列表 + */ + List getAllConfigSceneList(); + /** * 获取配置版本号 * diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/config/AbstractConfigAccess.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/config/AbstractConfigAccess.java index 02d3b091..01769876 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/config/AbstractConfigAccess.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/access/config/AbstractConfigAccess.java @@ -50,6 +50,12 @@ public abstract class AbstractConfigAccess implements ConfigAccess { .eq(NotifyConfig::getNotifyScene, notifyScene)); } + private List getByGroupIdAndSceneIdAndNotifyScene(String groupName, String sceneName, Integer notifyScene) { + return notifyConfigMapper.selectList(new LambdaQueryWrapper().eq(NotifyConfig::getGroupName, groupName) + .eq(NotifyConfig::getSceneName, sceneName) + .eq(NotifyConfig::getNotifyScene, notifyScene)); + } + protected SceneConfig getByGroupNameAndSceneName(String groupName, String sceneName) { return sceneConfigMapper.selectOne(new LambdaQueryWrapper() .eq(SceneConfig::getGroupName, groupName).eq(SceneConfig::getSceneName, sceneName)); @@ -89,6 +95,11 @@ public abstract class AbstractConfigAccess implements ConfigAccess { return getByGroupIdAndNotifyScene(shardingGroupId, notifyScene); } + @Override + public List getNotifyConfigByGroupNameAndSceneName(String shardingGroupId,String shardingSceneId, Integer notifyScene) { + return getByGroupIdAndSceneIdAndNotifyScene(shardingGroupId,shardingSceneId, notifyScene); + } + @Override public List getNotifyListConfigByGroupName(String shardingGroupId) { return getNotifyConfigs(shardingGroupId); @@ -138,6 +149,15 @@ public abstract class AbstractConfigAccess implements ConfigAccess { return allSystemConfigGroupList; } + @Override + public List getAllConfigSceneList() { + List allSystemConfigSceneList = sceneConfigMapper.selectList(new LambdaQueryWrapper().orderByAsc(SceneConfig::getId)); + if (CollectionUtils.isEmpty(allSystemConfigSceneList)) { + return Collections.EMPTY_LIST; + } + return allSystemConfigSceneList; + } + @Override public Integer getConfigVersion(String groupName) { GroupConfig groupConfig = getGroupConfigByGroupName(groupName); diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/NotifyConfig.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/NotifyConfig.java index 350ad9f2..f15765f9 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/NotifyConfig.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/NotifyConfig.java @@ -3,7 +3,6 @@ package com.aizuda.easy.retry.template.datasource.persistence.po; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; - import java.io.Serializable; import java.time.LocalDateTime; @@ -15,6 +14,8 @@ public class NotifyConfig implements Serializable { private String groupName; + private String sceneName; + private Integer notifyStatus; private Integer notifyType; @@ -25,6 +26,10 @@ public class NotifyConfig implements Serializable { private Integer notifyScene; + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + private String description; private LocalDateTime createDt; diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/SceneConfig.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/SceneConfig.java index 70394ec6..0d33c6a9 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/SceneConfig.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/SceneConfig.java @@ -7,6 +7,11 @@ import lombok.Data; import java.io.Serializable; import java.time.LocalDateTime; +/** + * @author zuojunlin + * @date 2023-11-19 22:05:25 + * @since 2.5.0 + */ @Data public class SceneConfig implements Serializable { diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryErrorMoreThresholdAlarmSchedule.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryErrorMoreThresholdAlarmSchedule.java index dae12cd6..dc4ffa76 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryErrorMoreThresholdAlarmSchedule.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryErrorMoreThresholdAlarmSchedule.java @@ -12,15 +12,14 @@ import com.aizuda.easy.retry.server.common.schedule.AbstractSchedule; import com.aizuda.easy.retry.server.common.util.DateUtils; import com.aizuda.easy.retry.template.datasource.access.AccessTemplate; import com.aizuda.easy.retry.template.datasource.access.TaskAccess; -import com.aizuda.easy.retry.template.datasource.persistence.po.GroupConfig; import com.aizuda.easy.retry.template.datasource.persistence.po.NotifyConfig; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryDeadLetter; +import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; - import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; @@ -38,7 +37,8 @@ import java.util.List; public class RetryErrorMoreThresholdAlarmSchedule extends AbstractSchedule implements Lifecycle { private static String retryErrorMoreThresholdTextMessageFormatter = "{}环境 重试失败数据监控 \n" + - "> 名称:{} \n" + + "> 组名称:{} \n" + + "> 场景名称:{} \n" + "> 时间窗口:{} ~ {} \n" + "> **共计:{}** \n"; @@ -60,37 +60,35 @@ public class RetryErrorMoreThresholdAlarmSchedule extends AbstractSchedule imple @Override protected void doExecute() { LogUtils.info(log, "retryErrorMoreThreshold time[{}] ip:[{}]", LocalDateTime.now(), HostUtils.getIp()); - - for (GroupConfig groupConfig : accessTemplate.getGroupConfigAccess().getAllConfigGroupList()) { - List notifyConfigs = accessTemplate.getNotifyConfigAccess().getNotifyConfigByGroupName(groupConfig.getGroupName(), NotifySceneEnum.MAX_RETRY_ERROR.getNotifyScene()); - if (CollectionUtils.isEmpty(notifyConfigs)) { - continue; - } - - // x分钟内进入死信队列的数据量 - LocalDateTime now = LocalDateTime.now(); - TaskAccess retryDeadLetterAccess = accessTemplate.getRetryDeadLetterAccess(); - - long count = retryDeadLetterAccess.count(groupConfig.getGroupName(), new LambdaQueryWrapper() - .between(RetryDeadLetter::getCreateDt, now.minusMinutes(30), now)); - for (NotifyConfig notifyConfig : notifyConfigs) { - if (count > notifyConfig.getNotifyThreshold()) { - // 预警 - AlarmContext context = AlarmContext.build() - .text(retryErrorMoreThresholdTextMessageFormatter, - EnvironmentUtils.getActiveProfile(), - groupConfig.getGroupName(), - DateUtils.format(now.minusMinutes(30), DateUtils.NORM_DATETIME_PATTERN), - DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), - count) - .title("组:[{}] 环境重试失败数据监控", groupConfig.getGroupName()) - .notifyAttribute(notifyConfig.getNotifyAttribute()); - - Alarm alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); - alarmType.asyncSendMessage(context); + for (SceneConfig sceneConfig : accessTemplate.getSceneConfigAccess().getAllConfigSceneList()) { + List notifyConfigs = accessTemplate.getNotifyConfigAccess().getNotifyConfigByGroupNameAndSceneName(sceneConfig.getGroupName(),sceneConfig.getSceneName(), NotifySceneEnum.MAX_RETRY_ERROR.getNotifyScene()); + if (CollectionUtils.isEmpty(notifyConfigs)) { + continue; + } + // x分钟内、x组、x场景进入死信队列的数据量 + LocalDateTime now = LocalDateTime.now(); + TaskAccess retryDeadLetterAccess = accessTemplate.getRetryDeadLetterAccess(); + long count = retryDeadLetterAccess.count(sceneConfig.getGroupName(), new LambdaQueryWrapper(). + between(RetryDeadLetter::getCreateDt, now.minusMinutes(30), now) + .eq(RetryDeadLetter::getGroupName,sceneConfig.getGroupName()) + .eq(RetryDeadLetter::getSceneName,sceneConfig.getSceneName())); + for (NotifyConfig notifyConfig : notifyConfigs) { + if (count > notifyConfig.getNotifyThreshold()) { + // 预警 + AlarmContext context = AlarmContext.build().text(retryErrorMoreThresholdTextMessageFormatter, + EnvironmentUtils.getActiveProfile(), + sceneConfig.getGroupName(), + sceneConfig.getSceneName(), + DateUtils.format(now.minusMinutes(30), + DateUtils.NORM_DATETIME_PATTERN), + DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), count) + .title("组:[{}] 场景:[{}] 环境重试失败数据监控", sceneConfig.getGroupName(),sceneConfig.getSceneName()) + .notifyAttribute(notifyConfig.getNotifyAttribute()); + Alarm alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); + alarmType.asyncSendMessage(context); + } } } - } } @Override diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryTaskMoreThresholdAlarmSchedule.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryTaskMoreThresholdAlarmSchedule.java index 308356d8..821ae917 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryTaskMoreThresholdAlarmSchedule.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/schedule/RetryTaskMoreThresholdAlarmSchedule.java @@ -12,9 +12,9 @@ import com.aizuda.easy.retry.server.common.Lifecycle; import com.aizuda.easy.retry.server.common.schedule.AbstractSchedule; import com.aizuda.easy.retry.server.common.util.DateUtils; import com.aizuda.easy.retry.template.datasource.access.AccessTemplate; -import com.aizuda.easy.retry.template.datasource.persistence.po.GroupConfig; import com.aizuda.easy.retry.template.datasource.persistence.po.NotifyConfig; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask; +import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -40,6 +40,7 @@ public class RetryTaskMoreThresholdAlarmSchedule extends AbstractSchedule implem private static String retryTaskMoreThresholdTextMessageFormatter = "{}环境 重试数据监控 \n" + "> 组名称:{} \n" + + "> 场景名称:{} \n" + "> 告警时间:{} \n" + "> **共计:{}** \n"; @@ -59,34 +60,33 @@ public class RetryTaskMoreThresholdAlarmSchedule extends AbstractSchedule implem @Override protected void doExecute() { LogUtils.info(log, "retryTaskMoreThreshold time[{}] ip:[{}]", LocalDateTime.now(), HostUtils.getIp()); - - for (GroupConfig groupConfig : accessTemplate.getGroupConfigAccess().getAllConfigGroupList()) { - List notifyConfigs = accessTemplate.getNotifyConfigAccess().getNotifyConfigByGroupName(groupConfig.getGroupName(), NotifySceneEnum.MAX_RETRY.getNotifyScene()); - if (CollectionUtils.isEmpty(notifyConfigs)) { - continue; - } - - long count = accessTemplate.getRetryTaskAccess().count(groupConfig.getGroupName(), new LambdaQueryWrapper() - .eq(RetryTask::getGroupName, groupConfig.getGroupName()) - .eq(RetryTask::getRetryStatus, RetryStatusEnum.RUNNING.getStatus())); - for (NotifyConfig notifyConfig : notifyConfigs) { - if (count > notifyConfig.getNotifyThreshold()) { - // 预警 - AlarmContext context = AlarmContext.build() - .text(retryTaskMoreThresholdTextMessageFormatter, - EnvironmentUtils.getActiveProfile(), - groupConfig.getGroupName(), - DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), - count) - .title("组:[{}])重试数据过多", groupConfig.getGroupName()) - .notifyAttribute(notifyConfig.getNotifyAttribute()); - - Alarm alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); - alarmType.asyncSendMessage(context); + for (SceneConfig sceneConfig : accessTemplate.getSceneConfigAccess().getAllConfigSceneList()) { + List notifyConfigs = accessTemplate.getNotifyConfigAccess().getNotifyConfigByGroupNameAndSceneName(sceneConfig.getGroupName(),sceneConfig.getSceneName(), NotifySceneEnum.MAX_RETRY.getNotifyScene()); + if (CollectionUtils.isEmpty(notifyConfigs)) { + continue; + } + long count = accessTemplate.getRetryTaskAccess().count(sceneConfig.getGroupName(), new LambdaQueryWrapper() + .eq(RetryTask::getGroupName, sceneConfig.getGroupName()) + .eq(RetryTask::getSceneName,sceneConfig.getSceneName()) + .eq(RetryTask::getRetryStatus, RetryStatusEnum.RUNNING.getStatus())); + for (NotifyConfig notifyConfig : notifyConfigs) { + if (count > notifyConfig.getNotifyThreshold()) { + // 预警 + AlarmContext context = AlarmContext.build() + .text(retryTaskMoreThresholdTextMessageFormatter, + EnvironmentUtils.getActiveProfile(), + sceneConfig.getGroupName(), + sceneConfig.getSceneName(), + DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), + count) + .title("组:[{}] 场景:[{}] 重试数据过多", sceneConfig.getGroupName(),sceneConfig.getSceneName()) + .notifyAttribute(notifyConfig.getNotifyAttribute()); + Alarm alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); + alarmType.asyncSendMessage(context); + } } } } - } @Override public String lockName() { diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/NotifyConfigRequestVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/NotifyConfigRequestVO.java index aa36aa63..b6518cd6 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/NotifyConfigRequestVO.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/request/NotifyConfigRequestVO.java @@ -20,6 +20,8 @@ public class NotifyConfigRequestVO { @Pattern(regexp = "^[A-Za-z0-9_]{1,64}$", message = "仅支持长度为1~64字符且类型为数字、字母和下划线") private String groupName; + private String sceneName; + @NotNull(message = "通知状态不能为空") private Integer notifyStatus; @@ -34,6 +36,10 @@ public class NotifyConfigRequestVO { @NotNull(message = "通知场景不能为空") private Integer notifyScene; + @NotNull(message = "限流状态不能为空") + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; /** * 描述 */ diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/NotifyConfigResponseVO.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/NotifyConfigResponseVO.java index cffaf807..3ad91d5e 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/NotifyConfigResponseVO.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/model/response/NotifyConfigResponseVO.java @@ -12,6 +12,8 @@ public class NotifyConfigResponseVO implements Serializable { private String groupName; + private String sceneName; + private Integer notifyStatus; private String notifyName; @@ -24,6 +26,10 @@ public class NotifyConfigResponseVO implements Serializable { private Integer notifyScene; + private Integer rateLimiterStatus; + + private Integer rateLimiterThreshold; + private String description; private LocalDateTime createDt; diff --git a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NotifyConfigServiceImpl.java b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NotifyConfigServiceImpl.java index 52879f09..4c2d32f7 100644 --- a/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NotifyConfigServiceImpl.java +++ b/easy-retry-server/easy-retry-server-web/src/main/java/com/aizuda/easy/retry/server/web/service/impl/NotifyConfigServiceImpl.java @@ -40,7 +40,9 @@ public class NotifyConfigServiceImpl implements NotifyConfigService { if (StrUtil.isNotBlank(queryVO.getGroupName())) { queryWrapper.eq(NotifyConfig::getGroupName, queryVO.getGroupName()); } - + if (StrUtil.isNotBlank(queryVO.getSceneName())) { + queryWrapper.eq(NotifyConfig::getSceneName, queryVO.getSceneName()); + } List notifyConfigs = accessTemplate.getNotifyConfigAccess().listPage(pageDTO, queryWrapper).getRecords(); return new PageResult<>(pageDTO, NotifyConfigResponseVOConverter.INSTANCE.batchConvert(notifyConfigs)); } diff --git a/frontend/src/config/router.config.js b/frontend/src/config/router.config.js index 60588f8f..dd82adea 100644 --- a/frontend/src/config/router.config.js +++ b/frontend/src/config/router.config.js @@ -114,7 +114,7 @@ export const asyncRouterMap = [ path: '/retry/notify/list', name: 'NotifyList', component: () => import('@/views/task/NotifyList'), - meta: { title: '通知配置', icon: 'profile', keepAlive: true, permission: ['retryTask'] } + meta: { title: '通知列表', icon: 'profile', keepAlive: true, permission: ['retryTask'] } }, { path: '/retry/notify/config', diff --git a/frontend/src/utils/retryEnum.js b/frontend/src/utils/retryEnum.js index acfdb345..e6f22c84 100644 --- a/frontend/src/utils/retryEnum.js +++ b/frontend/src/utils/retryEnum.js @@ -39,11 +39,11 @@ const enums = { }, notifyScene: { '1': { - 'name': '重试数量超过阈值', + 'name': '场景重试数量超过阈值', 'color': '#d06892' }, '2': { - 'name': '重试失败数量超过阈值', + 'name': '场景重试失败数量超过阈值', 'color': '#f5a22d' }, '3': { @@ -53,6 +53,14 @@ const enums = { '4': { 'name': '客户端组件异常', 'color': '#a127f3' + }, + '5': { + 'name': '任务重试数量超过阈值', + 'color': '#f5a22d' + }, + '6': { + 'name': '任务失败进入死信队列', + 'color': '#f5a22d' } }, routeKey: { @@ -87,6 +95,16 @@ const enums = { 'color': '#087da1' } }, + rateLimiterStatus: { + '0': { + 'name': '未启用', + 'color': '#9c1f1f' + }, + '1': { + 'name': '启用', + 'color': '#f5a22d' + } + }, notifyStatus: { '0': { 'name': '停用', diff --git a/frontend/src/views/task/NotifyList.vue b/frontend/src/views/task/NotifyList.vue index bf5755bf..e92bd026 100644 --- a/frontend/src/views/task/NotifyList.vue +++ b/frontend/src/views/task/NotifyList.vue @@ -7,19 +7,23 @@ - 查询 - 重置 + 查询 + 重置 @@ -45,13 +49,18 @@ :rowSelection="options.rowSelection" > - - {{ notifyType[text].name }} + + {{ notifyTypeList[text].name }} + + + + + {{ notifyStatusList[text].name }} - - {{ notifyScene[text].name }} + + {{ notifySceneList[text].name }} @@ -72,7 +81,7 @@