Step Functions 的最佳做法 - AWS Step Functions

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

Step Functions 的最佳做法

下列主題是協助您管理和最佳化 Step Functions 工作流程的最佳作法。

使用快速工作流程最佳化

Step Functions 會根據您用來建置狀態機器的工作流程類型來決定標準和快速工作流程的定價。若要最佳化無伺服器工作流程的成本,您可以遵循下列其中一項或兩項建議:

如需有關選擇「標準」或「快速」工作流程類型如何影響帳單的資訊,AWS Step Functions 定價

標準工作流程中的巢狀快速工

Step Functions 會執行具有有限持續時間和步驟數目的工作流程。某些工作流程可能會在短時間內完成執行。其他人可能需要長時間執行和 high-event-rate 工作流程的組合。使用 Step Functions,您可以從多個較小、更簡單的工作流程中建立大型、複雜的工作流程。

例如,若要建立訂單處理工作流程,您可以將所有非冪等作業納入「標準」工作流程中。這可能包括操作,例如通過人工互動批准訂單和處理付款。然後,您可以在 Express 工作流程中結合一系列冪等動作,例如傳送付款通知和更新產品庫存。您可以在「標準」工作流程中嵌套此 Express 工作流程。在此範例中,「標準」工作流程稱為父狀態機器。巢狀 Express 工作流程稱為子狀態機器

將標準工作流程轉換為快速工

如果現有的「標準」工作流程符合下列需求,您可以將它們轉換為 Express 工作流程:

  • 工作流程必須在五分鐘內完成其執行。

  • 工作流程符合at-least-once執行模型。這表示工作流程中的每個步驟可能會執行一次以上。

  • 工作流程不使用.waitForTaskToken.sync服務整合模式。

重要

快速工作流程使用 Amazon CloudWatch 日誌記錄執行歷史記錄。使用 CloudWatch 記錄時會產生額外費用。

若要使用主控台將標準工作流程轉換為 Express 工作流程
  1. 開啟「Step Functions」主控台

  2. 在 [狀態電腦] 頁面上,選擇 [標準類型狀態機器] 以開啟它。

    提示

    從 [任何類型] 下拉式清單中,選擇 [標準] 篩選狀態機器清單,並僅檢視 [標準] 工作流程。

  3. 選擇「複製到新的」。

    工作流 Studio 會在設計模式顯示所選狀態機的工作流程中開啟。

  4. (選擇性) 更新工作流程設計。

  5. 指定狀態機的名稱。若要執行此操作,請選擇的預設狀態機器名稱旁邊的編輯圖示MyStateMachine。然後,在 [狀態機器組態] 中,在 [狀態機器名稱] 方塊中指定名稱

  6. (選擇性) 在狀態機器組態中,指定其他工作流程設定,例如狀態機器類型及其執行角色。

    請確定針對「類型」選擇「快速」。保留狀態機器設定上的所有其他預設選項。

    注意

    如果您要轉換先前在中定義的標準工作流程 AWS CDK 或 AWS SAM,您必須變更的值TypeResource名稱。

  7. 在 [確認角色建立] 對話方塊中,選擇 [確認] 以繼續。

    您也可以選擇 [檢視角色設定] 以返回 [狀態機器組態]。

    注意

    如果刪除 Step Functions 所建立的IAM角色,則 Step Functions 稍後無法重新建立。同樣地,如果您修改角色 (例如,從原則中的主參與者中移除 Step Functions),IAM則 Step Functions 稍後無法還原其原始設定。

如需管理工作流程成本最佳化時的最佳做法和指導方針的詳細資訊,請參閱建立符合成本效益 AWS Step Functions 工作流程

在 Step Functions 中標記狀態機和活動

AWS Step Functions 支持標記狀態機(標準和快速)和活動。標籤可以幫助您跟踪和管理您的資源,並提供更好的安全性 AWS Identity and Access Management (IAM) 政策。標記 Step Functions 資源後,您可以使用 AWS Resource Groups。 若要瞭解如何操作,請參閱 AWS Resource Groups 使用者指南

