處理無伺服器應用程式中的錯誤

使用 AWS Step Functions 和 AWS Lambda

在此教學中,您將了解如何使用 AWS Step Functions 處理工作流程執行階段的錯誤。AWS Step Functions 是一種無伺服器協調服務,可讓您輕鬆地將多個 Lambda 函數協調為易於偵錯和變更的彈性工作流程。AWS Lambda 是一種運算服務,可讓您執行程式碼,而無需佈建或管理伺服器。 

Lambda 函數偶爾會失敗,例如當發出未處理的例外、當這種函數執行得超過設定的逾時時間,或是記憶體用盡時。在您的每一個 Lambda 函數中撰寫並維護錯誤處理邏輯,以處理例如 API 調節或通訊端逾時等情況,恐怕是既耗時又繁複的工作,對於分散式應用程式而言更是如此。將此程式碼內嵌至各個 Lambda 函數,會在其彼此之間造成相依性;隨著事物變遷,這麼多的關聯可能維護不易。

為了避免這些困擾,同時減少所需撰寫的錯誤處理程式碼數量,您可使用 AWS Step Functions 建立能支援函數錯誤處理的無伺服器工作流程。無論是開發人員建立的函數例外狀況 (例如,找不到檔案) 或未預期 (例如,記憶體不足) 的錯誤,您可設定 Step Functions 根據發生的錯誤類型,使用條件邏輯加以回應。以此方式將工作流程邏輯與商務邏輯相互區隔,無需變更 Lambda 函數的商務邏輯,即可修改工作流程對於錯誤的回應方式。

在此教學中,您將使用 AWS Step Functions 設計並執行無伺服器工作流程,穩定地處理這類錯誤。您將會建立 AWS Lambda 函數以模擬呼叫 RESTful API,傳回各種回應碼和例外。接著,會請您使用 AWS Step Functions 建立具有「重試」和「擷取」能力的狀態機器,依照發生的例外而定,以不同的邏輯回應。

本教學需要 AWS 帳戶

使用 AWS Step Functions 或 AWS Lambda 無須額外付費。您在本教學建立的資源符合免費方案資格。 

進一步了解免費方案 >>


步驟 1.建立 Lambda 函數以模擬 API

在此步驟中,您將建立 Lambda 函數,模擬幾種基本的 API 互動。Lambda 函數會以您提供的錯誤代碼作為事件參數中的輸入,發出例外以模擬虛構 API 所作的回應。


a.  開啟 AWS 管理主控台,以便讓此逐步指南持續保持開啟狀態。當畫面載入時,請輸入您的使用者名稱和密碼以開始使用。接著在搜尋列輸入 Lambda,選取 Lambda 開啟服務主控台。

01a
01a

(按一下以放大)


b.選擇建立函數

01b
01b

(按一下以放大)


c.維持選取從頭開始撰寫。接下來,請依如下方式設定 Lambda 函數:

對於名稱,輸入 MockAPIFunction
對於執行階段,選擇 Python 3.6
對於角色,選取建立自訂角色

此時會開啟新的 IAM 視窗。維持角色名稱lambda_basic_execution ,然後按一下允許。您會自動回到 Lambda 主控台。

按一下建立函數​。

01c
01c

(按一下以放大)


d.在 MockAPIFunction 畫面,向下捲動至函數程式碼畫面。在此教學中,您將建立函數,其使用程式設計模型於 Python 中編寫 Lambda 函數。在程式碼視窗中,將所有程式碼取代為以下所示,接著選擇儲存

class TooManyRequestsException(Exception): pass
class ServerUnavailableException(Exception): pass
class UnknownException(Exception): pass

def lambda_handler(event, context):
    statuscode = event["statuscode"]    
    if statuscode == "429":
        raise TooManyRequestsException('429 Too Many Requests')
    elif statuscode == "503":
        raise ServerUnavailableException('503 Server Unavailable')
    elif statuscode == "200":
        return '200 OK'
    else:
        raise UnknownException('Unknown error')
01d
01d

(按一下以放大)


e.一旦建立 Lambda 函數,捲動至視窗頂端,記下頁面右上角的 Amazon Resource Name (ARN)。Amazon Resource Names (ARN) 能唯一識別 AWS 的資源,協助您遍及各項 AWS 服務和 API 呼叫,追蹤並使用 AWS 項目與政策。當您需要從 Step Functions 參考特定資源時,我們要求必須有 ARN。

01e
01e

(按一下以放大)


步驟 2.建立 AWS Identity and Access Management (IAM) 角色

AWS Step Functions 能執行程式碼並存取其他 AWS 資源 (例如,存放在 Amazon S3 儲存貯體內的資料)。為維護安全起見,您必須使用 AWS Identity and Access Management (IAM),授與 Step Functions 對這些資源的存取權。


a.另用瀏覽器視窗導覽至 AWS 管理主控台,在搜尋列中輸入 IAM。按一下 IAM 開啟服務主控台。

02a
02a

(按一下以放大)


b.按一下角色,接著選擇建立角色

