스프링부트에서 Scheduling 사용하기

|

스케줄링은 특정 기간 동안 작업을 실행하는 프로세스이다. Spring Boot를 통해 Spring에서 지원하는 스케줄러를 간편하게 작성할 수 있다.

Schedule 기능 켜기

자바 설정(Java configuration) 관련 클래스에 @EnableScheduling 를 추가하면 기능을 사용할 수 있다.

@SpringBootApplication
@EnableScheduling
public class DemoApplication {
   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

구현하기

@Scheduled 어노테이션을 메소드에 선언하며 실행이 가능하며 실행주기는 cron, fixedDelay, fixedRate 라는 세개의 속성으로 지정할 수 있다.

cron 으로 실행주기 설정하기.

그 전에crontab 주기설정 방법부터 알아보자.

*           *      *      *      *      *
초(0-59)   분(0-59)  시간(0-23)  일(1-31)  월(1-12)  요일(0-7) 
각 별 위치에 따라 주기를 다르게 설정 할 수 있다.
순서대로 초-분-시간-일-월-요일 순이다. 그리고 괄호 안의 숫자 범위 내로 별 대신 입력 할 수도 있다.
요일에서 0과 7은 일요일이며, 1부터 월요일이고 6이 토요일이다.

cron 속성 지정하여 사용.

package 패키지위치;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {
   @Scheduled(cron = "0 * 9 * * ?")
   public void cronJobSch() {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
      Date now = new Date();
      String strDate = sdf.format(now);
      System.out.println("Java cron job expression:: " + strDate);
   }
}

다음 예제는 고정된 시간이 1초마다 호출되고 이 시간은 이전 호출이 완료된 시점부터 계산될 것이다.

// 1초에 한번 실행된다.
@Scheduled(fixedDelay = 1000) 
public void scheduleFixedRateTask() {
    System.out.println(
      "Fixed rate task - " + System.currentTimeMillis() / 1000);
}

고정된 비율로 실행하기를 원한다면 어노테이션에서 지정한 프로퍼티명만 바꿔주면 된다. 다음 예제는 각 호출의 연속적인 시작 시각의 간격으로 계산된 1초마다 실행될 것이다.

@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTask() {
  // 주기적으로 실행될 것이다
}

위 차이를 쉽게 얘기하면 fixedDelay 는 이전 수행이 종료된 시점부터 delay 후에 재 호출되고 fixedRate 는 이전 수행이 시작된 시점부터 delay 후에 재 호출된다. 그러므로 fixedRate 로 지정 시 동시에 여러개가 돌 가능성이 존재한다.

Thread pool 설정

기본적으로 모든 @Scheduled 작업은 Spring에 의해 생성 된 한개의 스레드 풀에서 실행된다. 그렇기 때문에 하나의 Scheduled이 돌고 있다면 그것이 다 끝나야 다음 Scheduled이 실행되는 문제가 있다.

실제로 로그를 보면 같은 쓰레드로 확인 될 것이다.

logger.info("Current Thread : {}", Thread.currentThread().getName());

결과

Current Thread : pool-1-thread-1

스프링 부트에서 설정을 통해 Schedule에 대한 쓰래드 풀을 생성하고 그 쓰레드 풀을 사용하여 모든 스케줄 된 작업을 실행하도록 할 수 있다.

아래는 설정 방법에 대한 예제이다.

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

스케줄이 돌고있는 메소드에서 현재 스레드의 이름을 로깅하면 아래와 같은 출력이 표시된다.

Current Thread : my-scheduled-task-pool-1
Current Thread : my-scheduled-task-pool-2

참고:

  • https://blog.outsider.ne.kr/1066
  • https://jdm.kr/blog/2
  • https://www.callicoder.com/spring-boot-task-scheduling-with-scheduled-annotation/

IntelliJ에서 프로젝트 Tomcat 설정하여 올리기

|

1. tomcat 에서 돌아갈 프로젝트를 내려받거나 셋팅한다.

  ex) https://github.com/계정명/프로젝트명.git 을 clone하여 내려받음.

2. 내려받은 후 프로젝트에서 사용할 java 버전을 설정한다.

3. 톰캣설치

http://tomcat.apache.org/ 에서 프로젝트 환경에 맞는 tomcat 다운로드 및 압축해제.

