Bläddra i källkod

优化报警代码

lideyin 5 år sedan
förälder
incheckning
ec93ef9f7e

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

@@ -1,7 +1,6 @@
 package cn.com.qmth.examcloud.core.oe.student.face.service.impl;
 
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * @Description 考试照片统计控制器
@@ -15,33 +14,34 @@ public class ExamCaptureProcessStatisticController {
     //人脸比对处理失败数量
     private static AtomicInteger faceCompareFailedCount = new AtomicInteger(0);
 
-    private static ReentrantLock facePPLock = new ReentrantLock();
-    private static ReentrantLock faceLivenessLock = new ReentrantLock();
+    private static Object facePPLock = new Object();
+    private static Object faceLivenessLock = new Object();
 
     /**
      * 人脸比对总数量自增
      */
     public static void increaseFaceCompareCount() {
-        faceCompareCount.incrementAndGet();
+        synchronized (facePPLock) {
+            faceCompareCount.incrementAndGet();
+        }
     }
 
     /**
      * 人脸比对错误数量自增
      */
     public static void increaseFaceCompareFailedCount() {
-        faceCompareFailedCount.incrementAndGet();
+        synchronized (facePPLock) {
+            faceCompareFailedCount.incrementAndGet();
+        }
     }
 
     /**
      * 同步重置人脸比对所有数量
      */
     public static void resetAllFaceCompareCount() {
-        try {
-            facePPLock.lock();
+        synchronized (facePPLock) {
             faceCompareCount.set(0);
             faceCompareFailedCount.set(0);
-        } finally {
-            facePPLock.unlock();
         }
     }
 
@@ -51,7 +51,9 @@ public class ExamCaptureProcessStatisticController {
      * @return int
      */
     public static int getFaceCompareCount() {
-        return faceCompareCount.get();
+        synchronized (facePPLock) {
+            return faceCompareCount.get();
+        }
     }
 
     /**
@@ -60,19 +62,23 @@ public class ExamCaptureProcessStatisticController {
      * @return int
      */
     public static int getFaceCompareFailedCount() {
-        return faceCompareFailedCount.get();
+        synchronized (facePPLock) {
+            return faceCompareFailedCount.get();
+        }
     }
 
     /**
      * 人脸比对失败率
      *
-     * @return double
+     * @return int
      */
-    public static double getFaceCompareFailureRate() {
-        if (faceCompareCount.get() == 0) {
-            return 0;
+    public static int getFaceCompareFailurePercent() {
+        synchronized (facePPLock) {
+            if (faceCompareCount.get() == 0) {
+                return 0;
+            }
+            return faceCompareFailedCount.get() * 100 / faceCompareCount.get();
         }
-        return (double) faceCompareFailedCount.get() / (double) faceCompareCount.get();
     }
 
     //活体检测处理数量
@@ -84,26 +90,27 @@ public class ExamCaptureProcessStatisticController {
      * 活体检测总数量自增
      */
     public static void increaseFaceLivenessDetectCount() {
-        faceLivenessDetectCount.incrementAndGet();
+        synchronized (faceLivenessLock) {
+            faceLivenessDetectCount.incrementAndGet();
+        }
     }
 
     /**
      * 活体检测错误数量自增
      */
     public static void increaseFaceLivenessDetectFailedCount() {
-        faceLivenessDetectFailedCount.incrementAndGet();
+        synchronized (faceLivenessLock) {
+            faceLivenessDetectFailedCount.incrementAndGet();
+        }
     }
 
     /**
      * 重置活体检测所有数量
      */
     public static void resetAllFaceLivenessDetectCount() {
-        try {
-            faceLivenessLock.lock();
+        synchronized (faceLivenessLock) {
             faceLivenessDetectCount.set(0);
             faceLivenessDetectFailedCount.set(0);
-        } finally {
-            faceLivenessLock.unlock();
         }
     }
 
@@ -113,7 +120,9 @@ public class ExamCaptureProcessStatisticController {
      * @return
      */
     public static int getFaceLivenessDetectCount() {
-        return faceLivenessDetectCount.get();
+        synchronized (faceLivenessLock) {
+            return faceLivenessDetectCount.get();
+        }
     }
 
     /**
@@ -122,18 +131,22 @@ public class ExamCaptureProcessStatisticController {
      * @return
      */
     public static int getFaceLivenessDetectFailedCount() {
-        return faceLivenessDetectFailedCount.get();
+        synchronized (faceLivenessLock) {
+            return faceLivenessDetectFailedCount.get();
+        }
     }
 
     /**
      * 活体检测失败率
      *
-     * @return
+     * @return int
      */
-    public static double getFaceLivenessDetectFailureRate() {
-        if (faceLivenessDetectCount.get() == 0) {
-            return 0;
+    public static int getFaceLivenessDetectFailurePercent() {
+        synchronized (faceLivenessLock) {
+            if (faceLivenessDetectCount.get() == 0) {
+                return 0;
+            }
+            return faceLivenessDetectFailedCount.get() * 100 / faceLivenessDetectCount.get();
         }
-        return (double) faceLivenessDetectFailedCount.get() / (double) faceLivenessDetectCount.get();
     }
 }

+ 125 - 104
examcloud-core-oe-face-starter/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/starter/config/ProcessBaiduFaceLivenessAlarmTask.java

@@ -1,15 +1,5 @@
 package cn.com.qmth.examcloud.core.oe.student.face.starter.config;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
@@ -19,6 +9,18 @@ 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 com.google.common.collect.Maps;
+import com.googlecode.aviator.AviatorEvaluator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Description 处理抓拍照片预警任务
@@ -30,99 +32,118 @@ import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
 @Order(203)
 public class ProcessBaiduFaceLivenessAlarmTask implements ApplicationRunner {
 
-	private static ExamCloudLog captureLog = ExamCloudLogFactory
-			.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
-
-	// 失败率预警阈值
-	private static final double RATE_WARN_THRESHOLD = 0.5;
-
-	// 总数量预警阈值
-	private static final int COUNT_WARN_THRESHOLD = 10;
-
-	@Autowired
-	SmsCloudService smsCloudService;
-
-	@Override
-	public void run(ApplicationArguments args) throws Exception {
-		Thread thread = new Thread(new Runnable() {
-
-			@Override
-			public void run() {
-				while (true) {
-					try {
-						faceLivenessDectectAlarm();
-					} catch (Exception e) {
-						captureLog.error("[FACE_LIVENESS_ALARM.] 活体检测预警出现异常", e);
-					}
-
-					// 每分钟轮循一次
-					Util.sleep(60);
-				}
-
-			}
-		});
-		thread.setDaemon(true);
-		thread.start();
-	}
-
-	/**
-	 * 活体检测,如果有必要则发短信
-	 */
-	private void faceLivenessDectectAlarm() {
-		if (captureLog.isDebugEnabled()) {
-			captureLog.debug("[FACE_LIVENESS_ALARM] 进入活体检测" + System.currentTimeMillis()
-					+ "....totalCount="
-					+ ExamCaptureProcessStatisticController.getFaceLivenessDetectCount()
-					+ " ,failCount="
-					+ ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount());
-		}
-
-		// 如果每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
-		if (ExamCaptureProcessStatisticController
-				.getFaceLivenessDetectCount() > COUNT_WARN_THRESHOLD
-				&& ExamCaptureProcessStatisticController
-						.getFaceLivenessDetectFailureRate() > RATE_WARN_THRESHOLD) {
-			SysPropertyCacheBean faceLivenessSmsAssemblyCodeProperty = CacheHelper
-					.getSysProperty("capture.faceLiveness.smsAssemblyCode");
-			if (!faceLivenessSmsAssemblyCodeProperty.getHasValue()) {
-				captureLog.error("[FACE_LIVENESS_ALARM.] 未配置人脸比对的短信模板代码,totalCount="
-						+ ExamCaptureProcessStatisticController.getFaceCompareCount()
-						+ ",errorCount="
-						+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-				throw new StatusException("300003", "未配置人脸活体检测的短信模板代码");
-			}
-			SysPropertyCacheBean smsPhoneProperty = CacheHelper
-					.getSysProperty("capture.sms.phones");
-			if (!smsPhoneProperty.getHasValue()) {
-				captureLog.error("[FACE_LIVENESS_ALARM.] 未配置图片处理失败的通知手机号,totalCount="
-						+ ExamCaptureProcessStatisticController.getFaceCompareCount()
-						+ ",errorCount="
-						+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-				throw new StatusException("300004", "未配置图片处理失败的通知手机号");
-			}
-
-			List<String> phoneList = Arrays
-					.asList(smsPhoneProperty.getValue().toString().split(","));
-			SendSmsReq sendSmsReq = new SendSmsReq();
-			sendSmsReq.setPhoneList(phoneList);
-			sendSmsReq
-					.setSmsAssemblyCode(faceLivenessSmsAssemblyCodeProperty.getValue().toString());
-
-			HashMap<String, String> params = new HashMap<>();
-			params.put("totalCount", String
-					.valueOf(ExamCaptureProcessStatisticController.getFaceLivenessDetectCount()));
-			params.put("errorCount", String.valueOf(
-					ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount()));
-			sendSmsReq.setParams(params);
-			try {
-				smsCloudService.sendSms(sendSmsReq);
-			} catch (Exception e) {
-				captureLog.error("[PROCESS_FACE_LIVENESS.] 发送短信出现异常", e);
-			}
-		}
-		// 每1分钟重置一次总数量与失败数量
-		ExamCaptureProcessStatisticController.resetAllFaceLivenessDetectCount();
-
-	}
+    private static ExamCloudLog captureLog = ExamCloudLogFactory
+            .getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+
+    @Autowired
+    SmsCloudService smsCloudService;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        Thread thread = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        faceLivenessDectectAlarm();
+                    } catch (Exception e) {
+                        captureLog.error("[FACE_LIVENESS_ALARM.] 活体检测预警出现异常", e);
+                    }
+
+                    // 每分钟轮循一次
+                    Util.sleep(60);
+                }
+
+            }
+        });
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    /**
+     * 活体检测,如果有必要则发短信
+     */
+    private void faceLivenessDectectAlarm() {
+        if (captureLog.isDebugEnabled()) {
+            captureLog.debug("[FACE_LIVENESS_ALARM] 进入活体检测" + System.currentTimeMillis()
+                    + "....totalCount="
+                    + ExamCaptureProcessStatisticController.getFaceLivenessDetectCount()
+                    + " ,failCount="
+                    + ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount());
+        }
+
+        // 默认每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
+        if (needSmsAlarm()) {
+            SysPropertyCacheBean faceLivenessSmsAssemblyCodeProperty = CacheHelper
+                    .getSysProperty("capture.faceLiveness.smsAssemblyCode");
+            if (!faceLivenessSmsAssemblyCodeProperty.getHasValue()) {
+                captureLog.error("[FACE_LIVENESS_ALARM.] 未配置人脸比对的短信模板代码,totalCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareCount()
+                        + ",errorCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+                throw new StatusException("300003", "未配置人脸活体检测的短信模板代码");
+            }
+            SysPropertyCacheBean smsPhoneProperty = CacheHelper
+                    .getSysProperty("capture.sms.phones");
+            if (!smsPhoneProperty.getHasValue()) {
+                captureLog.error("[FACE_LIVENESS_ALARM.] 未配置图片处理失败的通知手机号,totalCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareCount()
+                        + ",errorCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+                throw new StatusException("300004", "未配置图片处理失败的通知手机号");
+            }
+
+            List<String> phoneList = Arrays
+                    .asList(smsPhoneProperty.getValue().toString().split(","));
+            SendSmsReq sendSmsReq = new SendSmsReq();
+            sendSmsReq.setPhoneList(phoneList);
+            sendSmsReq
+                    .setSmsAssemblyCode(faceLivenessSmsAssemblyCodeProperty.getValue().toString());
+
+            HashMap<String, String> params = new HashMap<>();
+            params.put("totalCount", String
+                    .valueOf(ExamCaptureProcessStatisticController.getFaceLivenessDetectCount()));
+            params.put("errorCount", String.valueOf(
+                    ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount()));
+            sendSmsReq.setParams(params);
+            try {
+                smsCloudService.sendSms(sendSmsReq);
+            } catch (Exception e) {
+                captureLog.error("[PROCESS_FACE_LIVENESS.] 发送短信出现异常", e);
+            }
+        }
+        // 每1分钟重置一次总数量与失败数量
+        ExamCaptureProcessStatisticController.resetAllFaceLivenessDetectCount();
+
+    }
+
+    /**
+     * 是否需要短信报警
+     *
+     * @return boolean
+     */
+    private boolean needSmsAlarm() {
+        if (ExamCaptureProcessStatisticController.getFaceCompareCount() == 0) {
+            return false;
+        }
+        SysPropertyCacheBean expressionProperty = CacheHelper.getSysProperty("capture.baidu.expression.alarm");
+        if (expressionProperty.getHasValue()) {
+            String expression = expressionProperty.getValue().toString();
+            Map<String, Object> env = Maps.newHashMap();
+            env.put("totalCount", ExamCaptureProcessStatisticController.getFaceLivenessDetectCount());
+            env.put("failedCount", ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount());
+            try {
+                return (Boolean) AviatorEvaluator.execute(expression, env, true);
+            } catch (Exception e) {
+                throw new StatusException("300004", "failed to execute expression. expression=" + expression);
+            }
+
+        } else {
+            // 默认每分钟失败率超过50%则发短信报警,且失败总数不少于10次则短信报警
+            return ExamCaptureProcessStatisticController.getFaceLivenessDetectFailedCount() > 10 &&
+                    ExamCaptureProcessStatisticController.getFaceLivenessDetectFailurePercent() > 50;
+        }
+    }
 
 }

+ 136 - 116
examcloud-core-oe-face-starter/src/main/java/cn/com/qmth/examcloud/core/oe/student/face/starter/config/ProcessFaceCompareAlarmTask.java

@@ -1,15 +1,5 @@
 package cn.com.qmth.examcloud.core.oe.student.face.starter.config;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
@@ -19,6 +9,19 @@ 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 com.google.common.collect.Maps;
+import com.googlecode.aviator.AviatorEvaluator;
+import com.mysql.cj.util.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Description 人脸比对预警任务
@@ -29,111 +32,128 @@ import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
 @Component
 @Order(202)
 public class ProcessFaceCompareAlarmTask implements ApplicationRunner {
-
-	// 失败率预警阈值
-	private static final double RATE_WARN_THRESHOLD = 0.5;
-
-	// 总数量预警阈值
-	private static final int COUNT_WARN_THRESHOLD = 10;
-
-	@Autowired
-	SmsCloudService smsCloudService;
-
-	private final ExamCloudLog captureLog = ExamCloudLogFactory
-			.getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
-
-	@Override
-	public void run(ApplicationArguments args) throws Exception {
-
-		Thread thread = new Thread(new Runnable() {
-
-			@Override
-			public void run() {
-				while (true) {
-					try {
-						faceCompareAlarm();
-
-					} catch (Exception e) {
-						captureLog.error("[FACE_COMPARE_ALARM.] 人脸比对预警出现异常 ", e);
-					}
-					// 每分钟轮循一次
-					Util.sleep(60);
-				}
-			}
-		});
-
-		thread.setDaemon(true);
-		thread.start();
-	}
-
-	/**
-	 * 人脸比对,如果有必要则发短信
-	 */
-	private void faceCompareAlarm() {
-		if (captureLog.isDebugEnabled()) {
-			captureLog.debug("[FACE_COMPARE_ALARM] 进入人脸" + System.currentTimeMillis()
-					+ "....totalCount="
-					+ ExamCaptureProcessStatisticController.getFaceCompareCount() + " ,failCount="
-					+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-		}
-
-		// 如果每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
-		if (ExamCaptureProcessStatisticController.getFaceCompareCount() > COUNT_WARN_THRESHOLD
-				&& ExamCaptureProcessStatisticController
-						.getFaceCompareFailureRate() > RATE_WARN_THRESHOLD) {
-			SysPropertyCacheBean faceCompareSmsAssemblyCodeProperty = CacheHelper
-					.getSysProperty("capture.faceCompare.smsAssemblyCode");
-
-			if (!faceCompareSmsAssemblyCodeProperty.getHasValue()) {
-				if (captureLog.isErrorEnabled()) {
-					captureLog.error("[FACE_COMPARE_ALARM.] 未配置人脸比对的短信模板代码,totalCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareCount()
-							+ ",errorCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-				}
-				throw new StatusException("300001", "未配置人脸比对的短信模板代码");
-			}
-			SysPropertyCacheBean smsPhoneProperty = CacheHelper
-					.getSysProperty("capture.sms.phones");
-			if (!smsPhoneProperty.getHasValue()) {
-				if (captureLog.isErrorEnabled()) {
-					captureLog.error("[FACE_COMPARE_ALARM.] 未配置图片处理失败的通知手机号,totalCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareCount()
-							+ ",errorCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-				}
-				throw new StatusException("300002", "未配置图片处理失败的通知手机号");
-			}
-
-			List<String> phoneList = Arrays
-					.asList(smsPhoneProperty.getValue().toString().split(","));
-
-			// List<String> phoneList = Arrays.asList("13717595977");
-			SendSmsReq sendSmsReq = new SendSmsReq();
-			sendSmsReq.setPhoneList(phoneList);
-			sendSmsReq.setSmsAssemblyCode(faceCompareSmsAssemblyCodeProperty.getValue().toString());
-			// sendSmsReq.setSmsAssemblyCode("FACECOMPARE");
-
-			HashMap<String, String> params = new HashMap<>();
-			params.put("totalCount",
-					String.valueOf(ExamCaptureProcessStatisticController.getFaceCompareCount()));
-			params.put("errorCount", String
-					.valueOf(ExamCaptureProcessStatisticController.getFaceCompareFailedCount()));
-			sendSmsReq.setParams(params);
-			try {
-				if (captureLog.isDebugEnabled()) {
-					captureLog.debug("[FACE_COMPARE_ALARM.] 开始调用发送短信接口,totalCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareCount()
-							+ ",errorCount="
-							+ ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
-				}
-				smsCloudService.sendSms(sendSmsReq);
-			} catch (Exception e) {
-				captureLog.error("[FACE_COMPARE_ALARM.] 发送短信出现异常", e);
-			}
-		}
-		// 每1分钟重置一次总数量与失败数量
-		ExamCaptureProcessStatisticController.resetAllFaceCompareCount();
-	}
+    @Autowired
+    SmsCloudService smsCloudService;
+
+    private final ExamCloudLog captureLog = ExamCloudLogFactory
+            .getLog("PROCESS_EXAM_CAPTURE_TASK_LOGGER");
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+
+        Thread thread = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        faceCompareAlarm();
+
+                    } catch (Exception e) {
+                        captureLog.error("[FACE_COMPARE_ALARM.] 人脸比对预警出现异常 ", e);
+                    }
+                    // 每分钟轮循一次
+                    Util.sleep(60);
+                }
+            }
+        });
+
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    /**
+     * 人脸比对,如果有必要则发短信
+     */
+    private void faceCompareAlarm() {
+        if (captureLog.isDebugEnabled()) {
+            captureLog.debug("[FACE_COMPARE_ALARM] 进入人脸" + System.currentTimeMillis()
+                    + "....totalCount="
+                    + ExamCaptureProcessStatisticController.getFaceCompareCount() + " ,failCount="
+                    + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+        }
+
+        // 默认每分钟失败率超过50%则发短信报警,且总数不少于10次则短信报警
+        if (needSmsAlarm()) {
+            SysPropertyCacheBean faceCompareSmsAssemblyCodeProperty = CacheHelper
+                    .getSysProperty("capture.faceCompare.smsAssemblyCode");
+
+            if (!faceCompareSmsAssemblyCodeProperty.getHasValue()) {
+                captureLog.error("[FACE_COMPARE_ALARM.] 未配置人脸比对的短信模板代码,totalCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareCount()
+                        + ",errorCount="
+                        + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+                throw new StatusException("300001", "未配置人脸比对的短信模板代码");
+            }
+            SysPropertyCacheBean smsPhoneProperty = CacheHelper
+                    .getSysProperty("capture.sms.phones");
+            if (!smsPhoneProperty.getHasValue()) {
+                if (captureLog.isErrorEnabled()) {
+                    captureLog.error("[FACE_COMPARE_ALARM.] 未配置图片处理失败的通知手机号,totalCount="
+                            + ExamCaptureProcessStatisticController.getFaceCompareCount()
+                            + ",errorCount="
+                            + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+                }
+                throw new StatusException("300002", "未配置图片处理失败的通知手机号");
+            }
+
+            List<String> phoneList = Arrays
+                    .asList(smsPhoneProperty.getValue().toString().split(","));
+
+            // List<String> phoneList = Arrays.asList("13717595977");
+            SendSmsReq sendSmsReq = new SendSmsReq();
+            sendSmsReq.setPhoneList(phoneList);
+            sendSmsReq.setSmsAssemblyCode(faceCompareSmsAssemblyCodeProperty.getValue().toString());
+            // sendSmsReq.setSmsAssemblyCode("FACECOMPARE");
+
+            HashMap<String, String> params = new HashMap<>();
+            params.put("totalCount",
+                    String.valueOf(ExamCaptureProcessStatisticController.getFaceCompareCount()));
+            params.put("errorCount", String
+                    .valueOf(ExamCaptureProcessStatisticController.getFaceCompareFailedCount()));
+            sendSmsReq.setParams(params);
+            try {
+                if (captureLog.isDebugEnabled()) {
+                    captureLog.debug("[FACE_COMPARE_ALARM.] 开始调用发送短信接口,totalCount="
+                            + ExamCaptureProcessStatisticController.getFaceCompareCount()
+                            + ",errorCount="
+                            + ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+                }
+                smsCloudService.sendSms(sendSmsReq);
+            } catch (Exception e) {
+                captureLog.error("[FACE_COMPARE_ALARM.] 发送短信出现异常", e);
+            }
+        }
+        // 每1分钟重置一次总数量与失败数量
+        ExamCaptureProcessStatisticController.resetAllFaceCompareCount();
+    }
+
+    /**
+     * 是否需要短信报警
+     *
+     * @return boolean
+     */
+    private boolean needSmsAlarm() {
+        if (ExamCaptureProcessStatisticController.getFaceCompareCount()==0){
+            return false;
+        }
+        SysPropertyCacheBean expressionProperty = CacheHelper.getSysProperty("capture.faceCompare.expression.alarm");
+        if (expressionProperty.getHasValue()) {
+            String expression = expressionProperty.getValue().toString();
+            Map<String, Object> env = Maps.newHashMap();
+            env.put("totalCount", ExamCaptureProcessStatisticController.getFaceCompareCount());
+            env.put("failedCount", ExamCaptureProcessStatisticController.getFaceCompareFailedCount());
+            try {
+                return (Boolean) AviatorEvaluator.execute(expression, env, true);
+            } catch (Exception e) {
+                throw new StatusException("300004", "failed to execute expression. expression=" + expression);
+            }
+
+        } else {
+            // 默认每分钟失败率超过50%则发短信报警,且失败总数不少于10次则短信报警
+            return ExamCaptureProcessStatisticController.getFaceCompareFailedCount() > 10 &&
+                    ExamCaptureProcessStatisticController.getFaceLivenessDetectFailurePercent() > 50;
+        }
+    }
 
 }