

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# AWS Flow Framework for Java에 대한 문제 해결 및 디버깅 팁
<a name="troubleshooting"></a>

**Topics**
+ [컴파일 오류](#troubleshooting.compilation)
+ [알 수 없는 리소스 장애](#troubleshooting.UnknownResourceFault)
+ [Promise에서 get()를 호출할 때의 예외](#troubleshooting.ExceptionsCallingGet)
+ [비결정적 워크플로](#troubleshooting.NonDeterministicWorkflows)
+ [버전 관리로 인한 문제](#troubleshooting.Versioning)
+ [워크플로 실행 문제 해결 및 디버깅](#troubleshooting.DebuggingWorkflowExecution)
+ [손실된 작업](#troubleshooting.LostTasks)
+ [API 파라미터 길이 제약으로 인한 검증 실패](#troubleshooting.validation-fail)

이 섹션에서는 Java AWS Flow Framework 용를 사용하여 워크플로를 개발하는 동안 발생할 수 있는 몇 가지 일반적인 위험에 대해 설명합니다. 또한 문제를 진단하고 디버깅하는 데 도움이 되는 팁도 제공합니다.

## 컴파일 오류
<a name="troubleshooting.compilation"></a>

AspectJ 컴파일 시간 위빙 옵션을 사용 중이라면 컴파일러가 워크플로 및 활동에서 생성된 클라이언트 클래스를 찾지 못하는 컴파일 시간 오류를 겪을 수 있습니다. 이러한 컴파일 오류는 컴파일 도중 AspectJ 빌더에서 생성된 클라이언트를 무시하는 경우가 원인인 경우가 많습니다. 사용자는 프로젝트에서 AspectJ 기능을 제거했다가 다시 활성화하는 방법으로 이 문제를 해결할 수 있습니다. 워크플로 또는 활동 인터페이스가 변경될 때마다 이 작업을 해주어야 한다는 점에 유의하십시오. 이러한 번거로움 때문에 이 방법 대신 로드 시간 위빙 옵션을 사용하는 것이 좋습니다. 자세한 내용은 [Java AWS Flow Framework 용 설정](setup.md) 단원을 참조하십시오.

## 알 수 없는 리소스 장애
<a name="troubleshooting.UnknownResourceFault"></a>

Amazon SWF는 사용자가 사용할 수 없는 리소스에 대해 작업을 수행하려 할 때 알 수 없는 리소스 장애를 반환합니다. 이 장애의 흔한 원인은 다음과 같습니다.
+ 사용자가 존재하지 않는 도메인을 사용해 작업자를 구성하기 때문입니다. 이를 수정하려면 먼저 [Amazon SWF 콘솔](https://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-register-domain-console.html) 또는 [Amazon SWF 서비스 API](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RegisterDomain.html)를 사용하여 도메인을 등록합니다.
+ 사용자가 등록되지 않은 유형의 워크플로 실행 또는 활동 작업을 생성하려 하기 때문입니다. 이러한 장애는 작업자가 실행되기 전에 사용자가 워크플로 실행을 생성하려 하는 경우 발생할 수 있습니다. 작업자는 처음으로 실행될 때 유형을 등록하므로 실행을 시작하기 전에 한 번 이상 실행해야 합니다(또는 콘솔 또는 서비스 API를 사용하여 유형을 수동으로 등록해야 함). 유형이 등록되면 사용자는 실행 중인 작업자가 없더라도 실행을 생성할 수 있습니다.
+ 작업자가 이미 제한 시간을 초과한 작업을 완료하려 하기 때문입니다. 예를 들어 작업자가 작업을 처리하는 데 시간이 너무 많이 걸려 제한 시간을 초과하는 경우 작업자는 이 작업을 완료 또는 실패 처리하려 할 때 UnknownResource 장애를 받습니다. AWS Flow Framework 작업자는 Amazon SWF를 계속 폴링하고 추가 작업을 처리합니다. 그러나 제한 시간 조정을 고려해야 합니다. 제한 시간을 조정하려면 새 버전의 활동 유형을 등록해야 합니다.

## Promise에서 get()를 호출할 때의 예외
<a name="troubleshooting.ExceptionsCallingGet"></a>

Java Future와 달리 `Promise`는 비차단형 구성으로서, 아직 준비 상태가 아닌 `Promise`에서 `get()`을 호출하면 차단하는 대신 예외를 발생시킵니다. 올바른 `Promise` 사용 방법은 이를 비동기식 메서드(또는 작업)에 전달하고 비동기식 메서드에 있는 값에 액세스하는 것입니다. AWS Flow Framework for Java에서는 비동기식 메서드가 이에 전달된 모든 `Promise` 인수가 준비 상태가 된 경우에만 직접적으로 호출되도록 합니다. 코드가 정확하다고 생각되거나 AWS Flow Framework 샘플 중 하나를 실행하는 동안이 오류가 발생하면 AspectJ가 제대로 구성되지 않았기 때문일 가능성이 높습니다. 자세한 내용은 [Java AWS Flow Framework 용 설정](setup.md) 단원을 참조하십시오.

## 비결정적 워크플로
<a name="troubleshooting.NonDeterministicWorkflows"></a>

[불확정성](details.md#details.non) 단원에서 설명한 것처럼 워크플로의 구현은 확정적이어야 합니다. 불확정성으로 이어질 수 있는 흔한 실수로는 시스템 클록 사용, 임의 숫자 사용 및 GUID 생성이 있습니다. 이러한 구문은 서로 다른 시간에 서로 다른 값을 반환할 수 있으므로 워크플로의 제어 흐름은 실행될 때마다 서로 다른 경로를 취할 수 있습니다([Java AWS Flow Framework 용의 작업 이해](details.md)자세한 내용은 섹션 [AWS Flow Framework 기본 개념: 분산 실행](awsflow-basics-distributed-execution.md) 및 참조). 프레임워크에서 워크플로 실행 중에 불확정성을 감지하면 예외가 발생합니다.

## 버전 관리로 인한 문제
<a name="troubleshooting.Versioning"></a>

새 버전의 워크플로 또는 활동을 구현하는 경우(예: 새 기능을 추가할 때) `@Workflow`, `@Activites` 또는 `@Activity`과 같은 적절한 주석을 사용하여 유형의 버전을 증가 시켜야 합니다. 새 버전의 워크플로가 배포되면 이미 실행 중인 기존 버전의 실행을 보유하게 되는 경우가 많습니다. 따라서 적절한 버전의 워크플로 및 활동을 지닌 작업자가 작업을 받도록 해야 합니다. 이렇게 하려면 각 버전에 다른 작업 목록 세트를 사용하면 됩니다. 예를 들어 작업 목록의 이름에 버전 번호를 추가할 수 있습니다. 이렇게 하면 서로 다른 버전의 워크플로 및 활동에 속하는 작업이 적절한 작업자에게 할당됩니다.

## 워크플로 실행 문제 해결 및 디버깅
<a name="troubleshooting.DebuggingWorkflowExecution"></a>

워크플로 실행과 관련된 문제를 해결하는 첫 번째 단계는 Amazon SWF 콘솔을 사용하여 워크플로 내역을 검색하는 것입니다. 워크플로 내역은 워크플로 실행의 실행 상태를 변경한 모든 이벤트에 대한 완전하고 신뢰할 수 있는 기록입니다. 이 내역은 Amazon SWF에서 유지 관리하며 문제를 진단하는 데 중요한 역할을 합니다. Amazon SWF 콘솔을 통해 사용자는 워크플로 실행을 검색하고 개별 내역 이벤트로 드릴다운할 수 있습니다.

AWS Flow Framework 는 워크플로 실행을 로컬에서 재생하고 디버깅하는 데 사용할 수 있는 `WorkflowReplayer` 클래스를 제공합니다. 사용자는 이 클래스를 사용하여 종료되었거나 실행 중인 워크플로 실행을 디버깅할 수 있습니다. `WorkflowReplayer`에서는 Amazon SWF에 저장된 내역에 의존하여 다시 재생을 수행합니다. 사용자는 자신의 Amazon SWF 계정에서 워크플로 실행을 가리키도록 하거나 내역 이벤트를 제공합니다(예: Amazon SWF에서 내역을 가져와 이를 나중에 사용할 수 있도록 로컬에서 직렬화할 수 있습니다). `WorkflowReplayer`를 사용하여 워크플로 실행을 다시 재생하면 사용자의 계정에서 실행 중인 워크플로 실행에 영향을 미치지 않습니다. 다시 재생은 클라이언트 상에서 완료됩니다. 사용자는 평상시와 같이 디버깅 도구를 사용하여 워크플로를 디버깅하고 중단점을 생성하며 코드를 한 단계씩 실행할 수 있습니다. Eclipse를 사용하는 경우 AWS Flow Framework 패키지 필터링에 단계 필터를 추가하는 것이 좋습니다.

예를 들어 다음 코드 조각은 워크플로 실행을 다시 재생하는 데 사용할 수 있습니다.

```
String workflowId = "testWorkflow";
String runId = "<run id>";
Class<HelloWorldImpl> workflowImplementationType = HelloWorldImpl.class;
WorkflowExecution workflowExecution = new WorkflowExecution();
workflowExecution.setWorkflowId(workflowId);
workflowExecution.setRunId(runId);

WorkflowReplayer<HelloWorldImpl> replayer = new WorkflowReplayer<HelloWorldImpl>(
    swfService, domain, workflowExecution, workflowImplementationType);

System.out.println("Beginning workflow replay for " + workflowExecution);
Object workflow = replayer.loadWorkflow();
System.out.println("Workflow implementation object:");
System.out.println(workflow);
System.out.println("Done workflow replay for " + workflowExecution);
```

 AWS Flow Framework 를 사용하면 워크플로 실행의 비동기 스레드 덤프를 가져올 수도 있습니다. 이 스레드 덤프에서는 사용자에게 모든 개방 비동기 작업의 호출 스택을 부여합니다. 이 정보는 실행에서 어떤 작업이 보류 중이고 멈춰 있을 수 있는지 판별하는 데 유용할 수 있습니다. 예제:

```
String workflowId = "testWorkflow";
String runId = "<run id>";
Class<HelloWorldImpl> workflowImplementationType = HelloWorldImpl.class;
WorkflowExecution workflowExecution = new WorkflowExecution();
workflowExecution.setWorkflowId(workflowId);
workflowExecution.setRunId(runId);

WorkflowReplayer<HelloWorldImpl> replayer = new WorkflowReplayer<HelloWorldImpl>(
    swfService, domain, workflowExecution, workflowImplementationType);

try {
    String flowThreadDump = replayer.getAsynchronousThreadDumpAsString();
    System.out.println("Workflow asynchronous thread dump:");
    System.out.println(flowThreadDump);
}
catch (WorkflowException e) {
    System.out.println("No asynchronous thread dump available as workflow has failed: " + e);
}
```

## 손실된 작업
<a name="troubleshooting.LostTasks"></a>

때로 작업자를 종료하고 이어서 재빨리 새 작업자를 시작했는데 해당 작업이 이전 작업자에게 전달되어버리는 경우가 있을 수 있습니다. 이러한 장애는 몇 가지 프로세스에 분산되어 있는 시스템의 경합 조건으로 인해 발생할 수 있습니다. 이 문제는 긴밀한 루프에서 단위 테스트를 실행하는 경우 생길 수도 있습니다. Eclipse에서 테스트를 중단하는 것 역시 때로 이 문제의 원인일 수 있는데, 그 이유는 종료 핸들러가 호출되지 않을 수 있기 때문입니다.

문제가 사실은 작업을 받는 이전 작업자로 인한 것인지 확인하려면 워크플로 내역을 검토하여 새 작업자가 수신하기를 기대한 작업을 어떤 프로세스에서 수신했는지 판별해야 합니다. 예를 들어 내역의 `DecisionTaskStarted` 이벤트에는 작업을 수신한 워크플로 작업자의 ID가 들어 있습니다. Flow Framework에서 사용하는 ID의 형식은 \$1*processId*\$1`@`\$1*호스트 이름*\$1입니다. 예를 들어 다음은 샘플 실행에 대한 Amazon SWF 콘솔 내 `DecisionTaskStarted` 이벤트에 관한 세부 정보입니다.


****  

|  |  | 
| --- |--- |
|   이벤트 타임스탬프   |   Mon Feb 20 11:52:40 GMT-800 2012   | 
|   ID   |   2276@ip-0A6C1DF5   | 
|   예약된 이벤트 Id   |   33   | 

이러한 상황을 방지하려면 각 테스트에 대해 서로 다른 작업 목록을 사용하십시오. 또한 이전 작업자 종료와 새 작업자 시작 사이에 지연을 추가하는 것을 고려하십시오.

## API 파라미터 길이 제약으로 인한 검증 실패
<a name="troubleshooting.validation-fail"></a>

Amazon SWF는 API 파라미터에 길이 제약을 적용합니다. 워크플로 또는 활동 구현이 제약 조건을 초과하면 `HTTP 400` 오류가 발생합니다. 예를 들어 실행 중인 활동에 대한 하트비트를 전송`ActivityExecutionContext`하기 위해 `recordActivityHeartbeat`를 호출할 때 문자열은 2048자를 초과해서는 안 됩니다.

또 다른 일반적인 시나리오는 예외로 인해 활동이 실패하는 경우입니다. 프레임워크는 직렬화된 예외를 세부 정보로 [https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskFailed.html](https://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondActivityTaskFailed.html) 사용하여를 호출하여 Amazon SWF에 활동 실패를 보고합니다. 직렬화된 예외의 길이가 32,768바이트를 초과하는 경우 API 호출은 400 오류를 보고합니다. 이 상황을 완화하기 위해 예외 메시지 또는 원인이 길이 제약 조건을 준수하도록 자를 수 있습니다.