

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 適用於 Java AWS Flow Framework 的 疑難排解和偵錯秘訣
<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)

本節說明使用 AWS Flow Framework for Java 開發工作流程時，您可能會遇到的一些常見陷阱。本節也會提供一些提示，協助您診斷和偵錯問題。

## 編譯錯誤
<a name="troubleshooting.compilation"></a>

如果您使用 AspectJ 編譯時間縈繞選項，則可能會發生編譯時間錯誤，在這類錯誤中，編譯器找不到針對工作流程和活動所產生的用戶端類別。這類編譯錯誤的可能原因在於 AspectJ 建置器會在編譯期間忽略已產生的用戶端。您可以移除專案中的 AspectJ 功能並重新予以啟用，以修復此問題。請注意，每次工作流程或活動界面變更時，您都需要執行這項作業。有鑑於此問題，建議您改為使用載入時間縈繞選項。如需詳細資訊，請參閱「[設定 AWS Flow Framework 適用於 Java 的](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 未正確設定。如需詳細資訊，請參閱「[設定 AWS Flow Framework 適用於 Java 的](setup.md)」一節。

## 非確定性工作流程
<a name="troubleshooting.NonDeterministicWorkflows"></a>

如「[不確定性](details.md#details.non)」一節所述，您工作流程的實作必須具有確定性。可能導致非確定性的一些常見錯誤為使用系統時鐘、使用亂數，以及產生 GUID。由於這些建構可能會在不同的時間傳回不同的值，因此每次執行工作流程時，工作流程的控制流程可能會採用不同的路徑 ([AWS Flow Framework 基本概念：分散式執行](awsflow-basics-distributed-execution.md)[了解 AWS Flow Framework 適用於 Java 的 中的任務](details.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` 事件包含已收到任務的工作流程工作者的身分。Flow Framework 使用的 ID 格式為：\$1*processId*\$1`@`\$1*host name*\$1。例如，以下是 Amazon SWF 主控台中執行範例`DecisionTaskStarted`的事件詳細資訊：


****  

|  |  | 
| --- |--- |
|   事件時間戳記   |   Mon Feb 20 11:52:40 GMT-800 2012   | 
|   Identity   |   2276@ip-0A6C1DF5   | 
|   排程事件 ID   |   33   | 

為了避免此情況，請為每個測試使用不同的任務清單。另外，請考慮新增關閉舊工作者與啟動新工作者之間的延遲。

## 由於 API 參數長度限制導致驗證失敗
<a name="troubleshooting.validation-fail"></a>

Amazon SWF 會對 API 參數強制執行長度限制。如果您的工作流程或活動實作超過限制，您將會收到`HTTP 400`錯誤。例如，當呼叫 `recordActivityHeartbeat` `ActivityExecutionContext`來傳送執行中活動的活動訊號時，字串長度不得超過 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 錯誤。若要緩解這種情況，您可以截斷例外狀況訊息或原因以符合長度限制。