반응형

저번 글에서 작성한 것처럼 SpringBoot와 Redis를 연결하고 조회수 기능을 구현할 것이다.

 

저번에 RedisTemplate까지 작성을 했었다.

 

우선 계획은 오늘의 조회수와 총조회수를 반환하는 API를 만들고 해당 API를 호출할 때마다 오늘의 조회수가 +1 될 수 있도록 만들 것이다.

 

우선 조회수가 반환될 수 있는 Dto를 작성해준다.

@Data
@AllArgsConstructor
public class AllHitRes {

    @ApiModelProperty(
            value = "블로그 오늘 조회수",
            example = "1"
    )
    private Long today;

    @ApiModelProperty(
            value = "블로그 전체 조회수",
            example = "1020303"
    )
    private Long total;
}

 

그러고는 Redis에서 데이터를 가져오고 오늘의 조회수를 +1 해주는 Service를 구현해 보자.

    private final RedisTemplate<String, String> redisTemplate;

    @Transactional
    public ResponseEntity<AllHitRes> getHit(Integer hitCookie, HttpServletResponse httpServletResponse){
		
        redisTemplate.opsForValue().increment("today");

        Long today = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("today")));
        Long total = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("total")));
	
        return new ResponseEntity<>(new AllHitRes(today, today + total), HttpStatus.OK);
    }

 

increment를 이용하여 today를 +1 하고 그 today와 total을 가져온다.

값을 클라이언트로 보낼 때는 today와 today + total(금일의 조회수까지 합치기 위함)로 보낸다.

 

이제 하루에 한 번 redis에 모아둔 값을 DB로 보내야 한다.

이 방법은 자바의 스케줄러를 사용한다.

@Component
@AllArgsConstructor
@Slf4j
public class RedisToDbScheduler {

    private RedisTemplate<String, String> redisTemplate;
    private HitRepository hitRepository;

    @Scheduled(cron = "0 0 0 * * *")
    @Transactional
    public void saveHitToDB(){

        Long today = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("today")));
        Long total = Long.parseLong(Objects.requireNonNull(redisTemplate.opsForValue().get("total")));

        HitEntity hitEntity = new HitEntity(today, total);

        redisTemplate.opsForValue().set("total", String.valueOf(today + total));
        redisTemplate.opsForValue().set("today", String.valueOf(0));

        log.info("today: {}. total: {}", today, today + total);

        hitRepository.save(hitEntity);
    }
}

@Component를 달아주고 스케줄러로 사용할 메서드에 @Scheduled로 시간을 명시해 준다.

당연하게 @Component를 달아주어야 Spring에게 관리될 수 있다.

 

@Scheduled에는 cron을 사용하여 서버시간으로 0시 0분 0초에 해당 메서드가 실행될 수 있도록 만들었다.

저 메서드에서는 금일의 조회수와 총조회수를 가져와서 DB에 기록해 두고 기록해 두고

금일 조회수와 총조회수를 합쳐 총 조회수를 갱신을 한 후 금일 조회수를 다시 0으로 만들어준다.

 

이렇게 하면 하루에 한 번 메서드가 실행이 되어 redis와 db를 관리할 수 있다.

'블로그 개발 프로젝트' 카테고리의 다른 글

조회수 중복 유저 제거  (0) 2023.08.10
Redis ERR value is not an integer or out of range  (0) 2023.08.09
Nginx에 페이지 연결하기  (0) 2023.08.07
EC2에 Nginx 초기 설정  (0) 2023.08.05
ExceptionHandler  (0) 2023.07.28

+ Recent posts