Ver Fonte

考试记录数据持久化

xiatian há 4 anos atrás
pai
commit
ca3ac8e3e7

+ 3 - 0
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -90,6 +90,9 @@ public class SystemConstant {
     public static final String REDIS_LOCK_STUDENT_PREFIX = "lock:student:student_id_";
     //计算客观分总分锁
     public static final String REDIS_LOCK_TOTAL_OBJECTIVE_SCORE_PREFIX = "lock:total_objective_score:record_id_";
+    
+    //考试记录数据持久化锁
+    public static final String REDIS_LOCK_EXAM_RECORD_PERSISTED_PREFIX = "lock:exam_record_persisted:record_id_";
     /**
      * redis过期时间
      */

+ 5 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -32,4 +32,9 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param param
      */
     void calculateObjectiveScore(Map<String, Object> param);
+    
+	/**考试记录数据持久化
+	 * @param recordId
+	 */
+	public void persisted(Long recordId);
 }

+ 33 - 11
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -1,5 +1,18 @@
 package com.qmth.themis.business.service.impl;
 
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
@@ -12,7 +25,6 @@ import com.qmth.themis.business.dao.TOeExamRecordMapper;
 import com.qmth.themis.business.dto.response.TEExamUnFinishDto;
 import com.qmth.themis.business.entity.TOeExamRecord;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.FinishTypeEnum;
 import com.qmth.themis.business.enums.ObjectiveScorePolicyEnum;
 import com.qmth.themis.business.service.TEExamPaperService;
 import com.qmth.themis.business.service.TEExamService;
@@ -20,15 +32,6 @@ import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.util.SimpleBeanUtil;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
 
 /**
  * @Description: 考试记录 服务实现类
@@ -39,7 +42,9 @@ import java.util.Objects;
  */
 @Service
 public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, TOeExamRecord> implements TOeExamRecordService {
-
+	private final static Logger log = LoggerFactory.getLogger(TOeExamRecordServiceImpl.class);
+	
+	
     @Resource
     TOeExamRecordMapper tOeExamRecordMapper;
 
@@ -279,4 +284,21 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         }
         return -1;
     }
+
+	/**
+	 *考试记录数据持久化
+	 */
+	@Override
+	public void persisted(Long recordId) {
+		String lockKey = SystemConstant.REDIS_LOCK_EXAM_RECORD_PERSISTED_PREFIX + recordId;
+        Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
+        if (!lock) {
+        	log.debug("persisted doing,request ignore");
+        }
+        try {
+        	//TODO
+        } finally {
+            redisUtil.releaseLock(lockKey);
+        }
+	}
 }

+ 3 - 0
themis-exam/src/main/java/com/qmth/themis/exam/start/StartRunning.java

@@ -93,6 +93,9 @@ public class StartRunning implements CommandLineRunner {
         //活体验证保存
         rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.livenessVerifySaveGroup.getCode(), MqTopicEnum.themisTopic.getCode(), MqTagEnum.livenessVerifySave.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(FaceVerifyConcurrentlyImpl.class));
         
+        //考试记录数据持久化
+        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.examRecordPersistedGroup.getCode(), MqTopicEnum.themisTopic.getCode(), MqTagEnum.examRecordPersisted.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(FaceVerifyConcurrentlyImpl.class));
+        
         
         SystemConstant.initTempFiles();
         log.info("服务器启动时执行 end");

+ 6 - 1
themis-mq/src/main/java/com/qmth/themis/mq/enums/MqGroupEnum.java