02b
02b

(按一下以放大)


c.在選取受信任實體的類型頁面,在 AWS 服務之下,選取清單中的 Step Functions,接著選擇下一步:許可

02c
02c

(按一下以放大)


d.在附加許可政策頁面,選擇下一步:檢閱

 

02d
02d

(按一下以放大)


e.在檢閱頁面,為角色名稱輸入 step_functions_basic_execution,按一下建立角色

02e
02e

(按一下以放大)


f.即建立您的新 IAM 角色,並顯示在 Lambda 函數的 IAM 角色下方的清單中。

02f
02f

(按一下以放大)


步驟 3.建立 Step Functions 狀態機器

現在您已建立模擬 API 回應的簡易 Lambda 函數,接著可以建立 Step Functions 狀態機器以呼叫 API 並處理例外。

在此步驟中,您將使用 Step Functions 主控台建立狀態機器,其使用「任務」狀態搭配「重試」和「擷取」欄位以處理各種 API 回應碼。您將以「任務」狀態叫用您模擬的 API Lambda 函數,其將傳回您作為輸入提供到狀態機器的 API 狀態碼。


a.開啟 AWS Step Functions 主控台。在建立狀態機器頁面,選取從頭開始撰寫。在詳細資訊區段,將您的狀態機器命名為 MyAPIStateMachine,然後選取我要使用現有的角色

03c
03c

(按一下以放大)


b.接下來,請您設計狀態機器,能夠依照您的模擬 API 所給的回應採取不同的動作。若無法連線至該 API,工作流程會再試一次。重試是解決暫時錯誤的好方法。此工作流程也能擷取模擬 API 擲出的各種例外。

狀態機器定義區段的內容取代為以下程式碼:

{
  "Comment": "An example of using retry and catch to handle API responses",
  "StartAt": "Call API",
  "States": {
    "Call API": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
      "Next" : "OK",
      "Comment": "Catch a 429 (Too many requests) API exception, and resubmit the failed request in a rate-limiting fashion.",
      "Retry" : [ {
        "ErrorEquals": [ "TooManyRequestsException" ],
        "IntervalSeconds": 1,
        "MaxAttempts": 2
      } ],
      "Catch": [ 
        {
          "ErrorEquals": ["TooManyRequestsException"],
          "Next": "Wait and Try Later"
        }, {
          "ErrorEquals": ["ServerUnavailableException"],
          "Next": "Server Unavailable"
        }, {
          "ErrorEquals": ["States.ALL"],
          "Next": "Catch All"
        }
      ]
    },
    "Wait and Try Later": {
      "Type": "Wait",
      "Seconds" : 1,
      "Next" : "Change to 200"
    },
    "Server Unavailable": {
      "Type": "Fail",
      "Error":"ServerUnavailable",
      "Cause": "The server is currently unable to handle the request."
    },
    "Catch All": {
      "Type": "Fail",
      "Cause": "Unknown error!",
      "Error": "An error of unknown type occurred"
    },
    "Change to 200": {
      "Type": "Pass",
      "Result": {"statuscode" :"200"} ,
      "Next": "Call API"
    },
    "OK": {
      "Type": "Pass",
      "Result": "The request has succeeded.",
      "End": true
    }
  }
}
03d
03d

(按一下以放大)


c.在「呼叫 API」任務狀態中找到「資源」行 (第 7 行)。為將此 ARN 更新至您剛建立之模擬 API Lambda 函數的 ARN,按一下 ARN 內文,從清單中選取該 ARN。

03e
03e

(按一下以放大)


d.在視覺工作流程窗格旁,按一下重新整理按鈕,讓 Step Functions 建立狀態機器圖,對應您剛才設計的工作流程。檢視視覺工作流程之後,按一下建立狀態機器

03f
03f

(按一下以放大)


步驟 4.測試錯誤處理工作流程

為了測試您的錯誤處理工作流程,您將叫用狀態機器,提供錯誤代碼作為輸入,以呼叫模擬 API。


a.按一下開始執行

04a
04a

(按一下以放大)


b.即顯示新的執行對話方塊,您可提供對狀態機器的輸入。您將扮演 API 的角色,提供我們想讓模擬 API 傳回的錯誤代碼。將現有文字取代為以下的程式碼,接著選擇開始執行

{
    "statuscode": "200"
}
04b
04b

(按一下以放大)


c.在執行詳細資訊畫面上,按一下輸入以查看您為您的狀態機器提供的輸入。接著,按一下輸出以檢視狀態機器執行的結果。您可看出,工作流程將狀態碼 200 釋義為 API 呼叫成功。

04c
04c

(按一下以放大)


d.在視覺工作流程之下,您可看出每項執行的執行路徑,在工作流程中以綠色表示。按一下「呼叫 API」任務狀態,接著展開步驟詳細資訊畫面中的輸入輸出欄位。

您可看出此「任務」狀態已用您所提供的輸入成功叫用您的模擬 API Lambda 函數,並擷取該 Lambda 函數的輸出:「200 正常」。

04d
04d

(按一下以放大)


e.接下來,在視覺工作流程中,按一下「正常」任務狀態。在步驟詳細資訊之下,您可看出,上個步驟 (「呼叫 API 任務」狀態) 的輸出已傳遞為這個步驟的輸入。「正常」狀態為「傳遞」狀態,其直接將輸入傳遞到其輸出,並不執行作業。「傳遞」狀態在狀態機器的建構和偵錯的時候相當實用。

04e
04e

(按一下以放大)


步驟 5.檢查狀態機器的執行


a.捲動至執行詳細資訊畫面頂端,按一下 MyAPIStateMachine

05a
05a

(按一下以放大)


b.再次按一下開始執行,這一次提供以下輸入,再按一下開始執行

{
    "statuscode": "503"
}
05b
05b

(按一下以放大)


c.在執行事件歷史記錄區段,展開各個執行步驟,以確認您的工作流程行為如所預期。我們預期這次執行會失敗,因此請勿驚慌! 您會注意到下列幾點:

  1. Step Functions 擷取了您的輸入
  2. 該輸入傳遞到「呼叫 API 任務」狀態
  3. 「呼叫 API 任務」狀態使用該輸入呼叫您的 MockAPIFunction
  4. MockAPIFunction 已執行
  5. MockAPIFunction 以 ServerUnavailableException 失敗
  6. 「呼叫 API 任務」狀態中的擷取宣告擷取了該例外
  7. 擷取宣告執行工作流程失敗
  8. 您的狀態機器完成其執行
05c
05c

(按一下以放大)


d.接下來,您將模擬 429 號例外。捲動至執行詳細資訊畫面頂端,按一下 MyAPIStateMachine。按一下開始執行,提供以下輸入,再按一下開始執行

{
    "statuscode": "429"
}
05d
05d

(按一下以放大)


e.現在,請您檢查工作流程的重試行為。在執行事件歷史記錄區段,再次展開各個執行步驟,以確認 Step Functions 又嘗試呼叫 MockAPILambda 函數兩次,兩次皆失敗。當時,您的工作流程轉換為「等候」及「稍後重試」狀態 (如右方圖像所示),希望 API 只是暫時無回應。

接下來,「等候」狀態使用暴力強制將回應碼變更為 200,您的工作流程也順利執行完畢。您在真實應用程式中應該不會這樣處理 429 號例外,這裡只是在教學中而簡化。

05e
05e

(按一下以放大)


f.再執行一個工作流程的執行個體;這一次請提供未由您的狀態機器處理過的隨機 API 回應:

{
    "statuscode": "999"
}

使用執行事件歷史記錄再次檢查執行情況。完成時,再按一次 MyAPIStateMachine。在執行窗格,您可看出工作流程所有執行的歷史記錄,並可依您的意願個別步入其中。

05f
05f

(按一下以放大)


步驟 6.終止您的資源

在此步驟中,您將終止您的 AWS Step Functions 和 AWS Lambda 相關資源。

重要:終止非主動使用中的資源可降低成本,且為最佳實務。未終止資源可能產生費用。


a.在 AWS Step Functions 主控台視窗頂部,按一下狀態機器

06a
06a

(按一下以放大)


b.在狀態機器視窗中,按一下 MyAPIStateMachine,然後選取刪除。透過選取對話方塊中的刪除狀態機器來確認此動作。在 Step Functions 確認所有處理中的執行都已完成後,您的狀態機器將在一兩分鐘內刪除。

06b
06b

(按一下以放大)


c.接下來,您將刪除您的 Lambda 函數。在 AWS 管理主控台功能表中按一下服務,然後選取 Lambda

06c
06c

(按一下以放大)


d.在函數畫面中,按一下 MockAPIFunction,選取動作,接著選取刪除。透過再次按一下刪除來確認刪除。

06d
06d

(按一下以放大)


e.最後,您將刪除您的 IAM 角色。在 AWS 管理主控台功能表中按一下服務,然後選取 IAM

06e
06e

(按一下以放大)


f.選取您為此教學建立的兩個 IAM 角色,然後按一下刪除角色。透過按一下對話方塊中的是,刪除以確認刪除。


您現在可以登出 AWS 管理主控台。

06f
06f

(按一下以放大)


恭喜您!

您已使用 AWS Step Functions 和 AWS Lambda,為網路 API 建立錯誤處理工作流程。使用 AWS Lambda,您可以為幾乎任何類型的應用程式或後端服務執行程式碼,無須任何管理。只需上傳程式碼,Lambda 就會運用其高可用性來處理執行程式碼及擴展規模所需的各項工作。

將 AWS Step Functions 與 AWS Lambda 合併 ,可輕鬆協調無伺服器應用程式的 AWS Lambda 函數。Step Functions 可讓您使用 Lambda 函數控制繁複的工作流程,無需以基礎應用程式管理並協調狀態。您還可以將 Step Functions 用於使用運算資源 (如 Amazon EC2 和 Amazon ECS) 的微型服務協調。