8 Commity 6346ba87e4 ... 7909baacc2

Autor SHA1 Wiadomość Data
  dengsixing 7909baacc2 111 2 miesięcy temu
  dengsixing 5fae6acc91 111 3 miesięcy temu
  dengsixing 7c5d62603b 111 4 miesięcy temu
  dengsixing 65bd1d3ee5 111 4 miesięcy temu
  dengsixing d1ca1a5291 111 4 miesięcy temu
  dengsixing d328d5af10 111 4 miesięcy temu
  dengsixing cecd8fee5a 111 5 miesięcy temu
  dengsixing 5b74163a10 111 5 miesięcy temu

+ 4 - 0
src/main/java/com/fdkankan/modeling/ModelingApplication.java

@@ -1,5 +1,6 @@
 package com.fdkankan.modeling;
 
+import cn.hutool.core.io.FileUtil;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -7,6 +8,8 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
+import java.util.UUID;
+
 @SpringBootApplication
 @EnableScheduling
 @ComponentScan(basePackages = {"com.fdkankan.*"})
@@ -15,6 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 public class ModelingApplication {
 
 	public static void main(String[] args) {
+		FileUtil.writeUtf8String("interrupt-calling-" + UUID.randomUUID().toString().replace("-",""), "/opt/queue-name-interrupt-calling.txt");
 		SpringApplication.run(ModelingApplication.class, args);
 	}
 

+ 13 - 0
src/main/java/com/fdkankan/modeling/constants/RabbitMQConstant.java

@@ -0,0 +1,13 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.fdkankan.modeling.constants;
+
+public class RabbitMQConstant {
+
+    public static String QUEUE_FANOUT = "fanout-interrupt-calling";
+
+    public static final String EXCHANGE_FANOUT_INTERRUPT_CALLING = "fanout-exchange-iterrupt-calling";
+}

+ 5 - 4
src/main/java/com/fdkankan/modeling/constants/SysConstants.java

@@ -13,10 +13,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.ObjectUtils;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -41,6 +38,10 @@ public class SysConstants implements ApplicationContextAware {
 
     public static ExecutorService executorService = Executors.newFixedThreadPool(1);
 
+    public static Set<String> callingNum = new HashSet<>();
+
+    public static Set<String> interrupCallingNums = new HashSet<>();
+
     @Value("${hostName.filePath:/opt/hosts/hosts.txt}")
     public void setHostName(String filePath){
         try {

+ 7 - 1
src/main/java/com/fdkankan/modeling/handler/LaserSceneObjGenerateHandler.java

@@ -1,8 +1,11 @@
 package com.fdkankan.modeling.handler;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.model.utils.ComputerUtil;
 import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.modeling.constants.SysConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -31,7 +34,10 @@ public class LaserSceneObjGenerateHandler implements SceneHandler {
             ComputerUtil.createProjectAndDataFile(laserObjFilePath, projectNum, dataMap.get("splitType"),
                     dataMap.get("skyboxType"), null, dataExtras);
 
-            //计算模型并返回需要上传oss的文件集合
+            //场景已删除,不启动算法进程
+            if(SysConstants.interrupCallingNums.contains(projectNum)){
+                throw new BusinessException(ErrorCode.APP_ID_ILLEGAL);
+            }
             CreateObjUtil.build3dModel(laserObjFilePath, "");
 
             log.info("OBJ文件生成完成");

+ 94 - 0
src/main/java/com/fdkankan/modeling/receiver/InterruptCallingListener.java

@@ -0,0 +1,94 @@
+package com.fdkankan.modeling.receiver;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.util.CmdUtils;
+import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.modeling.constants.RabbitMQConstant;
+import com.fdkankan.modeling.constants.SysConstants;
+import com.fdkankan.modeling.entity.BuildLog;
+import com.fdkankan.modeling.service.IBuildLogService;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.ExchangeTypes;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Exchange;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.QueueBinding;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/20
+ **/
+@Slf4j
+@Component
+public class InterruptCallingListener {
+
+    @Autowired
+    private IBuildLogService buildLogService;
+
+    /**
+     * @throws Exception
+     */
+    @RabbitListener(
+            bindings = @QueueBinding(
+                    value = @Queue("#{queueNameService.getInterruptCallingQueueName()}"), // 匿名队列(随机生成队列名,非持久)
+                    exchange = @Exchange(name = RabbitMQConstant.EXCHANGE_FANOUT_INTERRUPT_CALLING, type = ExchangeTypes.FANOUT),
+                    key = "" // Fanout 交换机忽略路由键
+            )
+    )
+    public void buildSceneHandler(Channel channel, Message message) throws Exception {
+        SysConstants.SYSTEM_BUILDING = true;
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            JSONObject jsonObject = JSON.parseObject(msg);
+            String num = jsonObject.getString("num");
+
+            log.info("接收到请求:{}", num);
+
+            SysConstants.interrupCallingNums.add(num);
+
+            log.info("buildSceneHandler,已经删除的场景码:{}", JSON.toJSONString(SysConstants.interrupCallingNums));
+
+            //如果该场景已经调起了算法进程,需要终止算法进程
+            if(SysConstants.callingNum.contains(num)){
+                //进入计算之前,把上次未关闭的算法杀掉(主要是重启的问题)
+                this.killMainLoader();
+                List<BuildLog> list = buildLogService.list(new LambdaQueryWrapper<BuildLog>().eq(BuildLog::getSceneNum, num).orderByDesc(BuildLog::getId));
+                if(CollUtil.isNotEmpty(list)){
+                    String dataSource = list.get(0).getDataSource();
+                    //算法文件锁是否存在,如果存在,则删除
+                    String lockPath = dataSource + "/.lockdirectory";
+                    if(FileUtil.exist(lockPath)){
+                        FileUtil.del(lockPath);
+                    }
+                }
+            }
+        }finally {
+            channel.basicAck(deliveryTag, false);
+        }
+    }
+
+    public void killMainLoader() throws Exception {
+        log.info("开始杀掉算法进程");
+        String command = "sudo ps -ef | grep 'MainLoader.exe' | grep -v grep | awk '{print $2}' | xargs kill -9";
+        CmdUtils.callLineSh(command);
+        log.info("开始杀掉算法完毕");
+    }
+
+}

+ 20 - 0
src/main/java/com/fdkankan/modeling/receiver/QueueNameService.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeling.receiver;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.modeling.constants.RabbitMQConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class QueueNameService {
+
+    public String getInterruptCallingQueueName(){
+        String queueName = FileUtil.readUtf8String("/opt/queue-name-interrupt-calling.txt");
+        if(StrUtil.isEmpty(queueName)){
+            queueName = RabbitMQConstant.QUEUE_FANOUT;
+        }
+        return queueName;
+    }
+}

+ 24 - 9
src/main/java/com/fdkankan/modeling/receiver/RabbitMqListener.java

@@ -5,16 +5,15 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.watch.WatchMonitor;
 import cn.hutool.core.io.watch.Watcher;
 import cn.hutool.core.lang.Console;
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.ModelingBuildStatus;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.util.CmdUtils;
 import com.fdkankan.common.util.FileUtils;
-import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.utils.ComputerUtil;
 import com.fdkankan.model.utils.CreateObjUtil;
 import com.fdkankan.modeling.bean.BuildSceneResultBean;
@@ -33,7 +32,6 @@ import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.rabbitmq.client.Channel;
-import com.fdkankan.model.constants.SceneBuildProcessType;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.StopWatch;
@@ -44,6 +42,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ObjectUtils;
+
 import java.io.File;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
@@ -166,7 +165,6 @@ public class RabbitMqListener {
                     return buildScene(buildContext,message, buildSceneResult,buildLog);
                 } catch (Exception e) {
                     log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
-                    e.printStackTrace();
                     return ModelingBuildStatus.FAILED;
                 }
             });
@@ -196,8 +194,8 @@ public class RabbitMqListener {
         buildSceneResult.setCameraType(message.getCameraType());
         buildSceneResult.setBuildStatus(status);
         //计算后处理
-        afterBuild(message, buildSceneResult, buildLog);
 
+        afterBuild(message, buildSceneResult, buildLog);
     }
 
     private ModelingBuildStatus buildScene(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult,BuildLog logRecord) throws Exception{
@@ -258,8 +256,22 @@ public class RabbitMqListener {
         String skyboxType = dataMap.get("skyboxType");
 
         ComputerUtil.createProjectAndDataFile(path,num, splitType, skyboxType,null,null);
+
+        //场景已删除,不启动算法进程
+        log.info("buildScene,已经删除的场景码:{}", JSON.toJSONString(SysConstants.interrupCallingNums));
+        if(SysConstants.interrupCallingNums.contains(num)){
+            SysConstants.interrupCallingNums.remove(num);
+            log.info("场景已被删除,跳出计算,num:{}", num);
+            return ModelingBuildStatus.FAILED;
+        }
+
         //计算模型并返回需要上传oss的文件集合
-        ComputerUtil.computer(num, path, buildType);
+        SysConstants.callingNum.add(num);
+        try {
+            ComputerUtil.computer(num, path, buildType);
+        }finally {
+            SysConstants.callingNum.remove(num);
+        }
 
         // 检测计算结果文件是否有生成
         String resultsPath = path + File.separator + "results" + File.separator;
@@ -394,8 +406,11 @@ public class RabbitMqListener {
      * @param buildStatus
      */
     private void sendCallBuildProcessLog(BuildSceneCallMessage message, ModelingBuildStatus buildStatus){
-        rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
-                BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(buildStatus.code()).build());
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("num", message.getSceneNum());
+        jsonObject.put("buildStatus", buildStatus.code());
+        jsonObject.put("batchId", message.getExt().get("batchId"));
+        rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog, jsonObject);
     }
 
     private void preBuild(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildLog buildLog) throws BuildException {

+ 17 - 1
src/main/resources/bootstrap-test.yml

@@ -3,8 +3,9 @@ spring:
     name: 4dkankan-center-modeling
   cloud:
     nacos:
+      username:
       config:
-        server-addr: 192.168.0.146:8848
+        server-addr: 192.168.0.25:8848
         file-extension: yaml
         namespace: test
         extension-configs:
@@ -34,3 +35,18 @@ spring:
       discovery:
         server-addr: ${spring.cloud.nacos.config.server-addr}
         namespace: ${spring.cloud.nacos.config.namespace}
+#  rabbitmq:
+#    host: 192.168.0.25
+#    port: 5672
+#    username: root
+#    password: root
+#    virtual-host: 4dkankan
+#    connection-timeout: 0
+#    listener:
+#      simple:
+#        prefetch: 1
+#        max-concurrency: 1
+#        acknowledge-mode: manual #开启消费者手动确认
+#    #开启消息投递确认机制
+#    publisher-confirm-type: correlated
+