對於以標籤為基礎的授權,如下列範例所示的狀態機器執行資源會繼承與狀態機器相關聯的標籤。

arn:<partition>:states:<Region>:<account-id>:execution:<StateMachineName>:<ExecutionId>

當您呼叫DescribeExecution或其他指定執行資源時ARN,Step Functions 會APIs在執行以標籤為基礎的授權時,使用與狀態機器相關聯的標籤來接受或拒絕要求。這可協助您在狀態機器層級允許或拒絕存取狀態機器執行。

若要查看資源標記的相關限制,請參閱 與標記相關的限制

進行標記以分配成本

您可以使用成本分配標籤來識別狀態機器的用途,並在您的組織中反映該組織 AWS 法案。註冊以取得您的 AWS 帳戶賬單包括標籤鍵和值。請參閱「設定每月成本分配報告AWS Billing 使用者指南,瞭解設定報告的詳細資訊。

例如,您可以新增代表您的成本中心和 Step Functions 資源用途的標籤,如下所示。

資源 金鑰
StateMachine1 Cost Center 34567
Application Image processing
StateMachine2 Cost Center 34567
Application Rekognition processing

針對安全進行標記

IAM支持基於標籤控制對資源的訪問。若要根據標籤控制存取,請在IAM策略的條件元素中提供有關資源標籤的資訊。

例如,您可以限制所有 Step Functions 資源的存取權,這些資源包含含索引鍵environment和值的標籤production

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "states:TagResource", "states:DeleteActivity", "states:DeleteStateMachine", "states:StopExecution" ], "Resource": "*", "Condition": { "StringEquals": {"aws:ResourceTag/environment": "production"} } } ] }

若要IAM取得更多資訊,請參閱使用指南中的〈使用標籤控制存取〉。

在 Step Functions 主控台中管理標籤

您可以在 Step Functions 主控台中檢視和管理狀態機器的標籤。從狀態機器的 Details (詳細資訊) 頁面,選擇 Tags (標籤)

使用 Step Fun API ctions 動作管理標籤

欲使用 Step Functions 管理標籤API,請使用下列API動作:

使用逾時來避免卡住的 Step Functions 工作流程執行

根據預設,Amazon 州語言不會指定狀態機器定義的逾時。如果沒有明確的逾時,Step Functions 通常僅依賴活動工作者的回應來知道任務已完成。如果出現錯誤,並且未為ActivityTask狀態指定TimeoutSeconds欄位,執行就會卡住,等待永遠不會出現的回應。

為了避免這種情況,請在狀態機器中創建時指定合理Task的超時時間。例如:

"ActivityState": { "Type": "Task", "Resource": "arn:aws:states:us-east-1:123456789012:activity:HelloWorld", "TimeoutSeconds": 300, "Next": "NextState" }

如果您使用帶有任務令牌的回調(. waitForTaskToken),我們建議您使用活動訊號,並在Task狀態定義中新增HeartbeatSeconds欄位。您可以設定HeartbeatSeconds為小於工作逾時,所以如果您的工作流程因活動訊號錯誤而失敗,您就會知道這是因為工作失敗,而不是工作需要很長時間才能完成。

{ "StartAt": "Push to SQS", "States": { "Push to SQS": { "Type": "Task", "Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken", "HeartbeatSeconds": 600, "Parameters": { "MessageBody": { "myTaskToken.$": "$$.Task.Token" }, "QueueUrl": "https://sqs.us-east-1.amazonaws.com/123456789012/push-based-queue" }, "ResultPath": "$.SQS", "End": true } } }

如需詳細資訊,請參閱 Amazon 州語言文件工作流程狀態中的。

注意

您可以使用 Amazon States 語言定義中的TimeoutSeconds欄位,為狀態機器設定逾時。如需詳細資訊,請參閱Step Functions 工作流程的 Amazon 狀態機器結構語言

