Commit f33df5fe by huangfusuper

增加线程监控,解决因为一场带来的线程的停机

parent df6ddbfe
......@@ -2,6 +2,7 @@ package com.byit.controller;
import com.byit.exception.DataValidationException;
import com.byit.factory.DaemonScanThreadRunHelperRedisLock;
import com.byit.listener.ListenerWorkThread;
import com.byit.model.vo.EmailAlarmVo;
import com.byit.service.EmailAlarmService;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -22,6 +23,10 @@ public class EmailController {
@RequestMapping("/threadCodeCount")
public int getAcCount(){
return DaemonScanThreadRunHelperRedisLock.SCAN_WORLD_THREAD.getActiveCount();
//return 1;
}
@RequestMapping("/listenerWorkThreadCount")
public int listenerWorkThreadCount(){
return ListenerWorkThread.LISTENER_WORK_THREAD_POOL_EXECUTOR.getActiveCount();
}
}
......@@ -4,6 +4,7 @@ import com.byit.thread.BaseThreadRunHelper;
import com.byit.util.lock.RedissLockUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
......@@ -44,6 +45,11 @@ public abstract class BaseDaemonScanThreadRunHelper implements DaemonScanThreadR
*/
public static final Set<String> LOCK_NAMES = new HashSet<>(8);
/**
* 构建的所由的线程的set集合 用于监控线程监控是否启动
*/
public static final Map<String,Thread> RUNNABLE_MAP = new ConcurrentHashMap<>(8);
/**
......@@ -93,7 +99,10 @@ public abstract class BaseDaemonScanThreadRunHelper implements DaemonScanThreadR
return r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
thread.setName(String.format("[byit-myth-job]-scan flow stream thread-Thread:%s",thread.hashCode()));
String threadName = String.format("[byit-myth-job]-scan flow stream thread-Thread:%s", thread.hashCode());
thread.setName(threadName);
//存储线程
RUNNABLE_MAP.put(threadName, thread);
return thread;
};
}
......
package com.byit.listener;
import cn.hutool.core.collection.CollectionUtil;
import com.byit.factory.BaseDaemonScanThreadRunHelper;
import com.byit.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 监控业务线程
*
* @author huangfu
* @date 2020年9月10日15:29:36
*/
@Component
@DependsOn("mythJobScheduler")
@Slf4j
public class ListenerWorkThread implements InitializingBean {
private volatile boolean flag = false;
public static final ThreadPoolExecutor LISTENER_WORK_THREAD_POOL_EXECUTOR = ThreadPoolUtil.createFixedLengthThreadPoolExecutor(r -> {
Thread thread = new Thread(r);
thread.setName("ListenerWorkThread-Pool");
return thread;
}, 1);
@Override
public void afterPropertiesSet() {
/**
* 获取线程池
*/
ThreadPoolExecutor scanWorldThread = BaseDaemonScanThreadRunHelper.SCAN_WORLD_THREAD;
LISTENER_WORK_THREAD_POOL_EXECUTOR.execute(() ->{
while (!flag) {
try {
TimeUnit.MINUTES.sleep(5);
log.info("--------开始监控此时的工作线程存活状态----------");
//获取存储线程池子
Map<String, Thread> runnableMap = BaseDaemonScanThreadRunHelper.RUNNABLE_MAP;
//存储死掉的线程
Map<String, Thread> deadRunnableMap = new HashMap<>();
//遍历所有的线程 判断线程的存活状态
runnableMap.forEach((key,value) ->{
boolean alive = value.isAlive();
//当线程死亡
if(!alive){
log.warn("--------{}线程处于不活跃状态,需要处理!----------",key);
deadRunnableMap.put(key, value);
}
});
//遍历死亡线程
if(CollectionUtil.isNotEmpty(deadRunnableMap)) {
deadRunnableMap.forEach((key,thread) ->{
//删除已死亡线程
log.warn("--------从线程工厂删除这个线程,{}----------",key);
BaseDaemonScanThreadRunHelper.RUNNABLE_MAP.remove(key);
//删除旧线程
log.warn("--------从线程池子删除这个线程,{}----------",key);
scanWorldThread.remove(thread);
//重启线程
log.warn("--------重启线程,{}----------",key);
scanWorldThread.execute(thread);
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
......@@ -18,10 +18,11 @@ public class RedissonDistributedLocker implements DistributedLocker {
@Override
public void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
try{
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
}catch (IllegalMonitorStateException sta) {
}catch (Exception sta) {
log.warn("--------解锁错误{}---------",sta.getMessage());
}
......@@ -29,11 +30,12 @@ public class RedissonDistributedLocker implements DistributedLocker {
@Override
public boolean trlock(String lockKey, int leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
boolean lockFlag = false;
try {
RLock lock = redissonClient.getLock(lockKey);
lockFlag = lock.tryLock(leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
} catch (Exception e) {
log.error("-----------------{}------------", MythLogUtils.getMessage(e));
Thread.currentThread().interrupt();
}
......@@ -42,11 +44,12 @@ public class RedissonDistributedLocker implements DistributedLocker {
@Override
public boolean trlock(String lockKey, TimeUnit unit ,int timeout) {
RLock lock = redissonClient.getLock(lockKey);
boolean lockFlag = false;
try {
RLock lock = redissonClient.getLock(lockKey);
lockFlag = lock.tryLock(timeout, unit);
} catch (InterruptedException e) {
} catch (Exception e) {
log.error("-----------------{}------------",MythLogUtils.getMessage(e));
Thread.currentThread().interrupt();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment