kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

AmazonSQSにキューを挿入してみる

f:id:kazu22002:20201126160353p:plain

問い合わせフォーム周りで便利になりそうな技術を試しているところで、AmazonSQSについても便利そうなため触ってみました。

メッセージキューを管理できるサービスでサービスごとの連携でかなり活躍する機能だと思います。

Amazon SQS

Fully managed message queues for microservices, distributed systems, and serverless applications

「マイクロサービスや分散システム、サーバーレスアプリのためのキュー管理システム」

aws.amazon.com

キューを作成

キューを作成していきます。

  • AmazonSQSサービスを開き、「キューを作成」をクリック
  • 名前を入力
  • 「キューを作成」をクリック
  • 一覧にキューが表示されたら完了

f:id:kazu22002:20201126160120p:plain

f:id:kazu22002:20201126160131p:plain

f:id:kazu22002:20201126160142p:plain

キューの箱ができたため、データを入れてみます。とりあえずlambdaでデータを入れてみます。lambdaのプログラムはnodejsを使いました。

const AWS = require('aws-sdk');
const SQS = new AWS.SQS({apiVersion: '2012-11-05'});

const QUEUE_URL = 'https://sqs.ap-northeast-1.amazonaws.com/*********';

exports.handler = function(event, context) {

    // SendMessage
    var params = {
        MessageBody: "test", /* required */
        QueueUrl: QUEUE_URL,   /* required */
        DelaySeconds: 0
    };

    SQS.sendMessage(params, function(err, data) { });
};

実行ユーザーにSQSの権限を付与した後に、テストを実行することでキューに追加されます。

SQSのキュー画面の一覧を確認し、利用可能なメッセージが0から変わっていればキューに入っていることを確認できます。

f:id:kazu22002:20201126160157p:plain

メッセージキュー

知ったきっかけはlaravelのドキュメントを読んでいるときに、キューの項目があり気になったことで調べた経緯があります。

最初はなにに使うのか考えましたが、ユースケースを理解してからはかなり便利な機能だと感じています。

具体的には

  • 機能の分離
  • 処理の分散( 並列処理 )
  • 1プロセスの長時間化の対策

メール送信処理をプログラムに記述した場合、メール処理が完了するまで通信が帰ってこない場合があります。日常的には早いケースでも遅くなる場合もあると思います。負荷により重くなっているケースもあるでしょう。このとき、プログラムが終わるまでユーザーは待たされてしまいます。一度ぐらいならいいかもしれないですが、同じことが多数発生するとユーザーは離れていくと思います。

メッセージキューの機能で、メール送信をキューに入れる。という処理だけプログラムに記述される場合は「メッセージキューにデータを入れる」処理で済むことになります。

「メールを送信する」と「メッセージキューにデータを入れる」でどれだけの違いがでるのか。と考えてしまいますが、メール送信自体はリアルタイムでなくてもいい。メール処理が大量に処理されているところに、「メールを送信する」処理が入るときっと待たされることになるでしょう。

「メッセージキューにデータを入れる」ことはデータを入れるだけなので他の機能に影響を受けないため、一定の処理になります。

「メッセージキューにデータを入れる」部分が大量にきたら処理が遅くなるのでは??と思うこともありますが、ここはサービス次第でしょう。

ここまで1プロセスあたりの時間の改善の説明していますが、本当に重要な部分は分散処理の部分になるとおもっています。

メッセージキューを採用することで、実際に処理する部分を分離することができ、分散化も可能になっています。別プログラムで実装することも容易になり、密結合なシステムから疎結合にしていけると思っています。

分散化が容易になる理由としては、単一機能に分離できることが理由だと思っています。

メール処理だけに機能分離したため分散化が簡単になったと言えると思います。

一貫性を求める場合は正直メッセージキューを利用できないケースがあると思います。例えばメール送信までが1プロセスで送信が完了したことを保証しなければならない場合は使えないと思います。

ユースケースは考える必要はありますが、利用できる場面は多いと思っています。プログラムを分離するだけでも利用価値は高いと思っています。

雑記

フォームで「Api Gateway -> Lambda -> SQS -> SES or SNS」をやっているだけですが、なかなか進んでいないです。

機能的には理解しやすい機能であり、サンプルも記事を探せば結構あるので、すぐできるとおもっていましたがlambdaのコードのデバックでかなり手間取ることが多くなってきました。

pythonを使ったり、Nodejsをつかったり言語をいろいろと変えている影響もありますが、集中して終わらせる能力が結構低くなってきましたね。

できる人は1日で作るんだろうなー。と思いながら、できる範囲で作業しています。

あとCloudFormationかTerraformを使えるようになりたいですね。いろんなサービスを触っていると試しただけの内容も結構残っていそうで削除する際に悩んでいます。一度作った内容の再現性も高くなるので、近いうちに触ってみます。