|
@@ -18,7 +18,9 @@ import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
|
import org.springframework.scheduling.annotation.Async;
|
|
import org.springframework.scheduling.annotation.Async;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
|
|
|
|
+import javax.annotation.PostConstruct;
|
|
import java.sql.SQLOutput;
|
|
import java.sql.SQLOutput;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
@@ -43,12 +45,17 @@ public class TaskService {
|
|
RedisUtil redisUtil;
|
|
RedisUtil redisUtil;
|
|
@Autowired
|
|
@Autowired
|
|
IScenePlusService scenePlusService;
|
|
IScenePlusService scenePlusService;
|
|
|
|
+ @Autowired
|
|
|
|
+ RabbitMqService rabbitMqService;
|
|
|
|
|
|
public static Integer checkOpenCount = 0;
|
|
public static Integer checkOpenCount = 0;
|
|
|
|
|
|
private static final LinkedBlockingQueue<DelEcsVo> delList = new LinkedBlockingQueue<>();
|
|
private static final LinkedBlockingQueue<DelEcsVo> delList = new LinkedBlockingQueue<>();
|
|
private static final HashMap<String,LinkedBlockingQueue<DelEcsVo>> openMap = new HashMap<>();
|
|
private static final HashMap<String,LinkedBlockingQueue<DelEcsVo>> openMap = new HashMap<>();
|
|
|
|
+ public static HashMap<Integer,List<MqSendLog>> configLogsMap = new HashMap<>();
|
|
|
|
+ public static HashMap<String,MqMsg> mqMsgMap = new HashMap<>();
|
|
|
|
|
|
|
|
+ public static HashMap<String,Integer> countMap = new HashMap<>();
|
|
|
|
|
|
public void sendMq() {
|
|
public void sendMq() {
|
|
checkCount();
|
|
checkCount();
|
|
@@ -77,14 +84,25 @@ public class TaskService {
|
|
mqSendLog.setConfigId(configId);
|
|
mqSendLog.setConfigId(configId);
|
|
numList.add(mqSendLog.getNum());
|
|
numList.add(mqSendLog.getNum());
|
|
}
|
|
}
|
|
-
|
|
|
|
List<MqQueueConfig> queueConfigList = queueConfigService.list();
|
|
List<MqQueueConfig> queueConfigList = queueConfigService.list();
|
|
|
|
+ rabbitMqService.getMqMsgMap(queueConfigList);
|
|
|
|
+
|
|
|
|
+ for (MqQueueConfig config : queueConfigList) {
|
|
|
|
+ List<MqSendLog> msgList = mqSendLogs.stream().filter(e -> e.getConfigId().equals(config.getId())).collect(Collectors.toList());
|
|
|
|
+ configLogsMap.put(config.getId(),msgList);
|
|
|
|
+ }
|
|
|
|
+ setMqMsg(queueConfigList);
|
|
|
|
+ for (MqQueueConfig config : queueConfigList) {
|
|
|
|
+ List<MqSendLog> msgList = mqSendLogs.stream().filter(e -> e.getConfigId().equals(config.getId())).collect(Collectors.toList());
|
|
|
|
+ configLogsMap.put(config.getId(),msgList);
|
|
|
|
+ }
|
|
|
|
+
|
|
for (MqQueueConfig mqQueueConfig : queueConfigList) {
|
|
for (MqQueueConfig mqQueueConfig : queueConfigList) {
|
|
- List<MqSendLog> msgList = mqSendLogs.stream().filter(e -> e.getConfigId().equals(mqQueueConfig.getId())).collect(Collectors.toList());
|
|
|
|
|
|
+ List<MqSendLog> msgList = configLogsMap.get(mqQueueConfig.getId());
|
|
if(msgList.isEmpty()){
|
|
if(msgList.isEmpty()){
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- MqMsg mqMsg = getRabbitMqMsg(mqQueueConfig.getQueueName());
|
|
|
|
|
|
+ MqMsg mqMsg = mqMsgMap.get(mqQueueConfig.getQueueName());
|
|
if(mqMsg == null){
|
|
if(mqMsg == null){
|
|
log.info("获取mq队列数据失败:{}",mqQueueConfig);
|
|
log.info("获取mq队列数据失败:{}",mqQueueConfig);
|
|
continue;
|
|
continue;
|
|
@@ -94,14 +112,54 @@ public class TaskService {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if(mqQueueConfig.getOpenScaling() == 1){ //开启弹性伸缩
|
|
|
|
- checkOpenEcs(mqQueueConfig,msgList,mqMsg.getMessages_ready());
|
|
|
|
|
|
+ if(mqQueueConfig.getOpenScaling() == 1 ){ //开启弹性伸缩
|
|
|
|
+ checkOpenEcs(mqQueueConfig,msgList);
|
|
}
|
|
}
|
|
sendRabbitMq(msgList,mqMsg.getConsumers() - mqMsg.getMessages_unacknowledged() - mqMsg.getMessages_ready(),mqQueueConfig.getQueueName());
|
|
sendRabbitMq(msgList,mqMsg.getConsumers() - mqMsg.getMessages_unacknowledged() - mqMsg.getMessages_ready(),mqQueueConfig.getQueueName());
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 设置调配队列计算
|
|
|
|
+ */
|
|
|
|
+ private void setMqMsg(List<MqQueueConfig> queueConfigList){
|
|
|
|
+ //获取常驻队列
|
|
|
|
+ List<MqQueueConfig> residentList = queueConfigList.stream().filter(e -> e.getIsResident() == 1).collect(Collectors.toList());
|
|
|
|
+ if(residentList.size() != 1){
|
|
|
|
+ log.info("常驻队列未配置,请配置常驻队列");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Integer residentCount = 0;
|
|
|
|
+ MqQueueConfig residentConfig = residentList.get(0);
|
|
|
|
+ MqMsg mqMsg = mqMsgMap.get(residentConfig.getQueueName());
|
|
|
|
+ List<MqSendLog> residentLogList = configLogsMap.get(residentConfig.getId());
|
|
|
|
+ if(mqMsg!= null ){
|
|
|
|
+ residentCount = mqMsg.getConsumers() - mqMsg.getMessages_unacknowledged() - residentLogList.size() ;
|
|
|
|
+ log.info("常驻队列空闲服务器数量为:{},{}",residentConfig.getQueueName(),residentCount);
|
|
|
|
+ }
|
|
|
|
+ //获取默认队列
|
|
|
|
+
|
|
|
|
+ for (MqQueueConfig mqQueueConfig : queueConfigList) {
|
|
|
|
+ List<MqSendLog> msgList = configLogsMap.get(mqQueueConfig.getId());
|
|
|
|
+ if(residentCount >0 && mqQueueConfig.getIsResident() !=1 && mqQueueConfig.getIsSpecial() !=1 && !msgList.isEmpty()){
|
|
|
|
+ updateMqSendLogConfig(residentCount,mqQueueConfig.getId(),residentConfig.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateMqSendLogConfig(Integer residentCount,Integer configId ,Integer residentConfigId){
|
|
|
|
+ List<MqSendLog> msgList = configLogsMap.get(configId);
|
|
|
|
+ for (int i = 0;i < residentCount ;i++){
|
|
|
|
+ if(i > msgList.size() -1){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ MqSendLog mqSendLog = msgList.get(i);
|
|
|
|
+ mqSendLog.setConfigId(residentConfigId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
private void checkCount() {
|
|
private void checkCount() {
|
|
if(checkOpenCount > 10000){ //一个W为一个循环
|
|
if(checkOpenCount > 10000){ //一个W为一个循环
|
|
checkOpenCount = 0;
|
|
checkOpenCount = 0;
|
|
@@ -121,17 +179,36 @@ public class TaskService {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- private void checkOpenEcs(MqQueueConfig mqQueueConfig,List<MqSendLog> msgList,Integer readCount) {
|
|
|
|
- List<MqEcs> list = mqEcsService.getNoModelingByQueueName(mqQueueConfig.getQueueName());
|
|
|
|
|
|
+ private void checkOpenEcs(MqQueueConfig mqQueueConfig,List<MqSendLog> msgList) {
|
|
|
|
+ //获取未关闭的服务器
|
|
|
|
+ List<MqEcs> list = mqEcsService.getNoStopByQueueName(mqQueueConfig.getQueueName());
|
|
|
|
+ countMap.put(mqQueueConfig.getQueueName(),list.size());
|
|
LinkedBlockingQueue<DelEcsVo> openList = openMap.get(mqQueueConfig.getQueueName());
|
|
LinkedBlockingQueue<DelEcsVo> openList = openMap.get(mqQueueConfig.getQueueName());
|
|
if(openList == null){
|
|
if(openList == null){
|
|
openList = new LinkedBlockingQueue<>();
|
|
openList = new LinkedBlockingQueue<>();
|
|
openMap.put(mqQueueConfig.getQueueName(),openList);
|
|
openMap.put(mqQueueConfig.getQueueName(),openList);
|
|
}
|
|
}
|
|
- if(msgList.size() + readCount > mqQueueConfig.getScalingThreshold() + list.size() + openList.size() && mqQueueConfig.getOpenScalingTime() % checkOpenCount == 0){
|
|
|
|
|
|
+
|
|
|
|
+ Integer ecsCount = countMap.get(mqQueueConfig.getQueueName());
|
|
|
|
+ MqMsg mqMsg = mqMsgMap.get(mqQueueConfig.getQueueName());
|
|
|
|
+ //默认队列
|
|
|
|
+ if(mqQueueConfig.getIsDefault() == 1 && ecsCount + openList.size() == 0){
|
|
|
|
+ log.info("默认队列无服务计算中:{}",mqQueueConfig.getQueueName());
|
|
|
|
+ MqScalingConfig mqScalingConfig = mqScalingConfigService.getById(mqQueueConfig.getScalingConfigId());
|
|
|
|
+ DelEcsVo vo = new DelEcsVo(null,mqScalingConfig,mqQueueConfig.getQueueName());
|
|
|
|
+ openList.offer(vo);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Boolean flag = mqQueueConfig.getOpenScalingTime() == 0 || checkOpenCount % mqQueueConfig.getOpenScalingTime() == 0;
|
|
|
|
+ //未在计算的服务器数量
|
|
|
|
+ Integer noModelingCount = mqMsg.getConsumers() - mqMsg.getMessages_unacknowledged();
|
|
|
|
+ //未启动的服务器数量
|
|
|
|
+ Integer notStartCount = ecsCount - mqMsg.getConsumers();
|
|
|
|
+
|
|
|
|
+ if(msgList.size() > mqQueueConfig.getScalingThreshold() + noModelingCount + notStartCount && flag){
|
|
log.info("将待开启弹性伸缩放入队列:{}",mqQueueConfig.getQueueName());
|
|
log.info("将待开启弹性伸缩放入队列:{}",mqQueueConfig.getQueueName());
|
|
MqScalingConfig mqScalingConfig = mqScalingConfigService.getById(mqQueueConfig.getScalingConfigId());
|
|
MqScalingConfig mqScalingConfig = mqScalingConfigService.getById(mqQueueConfig.getScalingConfigId());
|
|
- DelEcsVo vo = new DelEcsVo(null,mqScalingConfig,mqQueueConfig.getQueueName(),new Date(),msgList);
|
|
|
|
|
|
+ DelEcsVo vo = new DelEcsVo(null,mqScalingConfig,mqQueueConfig.getQueueName());
|
|
openList.offer(vo);
|
|
openList.offer(vo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -145,16 +222,19 @@ public class TaskService {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
DelEcsVo take = openList.poll();
|
|
DelEcsVo take = openList.poll();
|
|
- List<MqSendLog> msgList = take.getMsgList();
|
|
|
|
MqQueueConfig mqQueueConfig = queueMap.get(key);
|
|
MqQueueConfig mqQueueConfig = queueMap.get(key);
|
|
|
|
+ List<MqSendLog> msgList = configLogsMap.get(mqQueueConfig.getId());
|
|
if(msgList.size() <= mqQueueConfig.getScalingThreshold()){
|
|
if(msgList.size() <= mqQueueConfig.getScalingThreshold()){
|
|
log.info("openEcsList--待计算任务为:{}未超过阈值:{}无需开启弹性伸缩:{}",msgList.size(),mqQueueConfig.getScalingThreshold() ,key);
|
|
log.info("openEcsList--待计算任务为:{}未超过阈值:{}无需开启弹性伸缩:{}",msgList.size(),mqQueueConfig.getScalingThreshold() ,key);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ countMap.put(mqQueueConfig.getQueueName(),countMap.get(mqQueueConfig.getQueueName()) +1);
|
|
|
|
+
|
|
log.info("openEcsList--开启弹性伸缩数量:{},{}",key,openList.size());
|
|
log.info("openEcsList--开启弹性伸缩数量:{},{}",key,openList.size());
|
|
Boolean flag = createEcs( take.getMqScalingConfig());
|
|
Boolean flag = createEcs( take.getMqScalingConfig());
|
|
if(flag){
|
|
if(flag){
|
|
mqEcsService.add(take.getQueueName());
|
|
mqEcsService.add(take.getQueueName());
|
|
|
|
+ sendRabbitMq(msgList,1,mqQueueConfig.getQueueName());
|
|
Thread.sleep(1000L * 5);
|
|
Thread.sleep(1000L * 5);
|
|
}else {
|
|
}else {
|
|
openList.offer(take);
|
|
openList.offer(take);
|
|
@@ -187,7 +267,7 @@ public class TaskService {
|
|
boolean flag = delList.stream().anyMatch(e -> e.getMqEcs().getEcsName().equals(mqEcs.getEcsName()));
|
|
boolean flag = delList.stream().anyMatch(e -> e.getMqEcs().getEcsName().equals(mqEcs.getEcsName()));
|
|
if(between >= mqQueueConfig.getStopScalingTime() + 60 * count && !flag){
|
|
if(between >= mqQueueConfig.getStopScalingTime() + 60 * count && !flag){
|
|
log.info("checkDelEcs-实例开启时间大于{}分钟,开始关闭:{}",mqQueueConfig.getStopScalingTime(),mqEcs.getEcsName());
|
|
log.info("checkDelEcs-实例开启时间大于{}分钟,开始关闭:{}",mqQueueConfig.getStopScalingTime(),mqEcs.getEcsName());
|
|
- DelEcsVo vo = new DelEcsVo(mqEcs,scalingMap.get(mqQueueConfig.getScalingConfigId()),null,new Date(),null);
|
|
|
|
|
|
+ DelEcsVo vo = new DelEcsVo(mqEcs,scalingMap.get(mqQueueConfig.getScalingConfigId()),null);
|
|
delList.offer(vo);
|
|
delList.offer(vo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -226,22 +306,7 @@ public class TaskService {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- @Value("${spring.rabbitmq.host}")
|
|
|
|
- public String host;
|
|
|
|
- @Value("${spring.rabbitmq.username}")
|
|
|
|
- public String username;
|
|
|
|
- @Value("${spring.rabbitmq.password}")
|
|
|
|
- public String password;
|
|
|
|
- @Value("${spring.rabbitmq.virtual-host}")
|
|
|
|
- public String virtualHost;
|
|
|
|
- @Value("${spring.rabbitmq.mgmt-url}")
|
|
|
|
- public String mgmtUrl;
|
|
|
|
- @Value("${spring.rabbitmq.mgmt-host}")
|
|
|
|
- public String mgmtHost;
|
|
|
|
|
|
|
|
- public MqMsg getRabbitMqMsg(String queueName) {
|
|
|
|
- return RabbitMqUtils.getRabbitMqMsg(mgmtUrl+host+":"+mgmtHost,virtualHost,username,password,queueName);
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized Boolean createEcs(MqScalingConfig mqScaling){
|
|
public synchronized Boolean createEcs(MqScalingConfig mqScaling){
|