使用 Amazon S3 ARNs 而不是在 Step Functions 中傳遞大型有效載荷

在狀態之間傳遞大型資料承載的執行作業可能會被終止。如果您在狀態之間傳遞的資料可能會增長到超過 256 KB,請使用 Amazon Simple Storage Service (Amazon S3) 存放資料,然後剖析Payload參數中儲存貯體的 Amazon 資源名稱 (ARN) 以取得儲存貯體名稱和金鑰值。或者,調整您的實作,以便在您的執行作業中傳遞較小的承載。

在下面的例子中,狀態機將輸入傳遞給 AWS Lambda 功能,該功能處理 Amazon S3 存儲桶中的JSON文件。執行此狀態機器之後,Lambda 函數會讀取JSON檔案的內容,並傳回檔案內容做為輸出。

建立 Lambda 函式

下列名為的 Lambda 函數pass-large-payload會讀取儲存在特定 Amazon S3 儲存貯體中的JSON檔案內容。

注意

建立此 Lambda 函數後,請確保提供其IAM角色適當的權限,以便從 Amazon S3 儲存貯體讀取。例如,將亞馬遜 S3 ReadOnlyAccess 權限附加到 Lambda 函數的角色。

import json import boto3 import io import os s3 = boto3.client('s3') def lambda_handler(event, context): event = event['Input'] final_json = str() s3 = boto3.resource('s3') bucket = event['bucket'].split(':')[-1] filename = event['key'] directory = "/tmp/{}".format(filename) s3.Bucket(bucket).download_file(filename, directory) with open(directory, "r") as jsonfile: final_json = json.load(jsonfile) os.popen("rm -rf /tmp") return final_json
建立狀態機

下列狀態機會叫用您先前建立的 Lambda 函數。

{ "StartAt":"Invoke Lambda function", "States":{ "Invoke Lambda function":{ "Type":"Task", "Resource":"arn:aws:states:::lambda:invoke", "Parameters":{ "FunctionName":"arn:aws:lambda:us-east-2:123456789012:function:pass-large-payload", "Payload":{ "Input.$":"$" } }, "OutputPath": "$.Payload", "End":true } } }

您可以將資料儲存在 Amazon S3 儲存貯體中,然後在Payload參數中傳遞儲存貯體的 Amazon 資源名稱 (ARN) 以取得儲存貯體名稱和金鑰值,而不是在輸入中傳遞大量資料。然後,您的 Lambda 函數可以使ARN用它直接訪問數據。以下是狀態機器執行的範例輸入,其中資料存放data.json在名為的 Amazon S3 儲存貯體中amzn-s3-demo-large-payload-json

{ "key": "data.json", "bucket": "arn:aws:s3:::amzn-s3-demo-large-payload-json" }

開始新的執行,以避免達到 Step Functions 中的歷史配額

AWS Step Functions 在執行事件歷史記錄中有 25,000 個項目的硬配額。當執行達到 24,999 個事件時,它會等待下一個事件發生。

  • 如果事件編號 25,000 為ExecutionSucceeded,則執行成功完成。

  • 如果事件編號 25,000 不是ExecutionSucceeded,則會記錄ExecutionFailed事件,並且狀態機器執行失敗,因為達到歷史記錄限制

若要避免長時間執行的執行達到此配額,您可以嘗試下列其中一種因應措施:

處理暫態 Lambda 服務例外

AWS Lambda 偶爾會遇到暫時性的服務錯誤。在此情況下,呼叫 Lambda 會導致 500 個錯誤,例如ClientExecutionTimeoutExceptionServiceExceptionAWSLambdaException、或SdkClientException。最佳做法是在狀態機器中主動處理這些例外狀況,以Retry叫用 Lambda 函數或錯誤。Catch

Lambda 錯誤報告為Lambda.ErrorName。若要重試 Lambda 服務例外狀況錯誤,您可以使用下列Retry程式碼。

