2017-11-19 6 views
0

나는 루프초 (아마도 약 0.5 초 또는 1 초 정도가 될 것입니다.)를 실행하고 있습니다. 나는 대략 5n 초마다 발생하는 또 다른 작업 B를 가지고 있지만이 작업은 완전히 별개의 환경과 서버에서 발생합니다.어떻게 NTP/인터럽트가 타이머에 영향을 줍니까?

작업 A가 작업 B가 발생하는 시간 간격에 적어도 한 번 발생해야합니다. 그러나 다음과 같은 경우에 걱정이됩니다.

  • NTP 조정으로 어느 서버에서든 시간이 엉망입니다.
  • 인터럽트 또는 GC가 실행 중이고 태스크 A가 느려지고 실행이 지연됩니다.

이러한 잠재적 인 장애 지점을 해결할 방법이 있습니까?

이들은 Java로 구현 될 예정이지만 상당히 독립적 인 언어라고 생각합니다.

+0

B가 실행되지 않고 두 번 실행되지 않는 것이 얼마나 중요합니까? 작업이 트랜잭션 방식으로 실행되도록 조정 서비스가 없어도이를 보장 할 수있는 방법을 상상할 수 없습니다. – teppic

답변

0

조정 서비스를 사용하지 않고 작업 A가 실행되지 않으면 작업 B가 실행되지 않을 수 있습니다. 클록 스큐 (clock skew) 및 프로세스 정지 문제 이외에도 다른 문제가 발생할 수 있습니다. 하드웨어/자원 오류로 인해 작업 A가 실패하면 어떻게됩니까? 서비스 재시작은 어떻게됩니까?

가장 간단한 해결 방법은 작업 B가 작업 A가 실행되지 않은 경우를 허용하는 것입니다. 할 수 없다면 작업 A의 상태를 추적하는 서비스를 제공해야합니다. 구현하는 가장 가벼운 방법은 실행하기 전에 고유 한 ID로 각 A를 실행하고 B를 실행하기 전에 확인하는 것입니다.

같은

뭔가 :

public class TaskA implements Runnable { 
    @Resource 
    private TaskService taskService; 

    @Override 
    public void run() { 
     // Run task A 
     // ... 

     // Set run ID for task B to retrieve 
     taskService.setRunId("A", UUID.randomUUID().toString()); 
    } 
} 

public class TaskB implements Runnable { 
    private static final Logger log = LoggerFactory.getLogger(TaskB.class); 

    @Resource 
    private TaskService taskService; 

    private String lastId; 

    @Override 
    public void run() { 
     String nextId = taskService.getRunId("A"); 
     if (this.lastId == null) { 
      log.info("First run. Not executing"); 
     } else if (lastId.equals(nextId)) { 
      log.warn("Task A has not run. Refusing to execute"); 
     } else { 
      log.info("Executing"); 
      // Run task B 
      // ... 
     } 
     this.lastId = nextId; 
    } 
} 

나는 고유 ID를 보장하는 영구 저장소의 필요성을 방지하기 위해 위의 예제에서 UUID를 사용했습니다. 환경에 데이터베이스가 있으면 데이터베이스를 사용할 수 있습니다. 난 당신이 지적한 이유 (시계 왜곡 등)에 대한 타임 스탬프의 사용을 피하고 싶습니다.

관련 문제