Procházet zdrojové kódy

添加图片处理失败发短信代码

lideyin před 5 roky
rodič
revize
6ead55df40

+ 9 - 1
examcloud-core-oe-face-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/service/impl/BaiduFaceLivenessWorker.java

@@ -17,9 +17,15 @@ import org.apache.commons.logging.LogFactory;
  */
 public class BaiduFaceLivenessWorker implements Worker {
 	private final Log captureLog = LogFactory.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+    private ExamCaptureProcessStatisticController statisticController;
 
-	@Override
+    public BaiduFaceLivenessWorker(ExamCaptureProcessStatisticController statisticController) {
+        this.statisticController = statisticController;
+    }
+
+    @Override
 	public void process(WorkerController controller, Object element) {
+        statisticController.increaseCount();
 		ExamCaptureService examCaptureService = SpringContextHolder.getBean(ExamCaptureService.class);
 		ExamCaptureQueueEntity examCaptureQueue = (ExamCaptureQueueEntity) element;
 		try {
@@ -33,9 +39,11 @@ public class BaiduFaceLivenessWorker implements Worker {
 				// 如果超过并发次数,则添加异常次数
 				controller.addConcurrencyWarn();
 			}else {
+                statisticController.increaseFailureCount();
 				captureLog.error("[BAIDU_FACELIVENESS_WORKER.] 自定义异常 "+e.getDesc(),e);
 			}
 		} catch (Exception e) {
+            statisticController.increaseFailureCount();
 			//异常处理
 			examCaptureQueue.setErrorMsg(e.getMessage());
 			examCaptureService.disposeBaiDuFaceLivenessFaild(examCaptureQueue);

+ 64 - 0
examcloud-core-oe-face-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/service/impl/ExamCaptureProcessStatisticController.java

@@ -0,0 +1,64 @@
+package cn.com.qmth.examcloud.core.oe.student.face.service.impl;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Description 考试照片统计控制器
+ * @Author lideyin
+ * @Date 2019/9/9 17:05
+ * @Version 1.0
+ */
+public class ExamCaptureProcessStatisticController {
+    //处理数量
+    private AtomicInteger count = new AtomicInteger(0);
+    //处理失败数量
+    private AtomicInteger failureCount = new AtomicInteger(0);
+
+    /**
+     * 总数量自增
+     */
+    public void increaseCount() {
+        count.incrementAndGet();
+    }
+
+    /**
+     * 错误数量自增
+     */
+    public void increaseFailureCount() {
+        failureCount.incrementAndGet();
+    }
+
+    /**
+     * 重置总数量
+     */
+    public void resetCount() {
+        count.set(0);
+    }
+
+    /**
+     * 重置失败数量
+     */
+    public void resetFailureCount() {
+        failureCount.set(0);
+    }
+
+    /**
+     * 总数量
+     * @return
+     */
+    public int getCount(){
+        return count.get();
+    }
+
+    /**
+     * 失败率
+     *
+     * @return
+     */
+    public double getFailureRate() {
+        if (count.get() == 0) {
+            return 0;
+        }
+        return (double) failureCount.get() / (double) count.get();
+    }
+}

+ 36 - 29
examcloud-core-oe-face-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/service/impl/FacePPCompareWorker.java

@@ -5,7 +5,6 @@ import cn.com.qmth.examcloud.commons.helpers.concurrency.simple.Worker;
 import cn.com.qmth.examcloud.commons.helpers.concurrency.simple.WorkerController;
 import cn.com.qmth.examcloud.core.oe.common.base.Constants;
 import cn.com.qmth.examcloud.core.oe.common.entity.ExamCaptureQueueEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamCaptureQueueStatus;
 import cn.com.qmth.examcloud.core.oe.student.face.service.ExamCaptureService;
 import cn.com.qmth.examcloud.web.support.SpringContextHolder;
 import org.apache.commons.logging.Log;
@@ -15,35 +14,43 @@ import org.slf4j.LoggerFactory;
 
 /**
  * face++人脸比对工作线程
- * 
+ *
  * @author lideyin 20190620
  */
 public class FacePPCompareWorker implements Worker {
-	private static final Logger log = LoggerFactory.getLogger(FacePPCompareWorker.class);
-	private final Log captureLog = LogFactory.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
-	@Override
-	public void process(WorkerController controller, Object element) {
-		ExamCaptureService examCaptureService = SpringContextHolder
-				.getBean(ExamCaptureService.class);
-		ExamCaptureQueueEntity examCaptureQueueEntity = (ExamCaptureQueueEntity) element;
-		try {
-			examCaptureService.disposeFaceCompare(examCaptureQueueEntity);
-		} catch (StatusException e) {
-			//异常处理
-			examCaptureQueueEntity.setErrorMsg(e.getDesc());
-			examCaptureService.disposeFaceCompareFaild(examCaptureQueueEntity);
-			if ((e.getCode().equals(Constants.FACE_COMPARE_CONCURRENCY_LIMIT_EXCEEDED))) {
-				// 如果超过并发次数,则添加异常次数
-				controller.addConcurrencyWarn();
-			}else {
-				captureLog.error("[BAIDU_FACELIVENESS_WORKER.] 自定义异常 "+e.getDesc(),e);
-			}
-		} catch (Exception e) {
-			//异常处理
-			examCaptureQueueEntity.setErrorMsg(e.getMessage());
-			examCaptureService.disposeFaceCompareFaild(examCaptureQueueEntity);
-			log.error("300001", "处理图片发生异常", e);
-			captureLog.error("[BAIDU_FACELIVENESS_WORKER.] 系统异常 "+e.getMessage(),e);
-		}
-	}
+    private final Log captureLog = LogFactory.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+    private ExamCaptureProcessStatisticController statisticController;
+
+    public FacePPCompareWorker(ExamCaptureProcessStatisticController statisticController) {
+        this.statisticController = statisticController;
+    }
+
+    @Override
+    public void process(WorkerController controller, Object element) {
+        //图片处理数量+1
+        statisticController.increaseCount();
+        ExamCaptureService examCaptureService = SpringContextHolder
+                .getBean(ExamCaptureService.class);
+        ExamCaptureQueueEntity examCaptureQueueEntity = (ExamCaptureQueueEntity) element;
+        try {
+            examCaptureService.disposeFaceCompare(examCaptureQueueEntity);
+        } catch (StatusException e) {
+            //异常处理
+            examCaptureQueueEntity.setErrorMsg(e.getDesc());
+            examCaptureService.disposeFaceCompareFaild(examCaptureQueueEntity);
+            if ((e.getCode().equals(Constants.FACE_COMPARE_CONCURRENCY_LIMIT_EXCEEDED))) {
+                // 如果超过并发次数,则添加异常次数
+                controller.addConcurrencyWarn();
+            } else {
+                statisticController.increaseFailureCount();
+                captureLog.error("[BAIDU_FACELIVENESS_WORKER.] 自定义异常 " + e.getDesc(), e);
+            }
+        } catch (Exception e) {
+            statisticController.increaseFailureCount();
+            //异常处理
+            examCaptureQueueEntity.setErrorMsg(e.getMessage());
+            examCaptureService.disposeFaceCompareFaild(examCaptureQueueEntity);
+            captureLog.error("[BAIDU_FACELIVENESS_WORKER.] 系统异常 " + e.getMessage(), e);
+        }
+    }
 }

+ 49 - 1
examcloud-core-oe-face-starter/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/starter/config/ProcessBaiduFacelivenessTask.java

@@ -1,10 +1,16 @@
 package cn.com.qmth.examcloud.core.oe.student.face.starter.config;
 
+import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.helpers.concurrency.simple.ConcurrentTask;
 import cn.com.qmth.examcloud.commons.util.Util;
 import cn.com.qmth.examcloud.core.oe.common.entity.ExamCaptureQueueEntity;
 import cn.com.qmth.examcloud.core.oe.common.repository.ExamCaptureQueueRepo;
 import cn.com.qmth.examcloud.core.oe.student.face.service.impl.BaiduFaceLivenessWorker;
+import cn.com.qmth.examcloud.core.oe.student.face.service.impl.ExamCaptureProcessStatisticController;
+import cn.com.qmth.examcloud.exchange.inner.api.SmsCloudService;
+import cn.com.qmth.examcloud.exchange.inner.api.request.SendSmsReq;
+import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
 import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -16,7 +22,10 @@ import org.springframework.boot.ApplicationRunner;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * 启动百度活体检测任务
@@ -29,12 +38,21 @@ public class ProcessBaiduFacelivenessTask implements ApplicationRunner {
     @Autowired
     ExamCaptureQueueRepo examCaptureQueueRepo;
     private final Log captureLog = LogFactory.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+    private final ExamCaptureProcessStatisticController statisticController = new ExamCaptureProcessStatisticController();
+    //失败率预警阈值
+    private static final double RATE_WARN_THRESHOLD = 0.5;
+    //总数量预警阈值
+    private static final int COUNT_WARN_THRESHOLD = 10;
+    @Autowired
+    SmsCloudService smsCloudService;
 
     private void start() {
+        sendAlarmSmsIfNecessary();
+
         ConcurrentTask concurrentTask = new ConcurrentTask();
         concurrentTask.setMaxActiveThreadSize(PropertyHolder.getInt("$capture.thread.maxActiveThreadSize", 100));
         concurrentTask.setMinThreadSize(PropertyHolder.getInt("$capture.thread.minThreadSize", 2));
-        concurrentTask.setWorker(new BaiduFaceLivenessWorker());
+        concurrentTask.setWorker(new BaiduFaceLivenessWorker(statisticController));
         concurrentTask.start();
         //当前获取数据的批次号(默认用时间戳)
         String processBatchNum = "B_" + System.currentTimeMillis();
@@ -79,6 +97,36 @@ public class ProcessBaiduFacelivenessTask implements ApplicationRunner {
         }
     }
 
+    /**
+     * 如果有必要则发短信
+     */
+    private void sendAlarmSmsIfNecessary() {
+        //每分钟判断是否需要发短信报警
+        Timer timer = new Timer();
+        timer.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                //如果每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
+                if (statisticController.getCount() > COUNT_WARN_THRESHOLD &&
+                        statisticController.getFailureRate() > RATE_WARN_THRESHOLD) {
+                    SysPropertyCacheBean smsPhoneProperty = CacheHelper.getSysProperty("capture.sms.phones");
+                    if (!smsPhoneProperty.getHasValue()) {
+                        throw new StatusException("300001", "未配置图片处理失败的通知手机号");
+                    }
+                    List<String> phoneList = Arrays.asList(smsPhoneProperty.getValue().toString().split(","));
+                    SendSmsReq sendSmsReq = new SendSmsReq();
+                    sendSmsReq.setPhoneList(phoneList);
+                    sendSmsReq.setSmsAssemblyCode("CAPTURE");
+                    sendSmsReq.setParams(null);
+                    smsCloudService.sendSms(sendSmsReq);
+                }
+                //每1分钟重置一次总数量与失败数量
+                statisticController.resetCount();
+                statisticController.resetFailureCount();
+            }
+        }, 100, 60 * 1000);
+    }
+
     @Override
     public void run(ApplicationArguments args) {
         new Thread(() -> {

+ 51 - 2
examcloud-core-oe-face-starter/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/starter/config/ProcessFaceCompareQueueTask.java

@@ -1,11 +1,19 @@
 package cn.com.qmth.examcloud.core.oe.student.face.starter.config;
 
+import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.helpers.concurrency.simple.ConcurrentTask;
 import cn.com.qmth.examcloud.commons.util.Util;
 import cn.com.qmth.examcloud.core.oe.common.entity.ExamCaptureQueueEntity;
 import cn.com.qmth.examcloud.core.oe.common.repository.ExamCaptureQueueRepo;
+import cn.com.qmth.examcloud.core.oe.student.face.service.impl.ExamCaptureProcessStatisticController;
 import cn.com.qmth.examcloud.core.oe.student.face.service.impl.FacePPCompareWorker;
+import cn.com.qmth.examcloud.exchange.inner.api.SmsCloudService;
+import cn.com.qmth.examcloud.exchange.inner.api.client.SmsCloudServiceClient;
+import cn.com.qmth.examcloud.exchange.inner.api.request.SendSmsReq;
+import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
 import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
+import com.google.common.collect.Lists;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.slf4j.Logger;
@@ -16,7 +24,10 @@ import org.springframework.boot.ApplicationRunner;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
+import java.util.Arrays;
 import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * 启动人脸比对任务
@@ -29,12 +40,21 @@ public class ProcessFaceCompareQueueTask implements ApplicationRunner {
     ExamCaptureQueueRepo examCaptureQueueRepo;
     private static final Logger log = LoggerFactory.getLogger(ProcessFaceCompareQueueTask.class);
     private final Log captureLog = LogFactory.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+    private final ExamCaptureProcessStatisticController statisticController = new ExamCaptureProcessStatisticController();
+    //失败率预警阈值
+    private static final double RATE_WARN_THRESHOLD = 0.5;
+    //总数量预警阈值
+    private static final int COUNT_WARN_THRESHOLD = 10;
+    @Autowired
+    SmsCloudService smsCloudService;
 
     private void start() {
+        sendAlarmSmsIfNecessary();
+
         ConcurrentTask concurrentTask = new ConcurrentTask();
         concurrentTask.setMaxActiveThreadSize(PropertyHolder.getInt("$capture.thread.maxActiveThreadSize", 100));
         concurrentTask.setMinThreadSize(PropertyHolder.getInt("$capture.thread.minThreadSize", 2));
-        concurrentTask.setWorker(new FacePPCompareWorker());
+        concurrentTask.setWorker(new FacePPCompareWorker(statisticController));
         concurrentTask.start();
         //当前获取数据的批次号(默认用时间戳)
         String processBatchNum = "A_" + System.currentTimeMillis();
@@ -81,11 +101,40 @@ public class ProcessFaceCompareQueueTask implements ApplicationRunner {
         }
     }
 
+    /**
+     * 如果有必要则发短信
+     */
+    private void sendAlarmSmsIfNecessary() {
+        //每分钟判断是否需要发短信报警
+        Timer timer = new Timer();
+        timer.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                //如果每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
+                if (statisticController.getCount() > COUNT_WARN_THRESHOLD &&
+                        statisticController.getFailureRate() > RATE_WARN_THRESHOLD) {
+                    SysPropertyCacheBean smsPhoneProperty = CacheHelper.getSysProperty("capture.sms.phones");
+                    if (!smsPhoneProperty.getHasValue()) {
+                        throw new StatusException("300001", "未配置图片处理失败的通知手机号");
+                    }
+                    List<String> phoneList = Arrays.asList(smsPhoneProperty.getValue().toString().split(","));
+                    SendSmsReq sendSmsReq = new SendSmsReq();
+                    sendSmsReq.setPhoneList(phoneList);
+                    sendSmsReq.setSmsAssemblyCode("CAPTURE");
+                    sendSmsReq.setParams(null);
+                    smsCloudService.sendSms(sendSmsReq);
+                }
+                //每1分钟重置一次总数量与失败数量
+                statisticController.resetCount();
+                statisticController.resetFailureCount();
+            }
+        }, 100, 60 * 1000);
+    }
+
     @Override
     public void run(ApplicationArguments args) {
         new Thread(() -> {
             start();
         }).start();
     }
-
 }