如何對 Amazon ECS 中出現的 OutOfMemory 錯誤進行疑難排解?
我想對 Amazon Elastic Container Service (Amazon ECS) 任務中出現的記憶體用量問題進行疑難排解。 -或- 由於 OutOfMemory 錯誤,我的 Amazon ECS 任務中的容器正在退出。
簡短描述
依預設,容器沒有資源限制,並且可使用主機內核排程器允許的資源。使用 Docker,您可以控制容器使用的記憶體量。請務必不要允許運行中容器佔用主機的大部分記憶體。在 Linux 主機上,當內核偵測到記憶體不足,無法執行重要的系統功能時,會引發 OutOfMemory 異常狀況,並開始結束進程以釋放記憶體。
透過 Docker,您可以使用以下任一選項:
- 硬記憶體限制,允許容器使用不超過一定量的使用者或系統記憶體
- 軟限制,允許容器視需使用盡可能多的記憶體,除非發生某些情況 (如記憶體不足或主機上的爭用)
當 Amazon ECS 任務因 OutOfMemory 問題而結束時,您可能會收到以下錯誤訊息:
OutOfMemoryError: Container killed due to memory usage
當任務中的容器退出時,您會出現此錯誤,因為容器中的進程取用的記憶體超過任務定義中分配的量。
解決方案
若要解決 Amazon ECS 任務中的 OutOfMemory 錯誤,請執行以下操作:
- 在 Amazon ECS 主控台中檢查停止的任務是否存在錯誤。檢查停止原因欄位中的錯誤代碼 OutOfMemory。
- 為您的任務開啟 Amazon CloudWatch Logs,對由於記憶體用量而發生的應用程式級問題進行偵錯。
- 在 Amazon ECS 主控台或 CloudWatch 主控台中檢視服務的記憶體用量。
- 使用 CloudWatch Container Insights 監控記憶體用量。您可以使用類似於以下內容的查詢,來檢視特定容器在一段時間的記憶體用量:
stats max(MemoryUtilized) as mem, max(MemoryReserved ) as memreserved by bin (5m) as period, TaskId, ContainerName | sort period desc | filter ContainerName like “example-container-name” | filter TaskId = “example-task-id”
若要降低由於 OutOfMemory 問題導致的任務不穩定風險,請執行以下操作:
- 在將應用程式投入生產之前,執行測試以了解應用程式的記憶體要求。您可在主機或伺服器內的容器上執行負載測試。然後,您可以使用 docker 統計資料檢查容器的記憶體使用情況。
- 確保應用程式僅在具有足夠資源的主機上執行。
- 限制容器可使用的記憶體量。您可以為容器設定適當的硬限制和軟限制值,來完成此操作。Amazon ECS 使用幾項參數來將記憶體分配給任務:memoryReservation 用於軟限制,memory 用於硬限制。指定這些值後,將會從容器所在的容器執行個體可用記憶體資源中減去這些值。
**注意:**Windows 容器不支援 memoryReservation 參數。 - 您可以為具有較高暫時性記憶體需求的容器開啟 swap (交換) 功能。這樣做可以減少容器在較高負載下出現 OutOfMemory 錯誤的機率。
**注意:**如果您使用的任務採用 AWS Fargate 啟動類型,則不支援 maxSwap 和 sharedMemorySize 參數。
**重要提示:**在 Docker 主機上設定交換時請注意。開啟交換可能會減慢應用程式並降低效能。但是,此功能可防止應用程式耗盡系統記憶體。
若要偵測因 OutOfMemory 事件而結束的 Amazon ECS 任務,請使用下列 AWS CloudFormation 範本。使用此範本可以建立 Amazon EventBridge 規則、Amazon Simple Notification Service (Amazon SNS) 主題和 Amazon SNS 主題政策。執行範本時,範本會要求您提供電子郵件清單、主題名稱和標記,以開啟或關閉監視。
AWSTemplateFormatVersion: 2010-09-09 Description: > - Monitor OOM Stopped Tasks with EventBridge rules with AWS CloudFormation. Parameters: EmailList: Type: String Description: "Email to notify!" AllowedPattern: '[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+' Default: "mail@example.com" SNSTopicName: Type: String Description: "Name for the notification topic." AllowedPattern: '[a-zA-Z0-9_-]+' Default: "oom-monitoring-topic" MonitorStatus: Type: String Description: "Enable / Disable monitor." AllowedValues: - ENABLED - DISABLED Default: ENABLED Resources: SNSMonitoringTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref EmailList Protocol: email TopicName: !Sub ${AWS::StackName}-${SNSTopicName} SNSMonitoringTopicTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: Topics: - !Ref SNSMonitoringTopic PolicyDocument: Version: '2012-10-17' Statement: - Sid: SnsOOMTopicPolicy Effect: Allow Principal: Service: events.amazonaws.com Action: [ 'sns:Publish' ] Resource: !Ref SNSMonitoringTopic - Sid: AllowAccessToTopicOwner Effect: Allow Principal: AWS: '*' Action: [ 'sns:GetTopicAttributes', 'sns:SetTopicAttributes', 'sns:AddPermission', 'sns:RemovePermission', 'sns:DeleteTopic', 'sns:Subscribe', 'sns:ListSubscriptionsByTopic', 'sns:Publish', 'sns:Receive' ] Resource: !Ref SNSMonitoringTopic Condition: StringEquals: 'AWS:SourceOwner': !Ref 'AWS::AccountId' EventRule: Type: AWS::Events::Rule Properties: Name: ECSStoppedTasksEvent Description: Triggered when an Amazon ECS Task is stopped EventPattern: source: - aws.ecs detail-type: - ECS Task State Change detail: desiredStatus: - STOPPED lastStatus: - STOPPED containers: reason: - prefix: "OutOfMemory" State: !Ref MonitorStatus Targets: - Arn: !Ref SNSMonitoringTopic Id: ECSOOMStoppedTasks InputTransformer: InputPathsMap: taskArn: $.detail.taskArn InputTemplate: > "Task '<taskArn>' was stopped due to OutOfMemory."
建立 CloudFormation 堆疊之後,您可以檢查電子郵件以確認訂閱。任務因 outofMemory 問題而結束後,您會收到一封電子郵件,其中包含類似下列內容的訊息:
"Task 'arn:aws:ecs:eu-west-1:555555555555:task/ECSFargate/0123456789abcdef0123456789abcdef' was stopped due to OutOfMemory."
相關資訊
相關內容
- 已提問 8 個月前lg...
- 已提問 2 個月前lg...
- 已提問 1 年前lg...
- 已提問 5 個月前lg...
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前