4. 톰캣 환경 설정

 4-1) 우측 상단 ▶버튼 좌측에 있는 ▽ 버튼 클릭 -> Edit Configurations 클릭
 4-2) 설정파일 열리면 + 버튼 눌러 tomcat server 선택
 4-3) 실행시킬 톰캣의 이름 지정 및 톰캣위치(3. 에서 다운받은 톰캣 위치) 지정
 4-4) 지정한 톰캣에 프로젝트 폴더 deploy (deploy 탭에서 exploded war  파일 선택 후 OK 클릭)

마지막으로 ▶ 또는 디버그 버튼으로 톰캣을 실행한다.

추가로 아래내용도 참고하게 될 것이다. (Intellj 에서 jsp 수정 후 tomcat 재구동 없이 배포하기.)

http://jmlim.github.io/intellij/2018/11/23/intellij-tomcat-non-restart/


Intellij 에서 Git 사용하기

|

벡엔드 개발을 할 때 많은 툴을 사용합니다. Source Tree, Postman, Sequel Pro 등등 수없이 개발하다가 해당툴을 사용하기 위해서 왔다 갔다 하는 경우가 많습니다. 하지만 외부 툴을 사용하는 순간 뭔가 개발 흐름이 끊기는 느낌이 있어서 저는 거의 모든 작업을 인텔리제이에서 하는 것을 지향합니다. 이번 포스팅은 Source Tree 즉 Git 관련 툴을 대체하는 방법을 소개하겠습니다. 해당 기능의 단축키는 스크린샷 하단에 표시되있습니다.

Commit

  • Diff : 변경 이력이 있는 모든 파일에 대해서 Diff 기능을 제공합니다. Commit을 하기 전에 자신이 변경한 모든 파일에 대해서 한 번 꼼꼼하게 읽어 보는 습관을 갖는 것이 실수를 줄이는 가장 효율적인 방법이라고 생각합니다.
  • Before Commit : **인텔리제이로 커밋을 했을 경우 얻을 수 있는 최고의 장점이라고 생각합니다. **간단하게 다루고 이 기능은 추후 포스팅을 통해서 다시 한번 다루겠습니다.
    • Check TODO: //TODO 메시지가 남아 있을 경우 사용자에게 해당 TODO가 남아 있다고 알려줍니다.
    • Optimize imports : 사용하지 않은 imports를 제거해 줍니다.
    • Reformat Code : 인텔리제이에서 설정한 코드스타일로 변경 해줍니다.

Push

  • 커밋한 내용을 레파지토리에 푸쉬 하는 기능입니다.

Pull

  • Remote Repository에 변경 내역을 Pull 받는 기능입니다.

Stash

  • Stash 기능은 아주 간단하게 소개하면 변경 내역을 임시저장 해놓는 기능입니다. 가령 다른 branch로 변경을 원할 때 변경 내역이 남아 있어 부득이하게 commit을 하는 경우가 있습니다. 그럴 때 stash 임시 저장소에 저장하면 편리하게 branch 간의 이동을 할 수 있습니다. 기본 단축키가 지정되있지 않아 Find Action 으로 stash 기능을 사용합니다.

UnStash

  • Stash 저장한 내역을 POP 하는 기능입니다. 기본 단축키가 지정되있지 않아 Find Action 으로 unStash 기능을 사용합니다. 저장한 메시지를 기반으로 선택하고 Apply Stash을 클릭하면 변경 내역을 불러옵니다.

Share Project on Github

  • 해당 프로젝트를 Github에 올리는 기능입니다.

Branch

  • New branch, Checkout, Compare, Merge, Rebase 등등 다양한 기능들을 제공합니다.

출처:

  • https://www.popit.kr/intellij-%EC%82%AC%EC%9A%A9%ED%8C%81/

Intellij에서 git branch 삭제하기

|

명령어로 삭제하는 방법

console 명령어로 삭제 시 local branch 삭제

git branch --delete <branch_name> 

remote branch 삭제

git push <repository> :<branch_name>

예)) git push origin :branch_hotfix

Intellij 에서는 branch 또는 remote branch 를 오른쪽 하단메뉴를 통해 간편하게 삭제할 수 있다.

  1. 오른쪽 하단 Git 메뉴 클릭 후 삭제 하려는 브랜치 클릭 후 삭제.
  2. Remote branch 를 삭제 후 원격 저장소가 있는 곳에 들어가서 확인하면 삭제된 것을 확인할 수 있다.

URL 링크로 파일 저장하기.

|

InputStream in = new URL(파일이 있는 URL 링크).openStream(); //ex: http://jmlim.github.io/public/img/imageofhanaumabay.jpg
Files.copy(in, Paths.get(파일을 저장할 링크)); //ex : C:/File/Images/파일명.jpg