import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct;
import java.util.*;
/**
* 自动增减消费者线程数量的抽象类
*
*/
public abstract class SelfManagementNumberOfConsumerThreads {
@Autowired
protected RedisTemplate<String,String> redisTemplate;
/**
* 消费者实现逻辑方法
*/
protected abstract void run();
/**
* 获取redis队列监听key
*
* @return
*/
protected abstract String getKey();
public void execute(String uuid) {
while (valves.contains(uuid)) {
this.run();
}
}
private Map<String, Thread> threads = new HashMap(16);
private TreeMap<Long, Integer> threadCountConfigMap = new TreeMap<>();
private List<String> valves = new ArrayList<>(16);
private int threadCount;
/**
* 初始化需要监听的redis key
* 初始化线程数量
*/
@PostConstruct
public void initThreadCount() {
this.setThreadCount(1);
this.initThreadCountConfig();
this.threadCountAutoMonitor();
}
public void setThreadCount(Integer threadCount) {
this.executeTask(threadCount - this.threadCount);
this.threadCount = threadCount;
}
/**
* 根据队列待消费数量 变更线程数量
*/
public void initThreadCountConfig() {
threadCountConfigMap.put(100L, 1);
threadCountConfigMap.put(5000L, 3);
threadCountConfigMap.put(10000L, 5);
threadCountConfigMap.put(30000L, 10);
threadCountConfigMap.put(100000L, 15);
}
public void executeTask(int threadCount) {
if (threadCount > 0) {
for (int i = 0; i < threadCount; i++) {
String uuid = UUID.randomUUID().toString();
valves.add(uuid);
//保存登记信息
Thread thread = new Thread(() -> execute(uuid));
thread.setName(this.getKey() + "-" + (valves.size() + 1));
threads.put(uuid, thread);
thread.start();
}
} else if (threadCount < 0) {
for (int i = 0; i < 0 - threadCount && !valves.isEmpty(); i++) {
threads.remove(valves.remove(valves.size() - 1));
}
}
}
private static final Long[] threadCountAutoMonitorSleepTime = {1000L, 60 * 10000L, 10000L, 5 * 60 * 10000L, 10000L, 5 * 60 * 10000L};
/**
* 线程个数 根据自动监听队列大小 做变更
*/
public void threadCountAutoMonitor() {
new Thread(() -> {
int index = 0;
int indexCount = 0;
while (true) {
try {
Thread.sleep(threadCountAutoMonitorSleepTime[index]);
if (Validator.isNullOrEmpty(threadCountConfigMap)) {
continue;
}
Long listSize = redisTemplate.opsForList().size(this.getKey());
listSize = listSize == null ? 0L : listSize;
int count = getCount(listSize);
if (count == this.threadCount && ++indexCount == 3) {
index = ++index == threadCountAutoMonitorSleepTime.length ? 0 : index;
indexCount = 0;
}
setThreadCount(count);
} catch (Exception e) {
index = 0;
indexCount = 0;
}
}
}).start();
}
private int getCount(Long listSize) {
List<Long> longs = new ArrayList<>(threadCountConfigMap.keySet());
if (longs.size() == 1) {
return threadCountConfigMap.get(longs.get(0));
}
for (int i = 0; i < longs.size() - 1; i++) {
if (longs.get(i) > listSize) {
return threadCountConfigMap.get(longs.get(i));
}
}
return threadCountConfigMap.get(longs.get(longs.size() - 1));
}
}
import org.springframework.stereotype.Component;
/**
* 消费者
*/
@Component
public class Listener extends SelfManagementNumberOfConsumerThreads {
/**
* 消费者实现逻辑方法
*/
@Override
protected void run() {
//消费者获取队列信息进行具体业务处理
String str = redisTemplate.opsForList().rightPop("key",60,TimeUnit.SECONDS);
if(Validator.isNotNullOrEmpty(openId)){
//…………
}
}
/**
* 获取redis队列监听key
*
* @return
*/
@Override
protected String getKey() {
return "key";
}
}