feat: add caching and performance monitoring
Phase 6: Caching and Monitoring - Add @Cacheable to ScheduleQueryService.getScheduleResult for hot query optimization - Add @CacheEvict to ScheduleArrangeService and ScheduleStatusService for cache invalidation - Create PerformanceMonitorAspect to monitor method execution time (warn if >1s) - Add business logging to key operations (query, arrange) - All 464 tests passing Cache strategy: - Cache key: competitionId - Cache eviction on schedule updates - Performance monitoring via AOP Related to Phase 6 caching and monitoring plan
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,36 @@
|
|||||||
|
package org.springblade.modules.martial.aspect;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class PerformanceMonitorAspect {
|
||||||
|
|
||||||
|
@Around("execution(* org.springblade.modules.martial.service.impl.Schedule*ServiceImpl.*(..))")
|
||||||
|
public Object monitorPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
String methodName = joinPoint.getSignature().toShortString();
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object result = joinPoint.proceed();
|
||||||
|
long executionTime = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
if (executionTime > 1000) {
|
||||||
|
log.warn("Slow method execution: {} took {}ms", methodName, executionTime);
|
||||||
|
} else {
|
||||||
|
log.debug("Method execution: {} took {}ms", methodName, executionTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
long executionTime = System.currentTimeMillis() - startTime;
|
||||||
|
log.error("Method execution failed: {} after {}ms", methodName, executionTime, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -8,6 +8,7 @@ import org.springblade.modules.martial.pojo.dto.*;
|
|||||||
import org.springblade.modules.martial.pojo.entity.*;
|
import org.springblade.modules.martial.pojo.entity.*;
|
||||||
import org.springblade.modules.martial.service.*;
|
import org.springblade.modules.martial.service.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|||||||
+4
@@ -9,6 +9,8 @@ import org.springblade.modules.martial.pojo.entity.*;
|
|||||||
import org.springblade.modules.martial.pojo.vo.ScheduleGroupDetailVO;
|
import org.springblade.modules.martial.pojo.vo.ScheduleGroupDetailVO;
|
||||||
import org.springblade.modules.martial.service.*;
|
import org.springblade.modules.martial.service.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -26,8 +28,10 @@ public class ScheduleQueryServiceImpl implements IScheduleQueryService {
|
|||||||
private final IMartialAthleteService athleteService;
|
private final IMartialAthleteService athleteService;
|
||||||
private final IMartialVenueService venueService;
|
private final IMartialVenueService venueService;
|
||||||
|
|
||||||
|
@Cacheable(value = "scheduleResult", key = "#competitionId", unless = "#result == null")
|
||||||
@Override
|
@Override
|
||||||
public ScheduleResultDTO getScheduleResult(Long competitionId) {
|
public ScheduleResultDTO getScheduleResult(Long competitionId) {
|
||||||
|
log.info("Querying schedule result for competition: {}", competitionId);
|
||||||
ScheduleResultDTO result = new ScheduleResultDTO();
|
ScheduleResultDTO result = new ScheduleResultDTO();
|
||||||
|
|
||||||
// 使用优化的一次性JOIN查询获取所有数据
|
// 使用优化的一次性JOIN查询获取所有数据
|
||||||
|
|||||||
+1
@@ -6,6 +6,7 @@ import org.springblade.modules.martial.mapper.MartialScheduleParticipantMapper;
|
|||||||
import org.springblade.modules.martial.pojo.entity.MartialScheduleParticipant;
|
import org.springblade.modules.martial.pojo.entity.MartialScheduleParticipant;
|
||||||
import org.springblade.modules.martial.service.IScheduleStatusService;
|
import org.springblade.modules.martial.service.IScheduleStatusService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|||||||
Reference in New Issue
Block a user