本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Amazon ECS 會傳送事件至少一次。這表示您可能會收到指定事件的多個副本。此外,可能不會依事件發生順序將事件交付至事件接聽程式。
為了正確排序事件,每個事件的 detail
區段都會包含 version
屬性。每次資源變更狀態時,此 version
都會遞增。重複事件在 detail
物件中具有相同的 version
。如果您使用 EventBridge 複寫 Amazon ECS 容器執行個體和任務狀態,則可以比較 Amazon ECS APIs 回報的資源版本與 EventBridge 中version
回報的資源版本,以確認事件串流中的版本為最新版本。較高版本屬性編號的事件應該視為比較低版本編號的事件晚發生。
範例:處理 AWS Lambda
函式中的事件
下列範例顯示使用 Python 3.9 撰寫的 Lambda 函數,以同時擷取任務和容器執行個體狀態變更事件,並將其儲存至兩個 Amazon DynamoDB 資料表中的其中一個:
-
ECSCtrInstanceState:存放容器執行個體的最新狀態。資料表 ID 是容器執行個體的
containerInstanceArn
值。 -
ECSTaskState:存放任務的最新狀態。資料表 ID 是任務的
taskArn
值。
import json
import boto3
def lambda_handler(event, context):
id_name = ""
new_record = {}
# For debugging so you can see raw event format.
print('Here is the event:')
print((json.dumps(event)))
if event["source"] != "aws.ecs":
raise ValueError("Function only supports input from events with a source type of: aws.ecs")
# Switch on task/container events.
table_name = ""
if event["detail-type"] == "ECS Task State Change":
table_name = "ECSTaskState"
id_name = "taskArn"
event_id = event["detail"]["taskArn"]
elif event["detail-type"] == "ECS Container Instance State Change":
table_name = "ECSCtrInstanceState"
id_name = "containerInstanceArn"
event_id = event["detail"]["containerInstanceArn"]
else:
raise ValueError("detail-type for event is not a supported type. Exiting without saving event.")
new_record["cw_version"] = event["version"]
new_record.update(event["detail"])
# "status" is a reserved word in DDB, but it appears in containerPort
# state change messages.
if "status" in event:
new_record["current_status"] = event["status"]
new_record.pop("status")
# Look first to see if you have received a newer version of an event ID.
# If the version is OLDER than what you have on file, do not process it.
# Otherwise, update the associated record with this latest information.
print("Looking for recent event with same ID...")
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
table = dynamodb.Table(table_name)
saved_event = table.get_item(
Key={
id_name : event_id
}
)
if "Item" in saved_event:
# Compare events and reconcile.
print(("EXISTING EVENT DETECTED: Id " + event_id + " - reconciling"))
if saved_event["Item"]["version"] < event["detail"]["version"]:
print("Received event is a more recent version than the stored event - updating")
table.put_item(
Item=new_record
)
else:
print("Received event is an older version than the stored event - ignoring")
else:
print(("Saving new event - ID " + event_id))
table.put_item(
Item=new_record
)
下列 Fargate 範例顯示以 Python 3.9 撰寫的 Lambda 函數,可擷取任務狀態變更事件並將其儲存至下列 Amazon DynamoDB 資料表:
import json
import boto3
def lambda_handler(event, context):
id_name = ""
new_record = {}
# For debugging so you can see raw event format.
print('Here is the event:')
print((json.dumps(event)))
if event["source"] != "aws.ecs":
raise ValueError("Function only supports input from events with a source type of: aws.ecs")
# Switch on task/container events.
table_name = ""
if event["detail-type"] == "ECS Task State Change":
table_name = "ECSTaskState"
id_name = "taskArn"
event_id = event["detail"]["taskArn"]
else:
raise ValueError("detail-type for event is not a supported type. Exiting without saving event.")
new_record["cw_version"] = event["version"]
new_record.update(event["detail"])
# "status" is a reserved word in DDB, but it appears in containerPort
# state change messages.
if "status" in event:
new_record["current_status"] = event["status"]
new_record.pop("status")
# Look first to see if you have received a newer version of an event ID.
# If the version is OLDER than what you have on file, do not process it.
# Otherwise, update the associated record with this latest information.
print("Looking for recent event with same ID...")
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
table = dynamodb.Table(table_name)
saved_event = table.get_item(
Key={
id_name : event_id
}
)
if "Item" in saved_event:
# Compare events and reconcile.
print(("EXISTING EVENT DETECTED: Id " + event_id + " - reconciling"))
if saved_event["Item"]["version"] < event["detail"]["version"]:
print("Received event is a more recent version than the stored event - updating")
table.put_item(
Item=new_record
)
else:
print("Received event is an older version than the stored event - ignoring")
else:
print(("Saving new event - ID " + event_id))
table.put_item(
Item=new_record
)