[SpringBoot] ์Šค์ผ€์ค„๋ง

2023. 10. 13. 09:59ยทWeb & Android/SpringBoot

๐Ÿ’ก ScheduledExecutorService๊ณผ SpringBoot์˜ @Scheduled๋กœ ์Šค์ผ€์ค„๋ง์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ScheduledExecutorService์€ ์ธ์ˆ˜์žˆ๋Š” ๋ฉ”์„œ๋“œ์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ @Scheduled๋Š” ์ธ์ˆ˜์žˆ๋Š” ๋ฉ”์„œ๋“œ์— ์ ์šฉ์ด ๋ถˆ๊ฐ€ํ•˜๋‹ค.

ScheduledExecutorService

  • Java 1.5๋ถ€ํ„ฐ ์ง€์›๋˜๋Š” ์Šค์ผ€์ค„๋ง์ด ๊ฐ€๋Šฅํ•œ Executor ์„œ๋น„์Šค๋กœ ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฉฐ, ๊ตฌํ˜„์ฒด๋กœ ScheduledThreadPoolExecutor()๊ฐ€ ์žˆ๋‹ค.
  • ์˜ˆ์ œ ์ฝ”๋“œ
  @Service
  @RequiredArgsConstructor
  @Transactional
  public class BattleRivalService {

    private final BattleRepository battleRepository;
    private final BattleRivalRepository battleRivalRepository;
    private final TeamRepository teamRepository;
    private final BattleService battleService;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public BattleRivalResponseDTO saveBattleRival(Battle battle, TeamMember teamMember) {
            LocalDate lc = LocalDate.now();
            LocalDateTime finishTime = LocalDateTime.now().plusDays(7);

            BattleRival result = battleRivalRepository.findByTeamId(teamMember.getTeam().getId());

            // ํŒ€์ด ๋Œ€๊ฒฐ์— ์ฐธ์—ฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
            if(result == null) {
                BattleRival battleRival = new BattleRival(battle, teamMember.getTeam());
                battleRivalRepository.save(battleRival);

                battle.update(lc);
                battleRepository.save(battle);

                Team team = teamRepository.findById(battle.getBattleRivals().get(0).getTeam().getId()).orElse(null);
                team.updateState("๋Œ€๊ฒฐ ์ง„ํ–‰ ์ค‘");
                teamRepository.save(team);

                team = teamRepository.findById(teamMember.getTeam().getId()).orElse(null);
                team.updateState("๋Œ€๊ฒฐ ์ง„ํ–‰ ์ค‘");
                teamRepository.save(team);

                scheduler.schedule(() -> {
                   try {
                       battleService.finishBattle(battle.getId());
                   } catch (ParseException e) {
                       throw new RuntimeException(e);
                   }
                }, ChronoUnit.SECONDS.between(LocalDateTime.now(), finishTime), TimeUnit.SECONDS);

                return BattleRivalResponseDTO.builder()
                        .teamId(battleRival.getTeam().getId())
                        .teamName(battleRival.getTeam().getName())
                        .peopleNum(battleRival.getTeam().getPeopleNum())
                        .step(battleRival.getStep())
                        .build();
            } else {
                // ํŒ€์ด ๋Œ€๊ฒฐ์— ์ฐธ์—ฌํ•œ ๊ฒฝ์šฐ
                return null;
            }
        }

 

@Scheduled

  • ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ๋Š” ์Šค์ผ€์ค„๋ง ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • @EnableScheduling ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์Šค์ผ€์ค„๋ง์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๊ณ , @Scheduled ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์Šค์ผ€์ค„๋ง ํ•  ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  @EnableScheduling
  @SpringBootApplication
  public class WalkingMateBackApplication {

      public static void main(String[] args) {
          SpringApplication.run(WalkingMateBackApplication.class, args);
      }

  }
  • ์‹ค์ œ ์Šค์ผ€์ค„๋ง ์ž‘์—…ํ•  ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ ๋‹ค.
    @Service
    public class SchedulerService {
     
        @Scheduled(fixedDelay = 1000) // 1์ดˆ๋งˆ๋‹ค ์‹คํ–‰
        public void run() {
            System.out.println("Hello CoCo World!);
        }
    }
    @Component(@Service ๋“ฑ) ์ฆ‰, ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋œ ํด๋ž˜์Šค์—ฌ์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ๋‘ ๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ๊ธฐ๋งŒ ํ•˜๋ฉด ์„ค์ •์€ ๋์ด๊ณ  ๋‹ค์Œ ๊ทœ์น™์„ ์ง€ํ‚ค๋ฉฐ ์Šค์ผ€์ค„๋Ÿฌ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค์ž.
    • @Scheduled ๊ทœ์น™
      - Method๋Š” void ํƒ€์ž…์œผ๋กœ
      - Method๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ์‚ฌ์šฉ ๋ถˆ๊ฐ€

@Scheduled ์†์„ฑ

fixedDelay : milliseconds ๋‹จ์œ„๋กœ, ์ด์ „ Task์˜ ์ข…๋ฃŒ ์‹œ์ ์œผ๋กœ๋ถ€ํ„ฐ ์ •์˜๋œ ์‹œ๊ฐ„๋งŒํผ ์ง€๋‚œ ํ›„ Task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

@Scheduled(fixedDelay = 1000)
public void run() {
    System.out.println("Hello CoCo World!");
}

fixedDelayString : fixedDelay์™€ ๊ฐ™์€๋ฐ ๋ฌธ์ž์—ด๋กœ ๊ฐ’์„ ํ‘œํ˜„ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

@Scheduled(fixedDelay = "1000")
public void run() {
    System.out.println("Hello CoCo World!");
}

fixedRate : milliseconds ๋‹จ์œ„๋กœ, ์ด์ „ Task์˜ ์‹œ์ž‘ ์‹œ์ ์œผ๋กœ๋ถ€ํ„ฐ ์ •์˜๋œ ์‹œ๊ฐ„๋งŒํผ ์ง€๋‚œ ํ›„ Task๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

@Scheduled(fixedRate = 1000)
public void run() {
        System.out.println("Hello CoCo World!");    
}

fixedRateString : fixedRate์™€ ๊ฐ™์€๋ฐ ๋ฌธ์ž์—ด๋กœ ๊ฐ’์„ ํ‘œํ˜„ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

@Scheduled(fixedRateString = "1000")
public void run() {
    System.out.println("Hello CoCo World!");

 

โ€ป fixedDelay vs fixedRate


fixedRate๋Š” ์ž‘์—… ์ˆ˜ํ–‰์‹œ๊ฐ„๊ณผ ์ƒ๊ด€์—†์ด ์ผ์ • ์ฃผ๊ธฐ๋งˆ๋‹ค ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๊ณ ,

fixedDelay๋Š” (์ž‘์—… ์ˆ˜ํ–‰ ์‹œ๊ฐ„์„ ํฌํ•จํ•˜์—ฌ) ์ž‘์—…์„ ๋งˆ์นœ ํ›„๋ถ€ํ„ฐ ์ฃผ๊ธฐ ํƒ€์ด๋จธ๊ฐ€ ๋Œ์•„ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

initialDelay : ์Šค์ผ€์ค„๋Ÿฌ์—์„œ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋“ฑ๋ก๋˜์ž๋งˆ์ž ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ดˆ๊ธฐ ์ง€์—ฐ์‹œ๊ฐ„์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    @Scheduled(fixedRate = 5000, initialDelay = 3000)
    public void run() {
        System.out.println("Hello CoCo World!");
    }

์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด 3์ดˆ์˜ ๋Œ€๊ธฐ์‹œ๊ฐ„(initialDelay) ํ›„์— 5์ดˆ(fixedRate)๋งˆ๋‹ค "Hello CoCo World!"๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์ž‘์—…์„ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์ˆ˜ํ–‰ํ•ด์ค€๋‹ค.

initialDelayString : ์œ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฌธ์ž์—ด๋กœ ๊ฐ’์„ ํ‘œํ˜„ํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

    @Scheduled(fixedRate = 5000, initialDelayString = "3000")
    public void run() {
        System.out.println("Hello CoCo World!");

cron : Cron ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์„ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.

    @Scheduled(cron = "* * * * * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }

์ฒซ ๋ฒˆ์งธ * ๋ถ€ํ„ฐ ์ดˆ(0-59), ๋ถ„(0-59), ์‹œ๊ฐ„(0-23), ์ผ(1-31), ์›”(1-12), ์š”์ผ(0-6) (0: ์ผ, 1: ์›”, 2:ํ™”, 3:์ˆ˜, 4:๋ชฉ, 5:๊ธˆ, 6:ํ† ), Spring @Scheduled cron์€ 6์ž๋ฆฌ ์„ค์ •๋งŒ ํ—ˆ์šฉํ•˜๋ฉฐ ์—ฐ๋„ ์„ค์ •์„ ํ•  ์ˆ˜ ์—†๋‹ค.

  • Cron ํ‘œํ˜„์‹
      • : ๋ชจ๋“  ์กฐ๊ฑด(๋งค์‹œ, ๋งค์ผ, ๋งค์ฃผ์ฒ˜๋Ÿผ ์‚ฌ์šฉ)์„ ์˜๋ฏธ
    • ? : ์„ค์ • ๊ฐ’ ์—†์Œ (๋‚ ์งœ์™€ ์š”์ผ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
    • '-' : ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•  ๋•Œ
    • , : ์—ฌ๋Ÿฌ ๊ฐ’์„ ์ง€์ •ํ•  ๋•Œ
    • / : ์ฆ๋ถ„๊ฐ’, ์ฆ‰ ์ดˆ๊ธฐ๊ฐ’๊ณผ ์ฆ๊ฐ€์น˜ ์„ค์ •์— ์‚ฌ์šฉ
    • L : ๋งˆ์ง€๋ง‰ - ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’ ์„ค์ • ์‹œ ์‚ฌ์šฉ (๋‚ ์งœ์™€ ์š”์ผ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
    • W : ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ‰์ผ(weekday)์„ ์„ค์ •ํ•  ๋•Œ
      • ์˜ˆ) 10W
        - 10์ผ์ด ํ‰์ผ ์ผ ๋•Œ : 10์ผ์— ์‹คํ–‰
        - 10์ผ์ด ํ† ์š”์ผ ์ผ ๋•Œ : ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ‰์ผ์ธ ๊ธˆ์š”์ผ(9์ผ)์— ์‹คํ–‰
        - 10์ผ์ด ์ผ์š”์ผ ์ผ ๋•Œ : ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ‰์ผ์ธ ์›”์š”์ผ(11์ผ)์— ์‹คํ–‰
    • '#' : N๋ฒˆ์งธ ์ฃผ ํŠน์ • ์š”์ผ์„ ์„ค์ •ํ•  ๋•Œ (-์š”์ผ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
      • ์˜ˆ) 4#2
      • ๋ชฉ์š”์ผ#2์งธ์ฃผ์— ์‹คํ–‰

zone : cron ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์‚ฌ์šฉํ•  time zone์œผ๋กœ ๋”ฐ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ Local์˜ time zone์ด๋‹ค.

    @Scheduled(cron = "* * * * * *", zone = "Asia/Seoul")
    public void run() {
        System.out.println("Hello CoCo World!");
    }

cron ์‚ฌ์šฉ ์˜ˆ์‹œ

    // ๋งค์ผ ์˜คํ›„ 18์‹œ์— ์‹คํ–‰
    @Scheduled(cron = "0 0 18 * * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค๋‹ฌ 10์ผ,20์ผ 14์‹œ์— ์‹คํ–‰
    @Scheduled(cron = "0 0 14 10,20 * ?")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค๋‹ฌ ๋งˆ์ง€๋ง‰๋‚  22์‹œ์— ์‹คํ–‰
    @Scheduled(cron = "0 0 22 L * ?")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // 1์‹œ๊ฐ„ ๋งˆ๋‹ค ์‹คํ–‰ ex) 01:00, 02:00, 03:00 ...
    @Scheduled(cron = "0 0 0/1 * * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค์ผ 9์‹œ00๋ถ„-9์‹œ55๋ถ„, 18์‹œ00๋ถ„-18์‹œ55๋ถ„ ์‚ฌ์ด์— 5๋ถ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์‹คํ–‰
    @Scheduled(cron = "0 0/5 9,18 * * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค์ผ 9์‹œ00๋ถ„-18์‹œ55๋ถ„ ์‚ฌ์ด์— 5๋ถ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์‹คํ–‰
    @Scheduled(cron = "0 0/5 9-18 * * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค๋‹ฌ 1์ผ 10์‹œ30๋ถ„์— ์‹คํ–‰
    @Scheduled(cron = "0 30 10 1 * *")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค๋…„ 3์›”๋‚ด ์›”-๊ธˆ 10์‹œ30๋ถ„์— ์‹คํ–‰
    @Scheduled(cron = "0 30 10 ? 3 1-5")
    public void run() {
        System.out.println("Hello CoCo World!");
    }
    
    // ๋งค๋‹ฌ ๋งˆ์ง€๋ง‰ ํ† ์š”์ผ 10์‹œ30๋ถ„์— ์‹คํ–‰
    @Scheduled(cron = "0 30 10 ? * 6L")
    public void run() {
        System.out.println("Hello CoCo World!");
    }

์ถœ์ฒ˜ : https://dev-coco.tistory.com/176

์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'Web & Android > SpringBoot' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[SpringBoot] REST API  (0) 2023.10.13
[SpringBoot] Bean  (0) 2023.10.13
[SpringBoot] Google ์ด๋ฉ”์ผ ์ธ์ฆ  (0) 2023.09.12
[SpringBoot] Lombok  (1) 2023.08.18
[SpringBoot] HTTP form์—์„œ put, delete ์‚ฌ์šฉ๋ฒ•  (0) 2023.08.17
'Web & Android/SpringBoot' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [SpringBoot] REST API
  • [SpringBoot] Bean
  • [SpringBoot] Google ์ด๋ฉ”์ผ ์ธ์ฆ
  • [SpringBoot] Lombok
woojin._.
woojin._.
์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ฐœ๋ฐœ์„ ํ•ด๋ณด๋ฉฐ ๋ฐœ์ƒํ•˜๋Š” ์ด์•ผ๊ธฐ๋“ค์— ๋Œ€ํ•œ ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค:)
  • woojin._.
    Jin's Dev Story
    woojin._.
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (829)
      • Tools (25)
        • eGovFrame (3)
        • GeoServer (3)
        • QGIS (2)
        • LabelImg (2)
        • Git (6)
        • GitHub (1)
        • Eclipse (7)
        • Visual Studio (1)
      • Web & Android (121)
        • SpringBoot (37)
        • Three.js (2)
        • Spring Data JPA (9)
        • ์Šคํ”„๋ง ๋ถ€ํŠธ ์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ with JPA (25)
        • Thymeleaf (4)
        • Spring Security (15)
        • Flutter (29)
      • Programming Language (61)
        • JAVA (27)
        • JavaScript (14)
        • Dart (2)
        • Python (15)
        • PHP (3)
      • Database (43)
        • PostgreSQL (32)
        • MYSQL (7)
        • Oracle (3)
        • MSSQL (1)
      • SERVER (17)
        • TCP_IP (3)
        • ๋ฆฌ๋ˆ…์Šค (7)
        • AWS (7)
      • Coding Test (445)
        • ๋ฐฑ์ค€[JAVA] (108)
        • ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค[JAVA] (260)
        • ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ณ ๋“์  Kit[JAVA] (3)
        • SQL ๊ณ ๋“์  Kit[ORACLE] (74)
      • CS ์ง€์‹ (49)
        • [์ž๋ฃŒ๊ตฌ์กฐ] (14)
        • [๋„คํŠธ์›Œํฌ] (12)
        • [๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค] (10)
        • [์•Œ๊ณ ๋ฆฌ์ฆ˜] (9)
        • [์šด์˜์ฒด์ œ] (4)
      • ๊ธฐํƒ€ (6)
      • ์ž๊ฒฉ์ฆ & ๊ณต๋ถ€ (62)
        • ์ •๋ณด์ฒ˜๋ฆฌ๊ธฐ์‚ฌ (2)
        • SQLD (6)
        • ๋„คํŠธ์›Œํฌ๊ด€๋ฆฌ์‚ฌ 2๊ธ‰ (5)
        • ๋ฆฌ๋ˆ…์Šค๋งˆ์Šคํ„ฐ 1๊ธ‰ (44)
        • ๋ฆฌ๋ˆ…์Šค๋งˆ์Šคํ„ฐ 2๊ธ‰ (1)
        • ISTQB (3)
        • ์‹œ์Šคํ…œ๋ณด์•ˆ (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    CS
    ๋ฆฌ๋ˆ…์Šค
    springboot
    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
    Java
    Spring Security
    pcce ๊ธฐ์ถœ๋ฌธ์ œ
    ๋ฐ์ดํ„ฐ
    JPA
    ๋ฆฌ๋ˆ…์Šค๋งˆ์Šคํ„ฐ
    backjoon
    ์ž๋ฐ”
    Linux
    Flutter
    postgresql
    ์Šคํ”„๋ง
    ์‹œํ๋ฆฌํ‹ฐ
    ์Šคํ”„๋ง๋ถ€ํŠธ
    baekjoon
    ๋ฆฌ๋ˆ…์Šค๋งˆ์Šคํ„ฐ 1๊ธ‰
    CS์ง€์‹
    ์Šคํ”„๋ง ๋ถ€ํŠธ ์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ with JPA
    spring
    Oracle
    ํ”Œ๋Ÿฌํ„ฐ
    DB
    programmers
    python
    ๋ฐฑ์ค€
  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
woojin._.
[SpringBoot] ์Šค์ผ€์ค„๋ง
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”