항해99 - 실전 프로젝트 05(스케쥴링 프로그래밍)

2021. 12. 13. 22:34항해99/실전프로젝트

728x90

이전편 : https://eating-salmon.tistory.com/75

 

항해99 - 실전 프로젝트 04(외부 API, DB에 저장하기)

모든 API를 관리하는 Class 만들기 https://eating-salmon.tistory.com/74 항해99-실전프로젝트 02(공공데이타포털 api 사용하기) E-R 다이어그램 e-r 다이어그램이 나타내고 있는 날씨, 천문 데이터 엔티티 정보.

eating-salmon.tistory.com

spring 스케줄러

일단 스케쥴러는 아래 포스팅에서 다루었으니 개념정리는 넘어가겠다.

https://eating-salmon.tistory.com/52?category=1233733

1. 스케쥴 클래스 만들기

  @Component
  @RequiredArgsConstructor
  @Slf4j
  @EnableScheduling
  public class Schedule {

  }
  • @Component : 스프링 빈 등록을 위한 애노테이션
  • @RequriedArgsConstrustor : 빈 자동주입을 위한 애노테이션, 사용 방법은 아래 포스팅에 포스팅을 해두었다.
    https://eating-salmon.tistory.com/35?category=1233732
  • @Slf4j : log 함수를 사용하기 위한 애노테이션
  • @EnableScheduling : 클래스에 애노테이션을 추가하면 spring에서 제공하는 스케쥴러를 사용할 수 있다.

2. 의존 주입 받기

  @Component
  @RequiredArgsConstructor
  @Slf4j
  @EnableScheduling
  public class Schedule {
      private final static int day = 1000 * 60 * 60 * 24;

      private final API api;

      private final LocationRepository locationRepository;
      private final WeatherRepository weatherRepository;
      private final StarRepository starRepository;
  }
  • private final static int day : 타이머 변수 스케쥴러는 ms 단위 임으로, 1000 * 60 * 60 * 24 은 24시간이 된다.
  • private final API api : 저번 포스팅에서 만들었던 공공 api를 가져오는 빈 객체
  • private final ~~Repository repostiory : DB 저장을 위한 JPA Repository

3. 공공 api 사용 후 데이터 저장하기

  @Component
  @RequiredArgsConstructor
  @Slf4j
  @EnableScheduling
  public class Schedule {
      private final static int day = 1000 * 60 * 60 * 24;

      private final API api;

      private final LocationRepository locationRepository;
      private final WeatherRepository weatherRepository;
      private final StarRepository starRepository;

      @Scheduled(fixedDelay = day)
      public void scheduleDelayTask() throws Exception {
          try{

              deleteStarDb();
              deleteWeatherDB();

              int starCount = 0;
              for (City city : City.values()) {
                  LocationStarMoonDustDto infoByAddress = 
                                              api.findInfoByAddress(city.getKorName(), starCount);
                  api.saveStarLocationWeather(count, infoByAddress);
                  starCount++;
              }
          }
          catch (HttpServerErrorException httpServerErrorException){
              log.info("httpServer Error = {}",httpServerErrorException.getMessage());
          }
      }
    }
    @Transactional
    public void deleteWeatherDB(){
        weatherRepository.deleteAll();
    }


    @Transactional
    public void deleteStarDb(){
        starRepository.deleteAll();
    }
  • try ~ catch : 공공 api 사용시 발생할 수 있는 예외사항 체크
  • deleteStarDB, deleteWeatherDB : 매일 별 테이블과 날씨 테이블을 초기화하기 위해서 모든 데이터를 지운다.
    추가로 삭제 작업임으로 트랜잭션을 통해서 작업의 단위를 나누었다.
  • for (City city : City.values()) : 전국 150여개의 도시를 for문을 통해 api 사용한다.
  • api.saveStarLocationWeather() : 가져온 DTO를 토대로 DB에 저장한다.

4. 스케쥴러 서버를 따로 만든 이유?

  • 24시간에 한번 씩 api를 사용하여 데이터를 불러오는 일은
  • 짧은 시간동안 아주 많은 리소스를 사용하게 된다. 만약 메인 서버와 스케쥴러 서버를 공유하게 된다면
  • 자원 문제를 통해서 서버가 다운될 확률이 증가하여 스케쥴러 서버를 따로 만들게 되었다.