LoginSignup
1
1

Lambda × SQSでのサーバーレスアーキテクチャの構築

Last updated at Posted at 2023-10-02

はじめに

先日、AWSのLambdaとSQSを用いた、サーバーレスな設計で、あるアプリケーションを作成したので、その時のアーキテクチャや、実装面で工夫した点をまとめました!
基本的なアーキテクチャですが、前提知識が少し必要なので、やや中級者向けの記事になります!

こういう処理を走らせたいけど、お金がかかるしサーバーを動かし続けたくないなあ、、
という方は、ぜひlambdaを活用してみてはいかがでしょうか!

アプリの概要

作成したアプリは、大枠では下記の処理を順番に実行するものです。

  1. 処理する対象のURL一覧を取得する処理
  2. URLに登録されている文章を取得する処理
  3. 文章を要約する処理
  4. 要約された文章を、S3に登録する処理

周期を設定したEventBridgeをトリガーとして、この処理を開始します。
2番目以降の処理から、lambdaの同時実行の力とSQSの特性を活かして、並行処理を実施します。

アーキテクチャ

スクリーンショット 2023-10-01 15.53.15.png

処理の詳細

1の処理の最後に、URLを1つずつQueueに格納する処理にすることで、URL単位でメッセージを送信することができ、その後の処理をメッセージ単位(URL単位)で実施することができます!

あまり触れたことない方はイメージしづらいかもしれませんが、例えば、100件のURLを処理する必要がある場合、URLを100件取得し、メッセージに登録する最初の処理は100回ループする必要があります。
しかし、その後の処理は、100件のURLを、100個のlambdaで並行処理することができるようにしています。
よくあるSQSの使用方法ですね!

コードの例

SQSにアクセスし、情報をQueueに格納する処理の参考コードは以下になります!
YOUR_ACCESS_KEY_IDなどの情報は、別途lambdaの環境変数の設定画面から設定する必要があります!

main.py
from sqs_connect import post_queue

def handler(event, context):

  # 今回はURLリストを取得するメソッドは割愛
  url_list = get_url_list()

  #SQS送信
  for url in url_list:
    post_queue(url)
sqs_connect.py
import boto3
import json
import os
import logging

def post_queue(url:str):
    #json形式なので、dicに入れる
    data_for_sqs = {"url": url}

    #jsonに変換
    message = json.dumps(data_for_sqs, ensure_ascii=False)

    #sqsと接続
    try:
        sqs = boto3.client('sqs',
                aws_access_key_id=os.environ["YOUR_ACCESS_KEY_ID"],
                aws_secret_access_key=os.environ["YOUR_SECRET_ACCESS_KEY"],
                region_name='ap-northeast-1'
                )

        # メッセージをSQSに送信
        response = sqs.send_message(
            QueueUrl=os.environ['YOUE_QUEUE_NAME'],
            MessageBody=message
            )

        logging.info(f'Successfully sent message: {response}')

    except Exception as e:
        logging.error(f'Failed to send message: {e}')

後続のlambdaで、SQSからメッセージを受け取るコードは以下になります!

main.py
def handler(event, context):
    
    #SQSから要素を取得
    queue_info =  json.loads(event['Records'][0]['body'])

    url = queue_info.get('url')

    #ここから、取得したURLに対する後続の処理を記載

ソリューションの特徴

完全サーバーレス

EC2インスタンスなどを使用していないため、サーバーを管理する必要がありません。
処理が走っていない時に料金は発生せず、監視も不要なので、運用面で非常に楽に管理することができます。

コスト

lambdaは1ヶ月あたり、100万件分のリクエストが無料であり、その後も100万リクエストあたり0.2USDで使用可能です。
また、SQSも同様に毎月100万件まで無料で実施可能です。
その後の料金も100万-1億リクエストまでは、100万リクエストあたり0.4USDで使用できます。
このように、lambdaとSQSを用いたサーバーレスアーキテクチャは、非常にコストエフェクティブなソリューションの1つです!

lambdaの同時実行の特性

lambdaはデフォルトで1アカウントに対し、1リージョンで1000件まで同時実行することが可能です。
処理単位を細かくlambdaで分けることにより、素早く処理を完了することができます!

インターフェースの統一と転用

このようなアーキテクチャで処理を実施するにあたり、インターフェースを工夫しました。
SQSとlambda間でやり取りをするインターフェース項目を、json形式で設定するのですが、これらのキー値を全体的に統一しています。
SQSのjsonに載せるキー名を、SQSや内部のコードで統一し、SQSから受け取る際のコードを転用できるようにすることで、開発効率を向上させることができます!

また、URL以外から文章を取得する必要があるケースも、今後の拡張としてあったため、3の文章を要約する処理へのインターフェースを拡張しやすいように設計して開発したことにより、今後文章の取得元が増えても、コード修正不要で3と4のメソッドを使用することができます。
lambdaで処理を細かく分けることで、影響範囲の制限を簡略化することができます!

参考

lambda料金について: https://aws.amazon.com/jp/lambda/pricing/
lambdaの無料枠について: https://aws.amazon.com/jp/lambda/pricing/?loc=ft#Free_Tier
SQSの料金について: https://aws.amazon.com/jp/sqs/pricing/
lambdaの同時実行について: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-concurrency.html

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1