"Retry": [ { "ErrorEquals": [ "Lambda.ClientExecutionTimeoutException", "Lambda.ServiceException", "Lambda.AWSLambdaException", "Lambda.SdkClientException"], "IntervalSeconds": 2, "MaxAttempts": 6, "BackoffRate": 2 } ]
注意

Lambda 中未處理的錯誤會報告為錯誤輸出Lambda.Unknown中。這些包括 out-of-memory 錯誤和功能超時。您可以比對Lambda.UnknownStates.ALL、或States.TaskFailed來處理這些錯誤。當 Lambda 達到調用的最大數量時,錯誤為。Lambda.TooManyRequestsException如需 Lambda HandledUnhandled錯誤的詳細資訊,請參閱FunctionError中的 AWS Lambda 開發人員指南

如需詳細資訊,請參閱下列內容:

輪詢活動任務時避免延遲

GetActivityTaskAPI旨在提供taskToken一次性。如果 taskToken 在與活動工作者通訊時遺失,可以封鎖數個 GetActivityTask 請求 60 秒來等待回應,直到 GetActivityTask 逾時為止。

如果您只有少量輪詢在等待回應,則所有請求可能都會排在封鎖的請求後面並且停止。但是,如果您對每個活動 Amazon Resource Name (ARN) 都有大量未完成的民意調查,並且某些比例的請求被卡住了等待,那麼還有更多可以獲得taskToken並開始處理工作。

對於生產系統,我們建議每個活動ARN在每個時間點至少 100 次公開投票。如果有一個輪詢遭到封鎖,而且有一部分的輪詢排在其後面,則有更多請求仍會收到 GetActivityTask 以在 taskToken 請求遭到封鎖時處理工作。

若要在輪詢任務時避免這幾種延遲問題:

  • 在您的活動工作者實作中,以個別的執行緒實作您的輪詢器。

  • 在每個時間點,每個活動ARN至少有 100 次公開投票。

    注意

    擴展到每 100 個開放式民意調查ARN可能很昂貴。例如,每個 100 個 Lambda 函數輪詢ARN的成本比具有 100 個輪詢執行緒的單一 Lambda 函數高 100 倍。若要降低延遲將成本降至最低,請使用具有非同步 I/O 的語言,然後針對每個工作人員實作多個輪詢執行緒。如需輪詢器執行緒與工作執行緒不同的範例活動工作者,請參閱 範例:Ruby 中的活動工作者

如需活動和活動工作者的詳細資訊,請參閱 瞭解 Step Functions 中的活動

CloudWatch 記錄檔資源策略大小限制

當您建立具有記錄的狀態機器,或更新現有狀態機器以啟用記錄時,Step Functions 必須使用您指定的記 CloudWatch 錄群組更新記錄資源原則。 CloudWatch 記錄檔資源策略的長度限制為 5,120 個字元。

當記 CloudWatch 錄檔偵測到原則接近大小限制時,記 CloudWatch 錄檔會自動為開頭的記錄群組啟用記錄/aws/vendedlogs/

您可以在 CloudWatch 記錄檔群組名稱前置詞,/aws/vendedlogs/以避免記 CloudWatch 錄資源原則大小限制。如果您在 Step Functions 主控台中建立記錄群組,建議的記錄群組名稱將已加上前置詞。/aws/vendedlogs/states

CloudWatch 每個區域的每個帳號也有 10 個資源策略的配額。如果您嘗試在某個帳號的區域中已有 10 個記 CloudWatch 錄資源原則的狀態機器上啟用記錄,則不會建立或更新狀態機器。如需記錄引號的詳細資訊,請參閱記CloudWatch 錄配額

如果您無法將記錄檔傳送至記 CloudWatch 錄檔,請參閱Troubleshooting state machine logging to CloudWatch Logs。若要深入瞭解一般記錄的相關資訊,請參閱啟用記錄來源 AWS 服務