feature: 开发线程池报警频率限制, 默认推送间隔五分钟(可通过配置修改).

pull/161/head
chen.ma 3 years ago
parent 3f8df895e0
commit 3ed2b32074

@ -0,0 +1,35 @@
package com.github.dynamic.threadpool.starter.alarm;
import lombok.Builder;
import lombok.Data;
/**
* .
*
* @author chen.ma
* @date 2021/10/28 22:15
*/
@Data
@Builder
public class AlarmControlDTO {
/**
* 线 Id
*/
private String threadPool;
/**
*
*/
private MessageTypeEnum typeEnum;
/**
* 线
*
* @return
*/
public String buildPk() {
return threadPool + "_" + typeEnum;
}
}

@ -0,0 +1,44 @@
package com.github.dynamic.threadpool.starter.alarm;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
/**
* .
*
* @author chen.ma
* @date 2021/10/28 21:24
*/
public class AlarmControlHandler {
private final Cache<String, String> cache;
public AlarmControlHandler(long alarmInterval) {
cache = CacheBuilder.newBuilder()
.expireAfterWrite(alarmInterval, TimeUnit.MINUTES)
.build();
}
/**
* .
*
* @param alarmControl
* @return
*/
public boolean isSend(AlarmControlDTO alarmControl) {
String pkId = cache.getIfPresent(alarmControl.buildPk());
if (StrUtil.isBlank(pkId)) {
// val 无意义
cache.put(alarmControl.buildPk(), IdUtil.simpleUUID());
return true;
}
return false;
}
}

