SQSのvisibleメッセージの数だけECSタスクを起動する方法

ご無沙汰しております。オンラインコンサルタントの直井です。今回は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に対応していないことが多いので戸惑うことが多かったです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です