Bladeren bron

性能日志

dujian 2 dagen geleden
bovenliggende
commit
92d61b1e5c
1 gewijzigde bestanden met toevoegingen van 123 en 32 verwijderingen
  1. 123 32
      alien-store/src/main/java/shop/alien/store/service/impl/CommonRatingServiceImpl.java

+ 123 - 32
alien-store/src/main/java/shop/alien/store/service/impl/CommonRatingServiceImpl.java

@@ -98,6 +98,19 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             TextReviewServiceEnum.LLM_QUERY_MODERATION.getService()
     );
 
+    /** 内容审核耗时超过该阈值打 WARN(毫秒) */
+    private static final long WARN_SLOW_CONTENT_AUDIT_MS = 5_000L;
+    /** 小票审核接口耗时超过该阈值打 WARN */
+    private static final long WARN_SLOW_RECEIPT_AUDIT_MS = 10_000L;
+    /** 打卡记录查询耗时超过该阈值打 WARN */
+    private static final long WARN_SLOW_CLOCK_IN_QUERY_MS = 2_000L;
+    /** 单条 DB 写入/更新耗时超过该阈值打 WARN */
+    private static final long WARN_SLOW_DB_MS = 2_000L;
+    /** doBusinessWithType 耗时超过该阈值打 WARN */
+    private static final long WARN_SLOW_POST_SAVE_MS = 3_000L;
+    /** 视频审核(含等待异步任务)耗时超过该阈值打 WARN */
+    private static final long WARN_SLOW_VIDEO_AUDIT_MS = 30_000L;
+
 
     /**
      *  新增评价ai审核接口通过后将券发到卡包中
@@ -106,6 +119,7 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
      */
     @Override
     public Integer saveCommonRating(CommonRating commonRating) {
+        final long saveStartMs = System.currentTimeMillis();
         // 1. 先进行AI审核,审核通过后再保存(防止绕过审核)
         try {
             // 参数校验:必填字段不能为空
@@ -148,7 +162,22 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             // 3. 内容审核:评价正文走服务端 moderate;配图/视频由前端直连 AI(util 忽略图,视频审核 util 恒通过)
             AiContentModerationUtil.AuditResult contentAuditResult = new AiContentModerationUtil.AuditResult(true, "");
             if (StringUtils.isNotEmpty(commonRating.getContent()) || !imageUrls.isEmpty()) {
-                contentAuditResult = aiContentModerationUtil.auditContent(commonRating.getContent(), null);
+                long contentAuditStart = System.currentTimeMillis();
+                try {
+                    contentAuditResult = aiContentModerationUtil.auditContent(commonRating.getContent(), null);
+                } catch (Exception ex) {
+                    long contentAuditMs = System.currentTimeMillis() - contentAuditStart;
+                    log.error("saveCommonRating 内容审核接口异常, userId={}, businessId={}, businessType={}, costMs={}, err={}",
+                            commonRating.getUserId(), commonRating.getBusinessId(), commonRating.getBusinessType(),
+                            contentAuditMs, ex.getMessage(), ex);
+                    throw ex;
+                }
+                long contentAuditMs = System.currentTimeMillis() - contentAuditStart;
+                if (contentAuditMs > WARN_SLOW_CONTENT_AUDIT_MS) {
+                    log.warn("saveCommonRating 内容审核耗时偏长: {}ms (阈值{}ms), userId={}, businessId={}, passed={}",
+                            contentAuditMs, WARN_SLOW_CONTENT_AUDIT_MS,
+                            commonRating.getUserId(), commonRating.getBusinessId(), contentAuditResult.isPassed());
+                }
             }
             
             // 内容审核不通过,直接判定为审核不通过
@@ -172,6 +201,7 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             // checkFlag: 0-未审核, 1-审核中, 2-审核通过, 3-审核拒绝
             // 只有审核通过的打卡(checkFlag=2)才算成功打卡
             try {
+                long clockQueryStart = System.currentTimeMillis();
                 LambdaQueryWrapper<StoreClockIn> clockInWrapper = new LambdaQueryWrapper<>();
                 clockInWrapper.eq(StoreClockIn::getUserId, commonRating.getUserId())
                         .eq(StoreClockIn::getStoreId, commonRating.getBusinessId())
@@ -179,6 +209,12 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                         .eq(StoreClockIn::getCheckFlag, 2) // 只统计审核通过的打卡(2-审核通过)
                         .last("LIMIT 1");
                 Integer clockInCount = storeClockInMapper.selectCount(clockInWrapper);
+                long clockQueryMs = System.currentTimeMillis() - clockQueryStart;
+                if (clockQueryMs > WARN_SLOW_CLOCK_IN_QUERY_MS) {
+                    log.warn("saveCommonRating 打卡记录查询耗时偏长: {}ms (阈值{}ms), userId={}, storeId={}",
+                            clockQueryMs, WARN_SLOW_CLOCK_IN_QUERY_MS,
+                            commonRating.getUserId(), commonRating.getBusinessId());
+                }
                 condition1Passed = clockInCount != null && clockInCount > 0;
                 if (condition1Passed) {
                     log.info("评论审核条件1通过:用户在该店铺有审核通过的打卡记录,userId={}, storeId={}", 
@@ -190,8 +226,8 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                             commonRating.getUserId(), commonRating.getBusinessId());
                 }
             } catch (Exception e) {
-                log.warn("检查用户打卡记录失败:userId={}, storeId={}", 
-                        commonRating.getUserId(), commonRating.getBusinessId(), e);
+                log.error("saveCommonRating 检查用户打卡记录异常, userId={}, storeId={}, err={}",
+                        commonRating.getUserId(), commonRating.getBusinessId(), e.getMessage(), e);
                 // 检查异常时,也记录为未通过
                 if (auditReason == null) {
                     auditReason = "检查用户打卡记录失败";
@@ -210,30 +246,49 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                     }
                     
                     // 调用小票审核接口
-                    ReceiptAuditUtil.ReceiptAuditResult receiptAuditResult = receiptAuditUtil.auditReceipt(imageUrls, storeName);
-                    condition2Passed = receiptAuditResult.isPassed();
-                    
-                    if (condition2Passed) {
-                        log.info("评论审核条件2通过:图片中包含该店铺的小票,isValidProof={}, proofType={}", 
-                                receiptAuditResult.isValidProof(), receiptAuditResult.getProofType());
-                    } else {
-                        // 小票审核不通过,记录审核原因
-                        String receiptReason = receiptAuditResult.getFailureReason();
-                        if (StringUtils.isNotEmpty(receiptReason)) {
-                            auditReason = "小票审核不通过:" + receiptReason;
+                    long receiptStart = System.currentTimeMillis();
+                    ReceiptAuditUtil.ReceiptAuditResult receiptAuditResult = null;
+                    try {
+                        receiptAuditResult = receiptAuditUtil.auditReceipt(imageUrls, storeName);
+                    } catch (Exception ex) {
+                        long receiptMs = System.currentTimeMillis() - receiptStart;
+                        log.error("saveCommonRating 小票审核接口异常, userId={}, businessId={}, imageCount={}, costMs={}, err={}",
+                                commonRating.getUserId(), commonRating.getBusinessId(), imageUrls.size(),
+                                receiptMs, ex.getMessage(), ex);
+                        condition2Passed = false;
+                        if (auditReason == null) {
+                            auditReason = "小票审核异常";
+                        }
+                    }
+                    if (receiptAuditResult != null) {
+                        long receiptMs = System.currentTimeMillis() - receiptStart;
+                        if (receiptMs > WARN_SLOW_RECEIPT_AUDIT_MS) {
+                            log.warn("saveCommonRating 小票审核耗时偏长: {}ms (阈值{}ms), userId={}, businessId={}, imageCount={}, passed={}",
+                                    receiptMs, WARN_SLOW_RECEIPT_AUDIT_MS,
+                                    commonRating.getUserId(), commonRating.getBusinessId(), imageUrls.size(),
+                                    receiptAuditResult.isPassed());
+                        }
+                        condition2Passed = receiptAuditResult.isPassed();
+                        if (condition2Passed) {
+                            log.info("评论审核条件2通过:图片中包含该店铺的小票,isValidProof={}, proofType={}",
+                                    receiptAuditResult.isValidProof(), receiptAuditResult.getProofType());
                         } else {
-                            auditReason = "小票审核不通过:上传的图片不是有效的消费凭证(小票、支付记录等)";
+                            String receiptReason = receiptAuditResult.getFailureReason();
+                            if (StringUtils.isNotEmpty(receiptReason)) {
+                                auditReason = "小票审核不通过:" + receiptReason;
+                            } else {
+                                auditReason = "小票审核不通过:上传的图片不是有效的消费凭证(小票、支付记录等)";
+                            }
+                            log.info("评论审核条件2未通过:小票审核失败,reason={}", receiptReason);
                         }
-                        log.info("评论审核条件2未通过:小票审核失败,reason={}", receiptReason);
                     }
                 } catch (Exception e) {
-                    log.warn("小票审核异常:userId={}, storeId={}", 
-                            commonRating.getUserId(), commonRating.getBusinessId(), e);
-                    // 小票审核异常时,也记录为未通过
+                    log.error("saveCommonRating 小票审核流程其它异常(已按不通过处理), userId={}, storeId={}, err={}",
+                            commonRating.getUserId(), commonRating.getBusinessId(), e.getMessage(), e);
                     if (auditReason == null) {
                         auditReason = "小票审核异常";
                     }
-                    condition2Passed = false; // 异常时视为不通过
+                    condition2Passed = false;
                 }
             }
             
@@ -259,9 +314,18 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             }
             
             // 5. 文本/图片审核通过,保存评论(状态为待审核,等待视频审核)
-            int i = this.save(commonRating) ? 0 : 1;
+            long dbSaveStart = System.currentTimeMillis();
+            boolean saved = this.save(commonRating);
+            long dbSaveMs = System.currentTimeMillis() - dbSaveStart;
+            if (dbSaveMs > WARN_SLOW_DB_MS) {
+                log.warn("saveCommonRating 评价入库耗时偏长: {}ms (阈值{}ms), userId={}, businessId={}, saved={}",
+                        dbSaveMs, WARN_SLOW_DB_MS,
+                        commonRating.getUserId(), commonRating.getBusinessId(), saved);
+            }
+            int i = saved ? 0 : 1;
             if (i != 0) {
-                log.error("保存评价失败");
+                log.error("保存评价失败: MyBatis save 返回 false, userId={}, businessId={}, businessType={}, costMs={}",
+                        commonRating.getUserId(), commonRating.getBusinessId(), commonRating.getBusinessType(), dbSaveMs);
                 return 1;
             }
             
@@ -317,11 +381,16 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                 CompletableFuture.runAsync(() -> {
                     AiVideoModerationUtil.VideoAuditResult videoAuditResult = null;
                     try {
-                        // 调用审核接口,增加超时控制(避免接口挂死)
+                        long videoAuditStart = System.currentTimeMillis();
                         videoAuditResult = CompletableFuture.supplyAsync(
                                 () -> aiVideoModerationUtil.auditVideos(videoUrls),
                                 commonVideoTaskExecutor
                         ).get();
+                        long videoAuditMs = System.currentTimeMillis() - videoAuditStart;
+                        if (videoAuditMs > WARN_SLOW_VIDEO_AUDIT_MS) {
+                            log.warn("saveCommonRating 视频审核等待耗时偏长: {}ms (阈值{}ms), ratingId={}, videoCount={}",
+                                    videoAuditMs, WARN_SLOW_VIDEO_AUDIT_MS, commonRating.getId(), videoUrls.size());
+                        }
 
                         // 审核不通过则更新状态和原因
                         if (Objects.nonNull(videoAuditResult) && !videoAuditResult.isPassed()) {
@@ -347,9 +416,7 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                                 if (rating.getAuditStatus() == null || rating.getAuditStatus() == 0) {
                                     rating.setAuditStatus(1);
                                     this.saveOrUpdate(rating);
-                                    // 对不同的businessType进行不同的处理,
-                                    // 使用更新后的rating对象,确保auditStatus正确
-                                    doBusinessWithType(rating);
+                                    invokeDoBusinessWithTypeWithMetrics(rating, commonRating.getBusinessId(), "视频审核通过异步分支");
                                     log.info("视频审核通过,已更新状态为通过,ratingID:{}", rating.getId());
                                 } else if (rating.getAuditStatus() == 2) {
                                     // 之前因为小票/打卡不通过,即使视频通过,也保持为不通过
@@ -366,8 +433,7 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                                 if (rating.getAuditStatus() == null || rating.getAuditStatus() == 0) {
                                     rating.setAuditStatus(1);
                                     this.saveOrUpdate(rating);
-                                    // 使用更新后的rating对象,确保auditStatus正确
-                                    doBusinessWithType(rating);
+                                    invokeDoBusinessWithTypeWithMetrics(rating, commonRating.getBusinessId(), "视频审核结果为空异步分支");
                                     log.info("无视频或视频审核结果为空,文本/图片已通过,设置为审核通过,ratingID:{}", rating.getId());
                                 } else if (rating.getAuditStatus() == 2) {
                                     // 之前因为小票/打卡不通过,保持为不通过
@@ -376,7 +442,8 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                             }
                         }
                     } catch (Exception e) {
-                        log.error("视频审核接口调用异常,commonRating ID:{}", commonRating.getId(), e);
+                        log.error("saveCommonRating 视频审核接口调用异常, ratingId={}, userId={}, businessId={}, err={}",
+                                commonRating.getId(), commonRating.getUserId(), commonRating.getBusinessId(), e.getMessage(), e);
                         CommonRating rating = this.getById(commonRating.getId());
                         if (Objects.nonNull(rating)) {
                             rating.setAuditStatus(2);
@@ -395,8 +462,7 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
                     if (rating.getAuditStatus() == null || rating.getAuditStatus() == 0) {
                         rating.setAuditStatus(1);
                         this.saveOrUpdate(rating);
-                        // 使用更新后的rating对象,确保auditStatus正确
-                        doBusinessWithType(rating);
+                        invokeDoBusinessWithTypeWithMetrics(rating, commonRating.getBusinessId(), "无视频同步分支");
                         log.info("无视频,文本/图片审核已通过,设置为审核通过,ratingID:{}", rating.getId());
                     } else if (rating.getAuditStatus() == 2) {
                         // 之前因为小票/打卡不通过,保持为不通过
@@ -407,12 +473,37 @@ public class CommonRatingServiceImpl extends ServiceImpl<CommonRatingMapper, Com
             
             return i;
         } catch (Exception e) {
-            log.error("CommonRatingService.saveCommonRating ERROR Msg={}", e.getMessage(), e);
+            long totalMs = System.currentTimeMillis() - saveStartMs;
+            log.error("CommonRatingService.saveCommonRating 未捕获异常, totalCostMs={}, userId={}, businessId={}, businessType={}, err={}",
+                    totalMs,
+                    commonRating != null ? commonRating.getUserId() : null,
+                    commonRating != null ? commonRating.getBusinessId() : null,
+                    commonRating != null ? commonRating.getBusinessType() : null,
+                    e.getMessage(), e);
             return 1;
         }
     }
 
     /**
+     * 调用 {@link #doBusinessWithType(CommonRating)} 并记录异常与慢调用
+     */
+    private void invokeDoBusinessWithTypeWithMetrics(CommonRating rating, Integer businessId, String scene) throws Exception {
+        long postStart = System.currentTimeMillis();
+        try {
+            doBusinessWithType(rating);
+        } catch (Exception ex) {
+            log.error("saveCommonRating doBusinessWithType 异常, scene={}, ratingId={}, businessId={}, err={}",
+                    scene, rating != null ? rating.getId() : null, businessId, ex.getMessage(), ex);
+            throw ex;
+        }
+        long postMs = System.currentTimeMillis() - postStart;
+        if (postMs > WARN_SLOW_POST_SAVE_MS) {
+            log.warn("saveCommonRating doBusinessWithType 耗时偏长, scene={}, {}ms (阈值{}ms), ratingId={}, businessId={}",
+                    scene, postMs, WARN_SLOW_POST_SAVE_MS, rating != null ? rating.getId() : null, businessId);
+        }
+    }
+
+    /**
      * 根据不同的businessType进行不同的处理
      * @param commonRating 评价信息
      */