ご無沙汰しております。オンラインコンサルタントの直井です。今回はECS周りについてご紹介いたします。
1. 動機
ECSのタスクをSQSのメッセージ数に応じてオートスケールしたいな…と思ったことがことの発端です。
要は、バッチ処理をメッセージに応じてスケーリングするといった内容です。今回の内容ではクラスター内のサービスだと、メッセージ数に応じてタスクをスケールアウトすることは可能ですが、スケールインの設定が難しいため、このような実装方法になりました。
2. 動作環境
Python:3.9
ECSのタスクは、処理が終了すればコンテナが終了してスケールインの操作が不要な状態
3. Lambdaサンプルコード
import boto3
import os
import time
import datetime
ecs_client = boto3.client("ecs")
cw_client = boto3.client('cloudwatch')
ECS_CLUSTER = ""
TASK_DEFINITION = ""
SUBNET_ID_1 = ""
SUBNET_ID_2 = ""
QUEUE_NAME = ""
def lambda_handler(event, context):
response = cw_client.get_metric_statistics(
Namespace = 'AWS/SQS',
MetricName = 'ApproximateNumberOfMessagesVisible',
Dimensions = [
{
'Name': 'QueueName',
'Value': QUEUE_NAME
},
],
StartTime=datetime.datetime.now() - datetime.timedelta(seconds=60),
EndTime=datetime.datetime.now(),
Period = 60,
Statistics = ['Maximum']
)
metric = int(response['Datapoints'][0]['Maximum'])
if metric > 0 :
print("Create!!")
for num in range(metric):
ecs_client.run_task(
cluster=ECS_CLUSTER,
launchType="FARGATE",
networkConfiguration={
"awsvpcConfiguration": {
"subnets": [SUBNET_ID_1,SUBNET_ID_2],
"assignPublicIp": "ENABLED",
}
},
taskDefinition=TASK_DEFINITION,
)
time.sleep(10)
else:
print("None")
ざっくりとコード内の説明
発火した過去1分でSQSで利用できるメッセージ数(visibleCount)を取得して、その数に応じて繰り返し処理でECSのタスクを起動させるようにしています。
visibleカウントは処理中ではないメッセージ数に応じて値が変化します。
4. 発火イベントを仕込む
右上のトリガーの追加を選択
バーに「event」と入力して「EventBridgeを選択」
「新規ルールの作成」を選択肢、「ルール名」と「スケジュール式」を入力して「追加」ボタンをクリック
※1分や1時間の場合は、1 minute, 1 hour だが、2以上であれば 2minutes, 2 hoursになるので注意
5. 最後に
サービスをうまく使ってどうにかできないか考えましたが、今回構成したシステム群が疎結合に作れたので、柔軟性があり助かりました。
ECSではちょいちょいコンソール画面に対応していないもしくは、新UIに対応していないことが多いので戸惑うことが多かったです。