728x90
0.스케쥴링
스케줄링(Scheduling)은 특정 작업(Task)을 일정한 시간 간격(Time Interval)이나 특정 시간(Time)에 자동으로 실행되는 시스템이다. 이번에는 자주 db에 접근해야하여 변화시키는 조회수를 redis와 스케쥴링을 통해 DB Update를 줄이는것이 목적이다.
1. 조회수 업데이트 스케쥴러
fixedRate 주기마다 redis에 저장해둔 product:views의 값을 DB의 각 상품의 조회수에 더해주는 스케쥴러다.
@Component
@RequiredArgsConstructor
@Slf4j
public class ProductViewScheduler {
private final String REDIS_KEY = "product:views";
private final RedisTemplate<String, Object> redisTemplate;
private final ProductRepository productRepository;
// 5분마다 Redis 조회수를 DB에 반영
@Scheduled(fixedRate = 100000)
public void syncViewCountsToDatabase() {
log.error("product:views syncViewCountsToDatabase ");
Set<String> productIds = redisTemplate.opsForZSet().range(REDIS_KEY, 0, -1)
.stream()
.map(Object::toString)
.collect(Collectors.toSet());
if (productIds == null || productIds.isEmpty()) {
return;
}
for (String productId : productIds) {
// Redis에서 해당 제품의 조회수를 가져옴
Double score = redisTemplate.opsForZSet().score(REDIS_KEY, productId);
if (score != null && score > 0) {
Long id = Long.parseLong(productId);
// DB에서 기존 조회수 가져오기
Product product = productRepository.findById(id).orElse(null);
if (product != null) {
product.setViewCount(product.getViewCount() + score.intValue());
productRepository.save(product);
}
// Redis에서 해당 제품의 조회수 삭제
redisTemplate.opsForZSet().remove(REDIS_KEY, productId);
}
}
}
}
1-1. @Scheduled, @EnableScheduling
Spring Boot에서 스케줄링(Scheduling)을 지원하는 어노테이션으로 @EnableScheduling어노테이션을 메인클래스에 추가한뒤 사용한다.
@Scheduled(fixedRate = 100000)
public void syncViewCountsToDatabase() {
}
- fixedRate → 주기적으로 실행
- fixedDelay → 이전 실행이 끝난 후 일정 시간 후 실행
- initialDelay → 애플리케이션 실행 후 일정 시간이 지난 후 실행
- cron → 특정 시간에 실행
@SpringBootApplication
@EnableScheduling
public class ShoppingmallBackendApplication {
public static void main(String[] args) {
SpringApplication.run(ShoppingmallBackendApplication.class, args);
}
}
1-1-1.cron 표현식
cron 표현식은 특정 시간에 실행되도록 예약하는 스케줄링 방식
초 분 시 일 월 요일
0 * * * * *
@Scheduled(cron = "0 0 0 * * *") // 매일 00:00:00에 실행
2.ProductViewService
기존 실시간 인기상품을 위한 redis부분에 스케쥴링을 위한 조회수또한 업데이트 될수있도록 로직을 업데이트 시켰다.
@Service
@RequiredArgsConstructor
public class ProductViewService {
private final String VIEWS_KEY = "product:views"; // DB 업데이트용
private final String POPULAR_KEY = "product:popular"; // 실시간 인기 제품용
private final RedisTemplate<String, Object> redisTemplate;
// 조회수 증가
public void incrementProductView(Long productId) {
String product = productId.toString();
//DB 동기화를 위한 카운트 증가
redisTemplate.opsForZSet().incrementScore(VIEWS_KEY, product, 1);
redisTemplate.expire(VIEWS_KEY, 1, TimeUnit.HOURS); // 1시간 유지(근데 5분마다 스케쥴링하며 삭제할거임)
//실시간 인기 제품을 위한 카운트 증가
redisTemplate.opsForZSet().incrementScore(POPULAR_KEY, product, 1);
redisTemplate.expire(POPULAR_KEY, 1, TimeUnit.HOURS); // 1시간 유지
}
}
728x90
'BackEnd > SpringBoot' 카테고리의 다른 글
[SpringBoot] redis 예외 필터, redis 연결상태 확인 이벤트 리스너, 추가 (0) | 2025.03.23 |
---|---|
[SpringBoot] 이미지 업로드 기능만들기 (0) | 2025.03.16 |
[SpringBoot] redis로 실시간 인기 제품 (0) | 2025.03.13 |