@@ -96,7 +96,12 @@ public enum MqGroupEnum {
     /**
      * 活体验证
      */
-    livenessVerifySaveGroup("themis-group-exam-livenessVerifySave");
+    livenessVerifySaveGroup("themis-group-exam-livenessVerifySave"),
+    
+    /**
+     * 考试记录数据持久化
+     */
+    examRecordPersistedGroup("themis-group-exam-examRecordPersisted");
 
     private MqGroupEnum(String code) {
         this.code = code;

+ 2 - 1
themis-mq/src/main/java/com/qmth/themis/mq/enums/MqTagEnum.java

@@ -27,7 +27,8 @@ public enum MqTagEnum {
     quartz("quartz标签"),
     calculateObjectiveScore("计算客观分标签"),
     faceVerifySave("人脸验证保存"),
-    livenessVerifySave("活体验证保存");
+    livenessVerifySave("活体验证保存"),
+    examRecordPersisted("考试记录数据持久化");
 
     private MqTagEnum(String code) {
         this.code = code;

+ 5 - 0
themis-mq/src/main/java/com/qmth/themis/mq/service/MqLogicService.java

@@ -70,4 +70,9 @@ public interface MqLogicService {
 	 * @param key
 	 */
 	public void execMqLivenessVerifySaveLogic(MqDto mqDto, String key);
+
+	/**
+	 *考试记录数据持久化
+	 */
+	void execMqExamRecordPersistedLogic(MqDto mqDto, String key);
 }

+ 19 - 0
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -282,6 +282,9 @@ public class MqLogicServiceImpl implements MqLogicService {
         redisUtil.delete(key, mqDto.getId());
     }
 
+    /**
+     *活体验证
+     */
     @Override
     public void execMqLivenessVerifySaveLogic(MqDto mqDto, String key) {
         Gson gson = new Gson();
@@ -301,4 +304,20 @@ public class MqLogicServiceImpl implements MqLogicService {
         tmRocketMessageService.saveOrUpdate(tmRocketMessage);
         redisUtil.delete(key, mqDto.getId());
     }
+    
+    /**
+     *考试记录数据持久化
+     */
+    @Override
+    public void execMqExamRecordPersistedLogic(MqDto mqDto, String key) {
+        Gson gson = new Gson();
+        Map<String, Object> param = (Map<String, Object>) mqDto.getBody();
+        Long recordId = (Long) param.get("recordId");
+        examRecordService.persisted(recordId);
+        mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
+        TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
+        tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));
+        tmRocketMessageService.saveOrUpdate(tmRocketMessage);
+        redisUtil.delete(key, mqDto.getId());
+    }
 }

+ 77 - 0
themis-mq/src/main/java/com/qmth/themis/mq/templete/impl/ExamRecordPersistedConcurrentlyImpl.java

@@ -0,0 +1,77 @@
+package com.qmth.themis.mq.templete.impl;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.util.JacksonUtil;
+import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.mq.service.MqLogicService;
+import com.qmth.themis.mq.templete.Concurrently;
+
+/**考试记录数据持久化
+ * @Description: 
+ * @Author: xiatian
+ * @Date: 2020-08-04
+ */
+@Service
+public class ExamRecordPersistedConcurrentlyImpl implements Concurrently {
+    private final static Logger log = LoggerFactory.getLogger(ExamRecordPersistedConcurrentlyImpl.class);
+    
+	@Resource
+	RedisUtil redisUtil;
+	@Resource
+	MqLogicService mqLogicService;
+
+    @Override
+    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
+                                                    ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+        MqDto mqDto = null;
+        try {
+            long threadId = Thread.currentThread().getId();
+            String threadName = Thread.currentThread().getName();
+            for (MessageExt messageExt : msgs) {
+                log.debug(":{}-:{} CalculateObjectiveScore 重试次数:{}", threadId, threadName,
+                        messageExt.getReconsumeTimes());
+                mqDto = JacksonUtil.readJson(new String(messageExt.getBody(), Constants.CHARSET), MqDto.class);
+                log.debug(":{}-:{} CalculateObjectiveScore 接收到的消息:{}", threadId, threadName,
+                        JacksonUtil.parseJson(mqDto));
+                int reconsumeTime = messageExt.getReconsumeTimes();
+                if (reconsumeTime >= SystemConstant.MAXRECONSUMETIMES) {
+                    mqLogicService.execMqWebsocketUnNormalLogic(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
+                } else {
+                    if (Objects.nonNull(mqDto.getAck()) && mqDto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE
+                            && Objects.nonNull(redisUtil.get(SystemConstant.MQ_TOPIC_BUFFER_LIST, mqDto.getId()))
+                            && redisUtil.lock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId(),
+                            SystemConstant.REDIS_LOCK_MQ_TIME_OUT)) {
+                        log.debug(":{}-:{} 更新db", threadId, threadName);
+                        mqLogicService.execMqFaceVerifySaveLogic(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
+                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+                    } else {
+                        log.debug(":{}-:{} 消息ack未确认,重发", threadId, threadName);
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;// 重试
+                    }
+                }
+            }
+        } catch (Exception e) {
+        	log.error("人脸验证保存,消息消费出错",e);
+            return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+        } finally {
+            if (Objects.nonNull(mqDto)) {
+                redisUtil.releaseLock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId());
+            }
+        }
+        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;// 成功
+    }
+}

+ 0 - 3
themis-mq/src/main/java/com/qmth/themis/mq/templete/impl/FaceVerifyConcurrentlyImpl.java

@@ -12,14 +12,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
-import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.service.TOeFaceVerifyHistoryService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.mq.dto.MqDto;
-import com.qmth.themis.mq.service.MqDtoService;
 import com.qmth.themis.mq.service.MqLogicService;
 import com.qmth.themis.mq.templete.Concurrently;