@ -14,8 +14,7 @@ import com.github.dynamic.threadpool.starter.toolkit.thread.RejectedTypeEnum;
import com.github.dynamic.threadpool.starter.wrap.DynamicThreadPoolWrap;
import com.google.common.base.Joiner;
import com.taobao.api.ApiException;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@ -31,13 +30,13 @@ import java.util.concurrent.TimeUnit;
* @date 2021/8/15 15:49
*/
@Slf4j
@RequiredArgsConstructor
@AllArgsConstructor
public class DingSendMessageHandler implements SendMessageHandler {
@NonNull
private String active;
@NonNull
private Long alarmInterval;
private InstanceInfo instanceInfo;
@Override
@ -87,7 +86,7 @@ public class DingSendMessageHandler implements SendMessageHandler {
"<font color='#708090' size=2>拒绝策略:%s</font> \n\n" +
"<font color='#708090' size=2>拒绝策略执行次数:</font><font color='#FF0000' size=2>%d</font> \n\n " +
"<font color='#708090' size=2>OWNER@%s</font> \n\n" +
"<font color='#708090' size=2>提示:5 分钟内此线程池不会重复告警(可配置)</font> \n\n" +
"<font color='#708090' size=2>提示:%d 分钟内此线程池不会重复告警(可配置)</font> \n\n" +
" --- \n\n " +
"**播报时间:%s**",
@ -123,6 +122,8 @@ public class DingSendMessageHandler implements SendMessageHandler {
pool.getRejectCount(),
// 告警手机号
afterReceives,
// 报警频率
alarmInterval,
// 当前时间
DateUtil.now()
);

@ -8,8 +8,24 @@ package com.github.dynamic.threadpool.starter.alarm;
*/
public enum MessageTypeEnum {
/**
*
*/
CHANGE,
ALARM
/**
*
*/
CAPACITY,
/**
*
*/
LIVENESS,
/**
*
*/
REJECT
}

@ -19,12 +19,24 @@ import java.util.Optional;
@Slf4j
public class ThreadPoolAlarmManage {
/**
*
*/
private static final SendMessageService SEND_MESSAGE_SERVICE;
/**
*
*/
private static final AlarmControlHandler ALARM_CONTROL_HANDLER;
static {
SEND_MESSAGE_SERVICE = Optional.ofNullable(ApplicationContextHolder.getInstance())
.map(each -> each.getBean(MessageAlarmConfig.SEND_MESSAGE_BEAN_NAME, SendMessageService.class))
.orElse(null);
ALARM_CONTROL_HANDLER = Optional.ofNullable(ApplicationContextHolder.getInstance())
.map(each -> each.getBean(AlarmControlHandler.class))
.orElse(null);
}
/**
@ -33,6 +45,9 @@ public class ThreadPoolAlarmManage {
* @param threadPoolExecutor
*/
public static void checkPoolCapacityAlarm(CustomThreadPoolExecutor threadPoolExecutor) {
if (SEND_MESSAGE_SERVICE == null) {
return;
}
ThreadPoolAlarm threadPoolAlarm = threadPoolExecutor.getThreadPoolAlarm();
ResizableCapacityLinkedBlockIngQueue blockIngQueue =
(ResizableCapacityLinkedBlockIngQueue) threadPoolExecutor.getQueue();
@ -40,7 +55,9 @@ public class ThreadPoolAlarmManage {
int queueSize = blockIngQueue.size();
int capacity = queueSize + blockIngQueue.remainingCapacity();
int divide = CalculateUtil.divide(queueSize, capacity);
if (divide > threadPoolAlarm.getCapacityAlarm()) {
boolean isSend = divide > threadPoolAlarm.getCapacityAlarm()
&& isSendMessage(threadPoolExecutor, MessageTypeEnum.CAPACITY);
if (isSend) {
SEND_MESSAGE_SERVICE.sendAlarmMessage(threadPoolExecutor);
}
}
@ -52,13 +69,16 @@ public class ThreadPoolAlarmManage {
* @param threadPoolExecutor
*/
public static void checkPoolLivenessAlarm(boolean isCore, CustomThreadPoolExecutor threadPoolExecutor) {
if (isCore || SEND_MESSAGE_SERVICE == null) {
if (isCore || SEND_MESSAGE_SERVICE == null || !isSendMessage(threadPoolExecutor, MessageTypeEnum.LIVENESS)) {
return;
}
int activeCount = threadPoolExecutor.getActiveCount();
int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
int divide = CalculateUtil.divide(activeCount, maximumPoolSize);
if (divide > threadPoolExecutor.getThreadPoolAlarm().getLivenessAlarm()) {
boolean isSend = divide > threadPoolExecutor.getThreadPoolAlarm().getLivenessAlarm()
&& isSendMessage(threadPoolExecutor, MessageTypeEnum.CAPACITY);
if (isSend) {
SEND_MESSAGE_SERVICE.sendAlarmMessage(threadPoolExecutor);
}
}
@ -69,7 +89,11 @@ public class ThreadPoolAlarmManage {
* @param threadPoolExecutor
*/
public static void checkPoolRejectAlarm(CustomThreadPoolExecutor threadPoolExecutor) {
if (SEND_MESSAGE_SERVICE != null) {
if (SEND_MESSAGE_SERVICE == null) {
return;
}
if (isSendMessage(threadPoolExecutor, MessageTypeEnum.REJECT)) {
SEND_MESSAGE_SERVICE.sendAlarmMessage(threadPoolExecutor);
}
}
@ -80,9 +104,26 @@ public class ThreadPoolAlarmManage {
* @param parameter
*/
public static void sendPoolConfigChange(PoolParameterInfo parameter) {
if (SEND_MESSAGE_SERVICE != null) {
SEND_MESSAGE_SERVICE.sendChangeMessage(parameter);
if (SEND_MESSAGE_SERVICE == null) {
return;
}
SEND_MESSAGE_SERVICE.sendChangeMessage(parameter);
}
/**
* Is send message.
*
* @param threadPoolExecutor
* @param typeEnum
* @return
*/
private static boolean isSendMessage(CustomThreadPoolExecutor threadPoolExecutor, MessageTypeEnum typeEnum) {
AlarmControlDTO alarmControl = AlarmControlDTO.builder()
.threadPool(threadPoolExecutor.getThreadPoolId())
.typeEnum(typeEnum)
.build();
return ALARM_CONTROL_HANDLER.isSend(alarmControl);
}
}

@ -42,6 +42,11 @@ public class BootstrapProperties {
*/
private boolean banner = true;
/**
* Alarm interval
*/
private Long alarmInterval;
/**
* notifys
*/

@ -1,16 +1,15 @@
package com.github.dynamic.threadpool.starter.config;
import com.github.dynamic.threadpool.common.model.InstanceInfo;
import com.github.dynamic.threadpool.starter.alarm.BaseSendMessageService;
import com.github.dynamic.threadpool.starter.alarm.DingSendMessageHandler;
import com.github.dynamic.threadpool.starter.alarm.SendMessageHandler;
import com.github.dynamic.threadpool.starter.alarm.SendMessageService;
import com.github.dynamic.threadpool.starter.alarm.*;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Optional;
/**
* Message alarm config.
*
@ -37,7 +36,14 @@ public class MessageAlarmConfig {
@Bean
public SendMessageHandler dingSendMessageHandler() {
String active = environment.getProperty("spring.profiles.active", Strings.EMPTY);
return new DingSendMessageHandler(active, instanceInfo);
Long alarmInterval = Optional.ofNullable(properties.getAlarmInterval()).orElse(5L);
return new DingSendMessageHandler(active, alarmInterval, instanceInfo);
}
@Bean
public AlarmControlHandler alarmControlHandler() {
Long alarmInterval = properties.getAlarmInterval();
return new AlarmControlHandler(alarmInterval);
}
}

@ -14,7 +14,8 @@ spring:
- type: DING
url: https://oapi.dingtalk.com/robot/send?access_token=
token: 4a582a588a161d6e3a1bd1de7eea9ee9f562cdfcbe56b6e72029e7fd512b2eae
receives: '15601166691,18210045950'
receives: '15601166691'
alarm-interval: 5
server-addr: http://localhost:6691
namespace: prescription
item-id: ${spring.application.name}

Loading…
Cancel
Save